diff --git a/cmd/minify/README.md b/cmd/minify/README.md index b10815204..7c447c1ee 100644 --- a/cmd/minify/README.md +++ b/cmd/minify/README.md @@ -219,6 +219,13 @@ Match will filters all files by the given pattern, eg. `--match '*.css'` will on You may define multiple patterns within one option, such as: `--exclude '**/folder1/**' '**/folder2/**' '**/folder3/**'` Doing this might result in unexpected behaviour when it is followed immediately by the input files, as this would be interpreted as another pattern, and not as inputs. `--exclude dir_to_exclude folder_input` Instead format accordingly: `--exclude dir_to_exclude -- folder_input`. +To match `*` or `?` literally, precede by a backslash. To specify a regular expression directly instead of a glob, use the tilde as a prefix (to use a tilde literally at the beginning, precede by a backslash). Examples of regular expressions: + +``` +./minify --match ~^path[0-9]/[^/]*.(js|html)$ +./minify --match ~^(?i)pathCaseInsensitive[0-9]/[^/]*.(js|html)$ +``` + ### Concatenate When multiple inputs are given and the output is either standard output or a single file, it will concatenate the files together if you use the bundle option. diff --git a/cmd/minify/main.go b/cmd/minify/main.go index f25fee7a2..def765d95 100644 --- a/cmd/minify/main.go +++ b/cmd/minify/main.go @@ -292,13 +292,11 @@ func run() int { Debug = log.New(io.Discard, "", 0) if !quiet { Error = log.New(os.Stderr, "ERROR: ", 0) + Warning = log.New(os.Stderr, "WARNING: ", 0) if 0 < verbose { - Warning = log.New(os.Stderr, "WARNING: ", 0) - } - if 1 < verbose { Info = log.New(os.Stderr, "INFO: ", 0) } - if 2 < verbose { + if 1 < verbose { Debug = log.New(os.Stderr, "DEBUG: ", 0) } } @@ -624,14 +622,19 @@ func minifyWorker(chanTasks <-chan Task, chanFails chan<- int) { // compilePattern returns *regexp.Regexp or glob.Glob func compilePattern(pattern string) (*regexp.Regexp, error) { if len(pattern) == 0 || pattern[0] != '~' { + sep := regexp.QuoteMeta(string(filepath.Separator)) if strings.HasPrefix(pattern, `\~`) { pattern = pattern[1:] } pattern = regexp.QuoteMeta(pattern) + pattern = strings.ReplaceAll(pattern, `\\\*`, `\*`) + pattern = strings.ReplaceAll(pattern, `\\\?`, `\?`) pattern = strings.ReplaceAll(pattern, `\*\*`, `.*`) - pattern = strings.ReplaceAll(pattern, `\*`, fmt.Sprintf(`[^%c]*`, filepath.Separator)) - pattern = strings.ReplaceAll(pattern, `\?`, fmt.Sprintf(`[^%c]?`, filepath.Separator)) + pattern = strings.ReplaceAll(pattern, `\*`, fmt.Sprintf(`[^%s]*`, sep)) + pattern = strings.ReplaceAll(pattern, `\?`, fmt.Sprintf(`[^%s]`, sep)) pattern = "^" + pattern + "$" + } else { + pattern = pattern[1:] } return regexp.Compile(pattern) } @@ -692,7 +695,8 @@ func createTasks(fsys fs.FS, inputs []string, output string) ([]Task, []string, info, err = os.Lstat(input) } if err != nil { - return nil, nil, err + Error.Println(err) + continue } if preserveLinks && info.Mode()&os.ModeSymlink != 0 { @@ -746,7 +750,8 @@ func createTasks(fsys fs.FS, inputs []string, output string) ([]Task, []string, // follow and dereference symlinks info, err := fs.Stat(fsys, input) if err != nil { - return err + Error.Println(err) + return nil } if info.IsDir() { return fs.WalkDir(fsys, input, walkFn)