"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "options.go" between
sift-0.8.0.tar.gz and sift-0.9.0.tar.gz

About: sift is an alternative to grep that aims for both speed and flexibility (written in Go).

options.go  (sift-0.8.0):options.go  (sift-0.9.0)
skipping to change at line 43 skipping to change at line 43
"golang.org/x/crypto/ssh/terminal" "golang.org/x/crypto/ssh/terminal"
) )
type Options struct { type Options struct {
BinarySkip bool `long:"binary-skip" description:"skip files th at seem to be binary"` BinarySkip bool `long:"binary-skip" description:"skip files th at seem to be binary"`
BinaryAsText bool `short:"a" long:"binary-text" description:"pro cess files that seem to be binary as text"` BinaryAsText bool `short:"a" long:"binary-text" description:"pro cess files that seem to be binary as text"`
Blocksize string `long:"blocksize" description:"blocksize in by tes (with optional suffix K|M)"` Blocksize string `long:"blocksize" description:"blocksize in by tes (with optional suffix K|M)"`
Color string Color string
ColorFunc func() `long:"color" description:"enable colored ou tput (default: auto)" json:"-"` ColorFunc func() `long:"color" description:"enable colored ou tput (default: auto)" json:"-"`
NoColorFunc func() `long:"no-color" description:"disable colore d output" json:"-"` NoColorFunc func() `long:"no-color" description:"disable colore d output" json:"-"`
ConfigFile string `long:"conf" description:"load config file F ILE" value-name:"FILE" json:"-"`
Context int `short:"C" long:"context" description:"show NUM context lines" value-name:"NUM" json:"-"` Context int `short:"C" long:"context" description:"show NUM context lines" value-name:"NUM" json:"-"`
ContextAfter int `short:"A" long:"context-after" description: "show NUM context lines after match" value-name:"NUM" json:"-"` ContextAfter int `short:"A" long:"context-after" description: "show NUM context lines after match" value-name:"NUM" json:"-"`
ContextBefore int `short:"B" long:"context-before" description :"show NUM context lines before match" value-name:"NUM" json:"-"` ContextBefore int `short:"B" long:"context-before" description :"show NUM context lines before match" value-name:"NUM" json:"-"`
Cores int `short:"j" long:"cores" description:"limit u sed CPU Cores (default: 0 = all)" default-mask:"-"` Cores int `short:"j" long:"cores" description:"limit u sed CPU Cores (default: 0 = all)" default-mask:"-"`
Count bool `short:"c" long:"count" description:"print c ount of matches per file" json:"-"` Count bool `short:"c" long:"count" description:"print c ount of matches per file" json:"-"`
IncludeDirs []string `long:"dirs" description:"recurse only into directories whose name matches GLOB" value-name:"GLOB" default-mask:"-"` IncludeDirs []string `long:"dirs" description:"recurse only into directories whose name matches GLOB" value-name:"GLOB" default-mask:"-"`
ErrShowLineLength bool `long:"err-show-line-length" description:"sh ow all line length errors"` ErrShowLineLength bool `long:"err-show-line-length" description:"sh ow all line length errors"`
ErrSkipLineLength bool `long:"err-skip-line-length" description:"sk ip line length errors"` ErrSkipLineLength bool `long:"err-skip-line-length" description:"sk ip line length errors"`
ExcludeDirs []string `long:"exclude-dirs" description:"do not rec urse into directories whose name matches GLOB" value-name:"GLOB" default-mask:"- "` ExcludeDirs []string `long:"exclude-dirs" description:"do not rec urse into directories whose name matches GLOB" value-name:"GLOB" default-mask:"- "`
IncludeExtensions string `short:"x" long:"ext" description:"limit sea rch to specific file extensions (comma-separated)" default-mask:"-"` IncludeExtensions string `short:"x" long:"ext" description:"limit sea rch to specific file extensions (comma-separated)" default-mask:"-"`
ExcludeExtensions string `short:"X" long:"exclude-ext" description:"e xclude specific file extensions (comma-separated)" default-mask:"-"` ExcludeExtensions string `short:"X" long:"exclude-ext" description:"e xclude specific file extensions (comma-separated)" default-mask:"-"`
IncludeFiles []string `long:"files" description:"search only files whose name matches GLOB" value-name:"GLOB" default-mask:"-"` IncludeFiles []string `long:"files" description:"search only files whose name matches GLOB" value-name:"GLOB" default-mask:"-"`
ExcludeFiles []string `long:"exclude-files" description:"do not se lect files whose name matches GLOB while recursing" value-name:"GLOB" default-ma sk:"-"` ExcludeFiles []string `long:"exclude-files" description:"do not se lect files whose name matches GLOB while recursing" value-name:"GLOB" default-ma sk:"-"`
IncludePath string `long:"path" description:"search only files whose path matches PATTERN" value-name:"PATTERN" default-mask:"-"` IncludePath string `long:"path" description:"search only files whose path matches PATTERN" value-name:"PATTERN" default-mask:"-"`
IncludeIPath string `long:"ipath" description:"search only files whose path matches PATTERN (case insensitive)" value-name:"PATTERN" default-mas k:"-"` IncludeIPath string `long:"ipath" description:"search only files whose path matches PATTERN (case insensitive)" value-name:"PATTERN" default-mas k:"-"`
ExcludePath string `long:"exclude-path" description:"do not sea rch files whose path matches PATTERN" value-name:"PATTERN" default-mask:"-"` ExcludePath string `long:"exclude-path" description:"do not sea rch files whose path matches PATTERN" value-name:"PATTERN" default-mask:"-"`
ExcludeIPath string `long:"exclude-ipath" description:"do not se arch files whose path matches PATTERN (case insensitive)" value-name:"PATTERN" d efault-mask:"-"` ExcludeIPath string `long:"exclude-ipath" description:"do not se arch files whose path matches PATTERN (case insensitive)" value-name:"PATTERN" d efault-mask:"-"`
IncludeTypes string `short:"t" long:"type" description:"limit se arch to specific file types (comma-separated, see --list-types)" default-mask:"- "` IncludeTypes string `short:"t" long:"type" description:"limit se arch to specific file types (comma-separated, see --list-types)" default-mask:"- "`
ExcludeTypes string `short:"T" long:"no-type" description:"exclu ExcludeTypes string `short:"T" long:"no-type" description:"exclu
de specific file types (comma-separated, --list-types)" default-mask:"-"` de specific file types (comma-separated, see --list-types)" default-mask:"-"`
AddCustomTypes []string `long:"add-type" description:"add custom typ
e (see --list-types for format)" default-mask:"-" json:"-"`
DelCustomTypes []string `long:"del-type" description:"remove custom
type" default-mask:"-" json:"-"`
CustomTypes map[string]string
FieldSeparator string `long:"field-sep" description:"column separa
tor (default: \":\")" default-mask:"-"`
FilesWithMatches bool `short:"l" long:"files-with-matches" descrip tion:"list files containing matches"` FilesWithMatches bool `short:"l" long:"files-with-matches" descrip tion:"list files containing matches"`
FilesWithoutMatch bool `short:"L" long:"files-without-match" descri ption:"list files containing no match"` FilesWithoutMatch bool `short:"L" long:"files-without-match" descri ption:"list files containing no match"`
FollowSymlinks bool `long:"follow" description:"follow symlinks" ` FollowSymlinks bool `long:"follow" description:"follow symlinks" `
Git bool `long:"git" description:"respect .gitignore files and skip .git directories"` Git bool `long:"git" description:"respect .gitignore files and skip .git directories"`
GroupByFile bool `long:"group" description:"group output by f ile (default: off)"` GroupByFile bool `long:"group" description:"group output by f ile (default: off)"`
NoGroupByFile func() `long:"no-group" description:"do not group o utput by file" json:"-"` NoGroupByFile func() `long:"no-group" description:"do not group o utput by file" json:"-"`
IgnoreCase bool `short:"i" long:"ignore-case" description:"c ase insensitive (default: off)"` IgnoreCase bool `short:"i" long:"ignore-case" description:"c ase insensitive (default: off)"`
NoIgnoreCase func() `short:"I" long:"no-ignore-case" description :"disable case insensitive" json:"-"` NoIgnoreCase func() `short:"I" long:"no-ignore-case" description :"disable case insensitive" json:"-"`
SmartCase bool `short:"s" long:"smart-case" description:"ca se insensitive unless pattern contains uppercase characters (default: off)"` SmartCase bool `short:"s" long:"smart-case" description:"ca se insensitive unless pattern contains uppercase characters (default: off)"`
NoSmartCase func() `short:"S" long:"no-smart-case" description: "disable smart case" json:"-"` NoSmartCase func() `short:"S" long:"no-smart-case" description: "disable smart case" json:"-"`
skipping to change at line 97 skipping to change at line 102
Recursive bool `short:"r" long:"recursive" description:"rec urse into directories (default: on)"` Recursive bool `short:"r" long:"recursive" description:"rec urse into directories (default: on)"`
NoRecursive func() `short:"R" long:"no-recursive" description:" do not recurse into directories" json:"-"` NoRecursive func() `short:"R" long:"no-recursive" description:" do not recurse into directories" json:"-"`
Replace string `long:"replace" description:"replace numbere d or named (?P<name>pattern) capture groups. Use ${1}, ${2}, $name, ... for capt ured submatches" json:"-"` Replace string `long:"replace" description:"replace numbere d or named (?P<name>pattern) capture groups. Use ${1}, ${2}, $name, ... for capt ured submatches" json:"-"`
ShowFilename string ShowFilename string
ShowFilenameFunc func() `long:"filename" description:"enforce printing the filename before results (default: auto)" json:"-"` ShowFilenameFunc func() `long:"filename" description:"enforce printing the filename before results (default: auto)" json:"-"`
NoShowFilenameFunc func() `long:"no-filename" description:"disable print ing the filename before results" json:"-"` NoShowFilenameFunc func() `long:"no-filename" description:"disable print ing the filename before results" json:"-"`
ShowLineNumbers bool `short:"n" long:"line-number" description:"sho w line numbers (default: off)"` ShowLineNumbers bool `short:"n" long:"line-number" description:"sho w line numbers (default: off)"`
NoShowLineNumbers func() `short:"N" long:"no-line-number" description:" do not show line numbers" json:"-"` NoShowLineNumbers func() `short:"N" long:"no-line-number" description:" do not show line numbers" json:"-"`
ShowColumnNumbers bool `long:"column" description:"show column number s"` ShowColumnNumbers bool `long:"column" description:"show column number s"`
NoShowColumnNumbers func() `long:"no-column" description:"do not show col umn numbers" json:"-"` NoShowColumnNumbers func() `long:"no-column" description:"do not show col umn numbers" json:"-"`
ShowByteOffset bool `long:"byte-offset" description:"show the byte
offset before each output line"`
NoShowByteOffset func() `long:"no-byte-offset" description:"do not sho
w the byte offset before each output line" json:"-"`
Stats bool `long:"stats" description:"show statistics"` Stats bool `long:"stats" description:"show statistics"`
TargetsOnly bool `long:"targets" description:"only list selecte d files, do not search"` TargetsOnly bool `long:"targets" description:"only list selecte d files, do not search"`
ListTypes func() `long:"list-types" description:"list available file types" json:"-" default-mask:"-"` ListTypes bool `long:"list-types" description:"list available file types" json:"-" default-mask:"-"`
Version func() `short:"V" long:"version" description:"show ve rsion and license information" json:"-"` Version func() `short:"V" long:"version" description:"show ve rsion and license information" json:"-"`
WordRegexp bool `short:"w" long:"word-regexp" description:"onl y match on ASCII word boundaries"` WordRegexp bool `short:"w" long:"word-regexp" description:"onl y match on ASCII word boundaries"`
WriteConfig bool `long:"write-config" description:"save config for loaded configs + given command line arguments" json:"-"` WriteConfig bool `long:"write-config" description:"save config for loaded configs + given command line arguments" json:"-"`
Zip bool `short:"z" long:"zip" description:"search cont ent of compressed .gz files (default: off)"` Zip bool `short:"z" long:"zip" description:"search cont ent of compressed .gz files (default: off)"`
NoZip func() `short:"Z" long:"no-zip" description:"do not s earch content of compressed .gz files" json:"-"` NoZip func() `short:"Z" long:"no-zip" description:"do not s earch content of compressed .gz files" json:"-"`
FileConditions struct { FileConditions struct {
FileMatches []string `long:"file-matches" description:"only s how matches if file also matches PATTERN" value-name:"PATTERN"` FileMatches []string `long:"file-matches" description:"only s how matches if file also matches PATTERN" value-name:"PATTERN"`
LineMatches []string `long:"line-matches" description:"only s how matches if line NUM matches PATTERN" value-name:"NUM:PATTERN"` LineMatches []string `long:"line-matches" description:"only s how matches if line NUM matches PATTERN" value-name:"NUM:PATTERN"`
RangeMatches []string `long:"range-matches" description:"only show matches if lines X-Y match PATTERN" value-name:"X:Y:PATTERN"` RangeMatches []string `long:"range-matches" description:"only show matches if lines X-Y match PATTERN" value-name:"X:Y:PATTERN"`
skipping to change at line 170 skipping to change at line 177
confpath := filepath.Join(path, SiftConfigFile) confpath := filepath.Join(path, SiftConfigFile)
if _, err := os.Stat(confpath); err == nil { if _, err := os.Stat(confpath); err == nil {
return confpath return confpath
} }
lp = path lp = path
path = filepath.Dir(path) path = filepath.Dir(path)
} }
return "" return ""
} }
// func listTypes list the available types (built-in and custom) and exits.
func listTypes() {
fmt.Println("The following list shows all file types supported.")
fmt.Println("Use --type/--no-type to include/exclude file types.")
fmt.Println("")
var types []string
for t := range global.fileTypesMap {
types = append(types, t)
}
sort.Strings(types)
for _, e := range types {
t := global.fileTypesMap[e]
var shebang string
if t.ShebangRegex != nil {
shebang = fmt.Sprintf("or first line matches /%s/", t.She
bangRegex)
}
fmt.Printf("%-15s:%s %s\n", e, strings.Join(t.Patterns, " "), she
bang)
}
fmt.Println("")
fmt.Println(`Custom types can be added with --add-type.`)
fmt.Println(`Example matching *.rb, *.erb, Rakefile and all files whose f
irst line matches the regular expression /\bruby\b/:`)
fmt.Println(`sift --add-type 'ruby=*.rb,*.erb,Rakefile;\bruby\b'`)
fmt.Println(`Write the definition to the config file:`)
fmt.Println(`sift --add-type 'ruby=*.rb,*.erb,Rakefile;\bruby\b' --write-
config`)
fmt.Println(`Remove the definition from the config file:`)
fmt.Println(`sift --del-type ruby --write-config`)
fmt.Println("")
os.Exit(0)
}
// LoadDefaults sets default options. // LoadDefaults sets default options.
func (o *Options) LoadDefaults() { func (o *Options) LoadDefaults() {
o.Cores = runtime.NumCPU() o.Cores = runtime.NumCPU()
o.OutputSeparator = "" o.OutputSeparator = ""
o.FieldSeparator = ":"
o.ShowFilename = "auto" o.ShowFilename = "auto"
o.Color = "auto" o.Color = "auto"
o.Recursive = true o.Recursive = true
o.CustomTypes = make(map[string]string)
o.ColorFunc = func() { o.ColorFunc = func() {
o.Color = "on" o.Color = "on"
} }
o.NoColorFunc = func() { o.NoColorFunc = func() {
o.Color = "off" o.Color = "off"
} }
o.NoIgnoreCase = func() { o.NoIgnoreCase = func() {
o.IgnoreCase = false o.IgnoreCase = false
} }
skipping to change at line 211 skipping to change at line 250
} }
o.NoShowFilenameFunc = func() { o.NoShowFilenameFunc = func() {
o.ShowFilename = "off" o.ShowFilename = "off"
} }
o.NoShowLineNumbers = func() { o.NoShowLineNumbers = func() {
o.ShowLineNumbers = false o.ShowLineNumbers = false
} }
o.NoShowColumnNumbers = func() { o.NoShowColumnNumbers = func() {
o.ShowColumnNumbers = false o.ShowColumnNumbers = false
} }
o.NoShowByteOffset = func() {
o.ShowByteOffset = false
}
o.NoZip = func() { o.NoZip = func() {
o.Zip = false o.Zip = false
} }
o.Version = func() { o.Version = func() {
fmt.Printf("sift %s (%s/%s)\n", SiftVersion, runtime.GOOS, runtim e.GOARCH) fmt.Printf("sift %s (%s/%s)\n", SiftVersion, runtime.GOOS, runtim e.GOARCH)
fmt.Println("Copyright (C) 2014-2016 Sven Taute") fmt.Println("Copyright (C) 2014-2016 Sven Taute")
fmt.Println("") fmt.Println("")
fmt.Println("This program is free software: you can redistribute it and/or modify") fmt.Println("This program is free software: you can redistribute it and/or modify")
fmt.Println("it under the terms of the GNU General Public License as published by") fmt.Println("it under the terms of the GNU General Public License as published by")
fmt.Println("the Free Software Foundation, version 3 of the Licen se.") fmt.Println("the Free Software Foundation, version 3 of the Licen se.")
fmt.Println("") fmt.Println("")
fmt.Println("This program is distributed in the hope that it will be useful,") fmt.Println("This program is distributed in the hope that it will be useful,")
fmt.Println("but WITHOUT ANY WARRANTY; without even the implied w arranty of") fmt.Println("but WITHOUT ANY WARRANTY; without even the implied w arranty of")
fmt.Println("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the") fmt.Println("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the")
fmt.Println("GNU General Public License for more details.") fmt.Println("GNU General Public License for more details.")
fmt.Println("") fmt.Println("")
fmt.Println("You should have received a copy of the GNU General P ublic License") fmt.Println("You should have received a copy of the GNU General P ublic License")
fmt.Println("along with this program. If not, see <http://www.gnu .org/licenses/>.") fmt.Println("along with this program. If not, see <http://www.gnu .org/licenses/>.")
os.Exit(0) os.Exit(0)
} }
}
o.ListTypes = func() { // loadConfigFile loads options from the given config file.
fmt.Println("The following list shows all file types supported.") func (o *Options) loadConfigFile(configFilePath string, label string) {
fmt.Println("Use --type/--no-type to include/exclude file types." configFile, err := ioutil.ReadFile(configFilePath)
) if err == nil && len(configFile) > 0 {
fmt.Println("") if err := json.Unmarshal(configFile, &o); err != nil {
var types []string errorLogger.Printf("cannot parse %s '%s': %s\n", label, c
for t := range global.fileTypesMap { onfigFilePath, err)
types = append(types, t)
}
sort.Strings(types)
for _, e := range types {
t := global.fileTypesMap[e]
var shebang string
if t.ShebangRegex != nil {
shebang = fmt.Sprintf(" or first line matches /%s
/", t.ShebangRegex)
}
fmt.Printf("%-15s%s%s\n", t.Name+":", strings.Join(t.Patt
erns, " "), shebang)
} }
os.Exit(0) }
if err != nil {
errorLogger.Printf("cannot open %s '%s': %s\n", label, configFile
Path, err)
} }
} }
// LoadConfigs tries to load options from sift config files. // LoadConfigs tries to load options from sift config files.
func (o *Options) LoadConfigs() { // if noConf is true, only a config file set via option --conf will be parsed.
// load config from global sift config if file exists func (o *Options) LoadConfigs(noConf bool, configFileArg string) {
if homedir := getHomeDir(); homedir != "" { if !noConf {
configFilePath := filepath.Join(homedir, SiftConfigFile) // load config from global sift config if file exists
configFile, err := ioutil.ReadFile(configFilePath) if homedir := getHomeDir(); homedir != "" {
if err == nil && len(configFile) > 0 { configFilePath := filepath.Join(homedir, SiftConfigFile)
if err := json.Unmarshal(configFile, &o); err != nil { if _, err := os.Stat(configFilePath); err == nil {
errorLogger.Printf("cannot parse global config '% o.loadConfigFile(configFilePath, "global config")
s': %s\n", configFilePath, err)
} }
} }
}
// load config from local sift config if file exists // load config from local sift config if file exists
if configFilePath := findLocalConfig(); configFilePath != "" { if configFilePath := findLocalConfig(); configFilePath != "" {
configFile, err := ioutil.ReadFile(configFilePath) if _, err := os.Stat(configFilePath); err == nil {
if err == nil && len(configFile) > 0 { o.loadConfigFile(configFilePath, "local config")
if err := json.Unmarshal(configFile, &o); err != nil {
errorLogger.Printf("cannot parse local config '%s
': %s\n", configFilePath, err)
} }
} }
} }
// load config from config option
if configFileArg != "" {
o.loadConfigFile(configFileArg, "config")
}
} }
// Apply processes user provided options // Apply processes user provided options
func (o *Options) Apply(patterns []string, targets []string) error { func (o *Options) Apply(patterns []string, targets []string) error {
if err := o.processTypes(); err != nil {
return err
}
if err := o.checkFormats(); err != nil { if err := o.checkFormats(); err != nil {
return err return err
} }
if err := o.processConditions(); err != nil { if err := o.processConditions(); err != nil {
return err return err
} }
if err := o.checkCompatibility(patterns, targets); err != nil { if err := o.checkCompatibility(patterns, targets); err != nil {
return err return err
skipping to change at line 315 skipping to change at line 356
} }
for i := range patterns { for i := range patterns {
patterns[i] = o.preparePattern(patterns[i]) patterns[i] = o.preparePattern(patterns[i])
} }
runtime.GOMAXPROCS(o.Cores) runtime.GOMAXPROCS(o.Cores)
return nil return nil
} }
// processTypes processes custom types defined on the command line
// or in the config file.
func (o *Options) processTypes() error {
for _, e := range o.DelCustomTypes {
if _, ok := o.CustomTypes[e]; !ok {
return fmt.Errorf("No custom type definition for '%s' fou
nd", e)
}
delete(o.CustomTypes, e)
}
for _, e := range o.AddCustomTypes {
s := strings.SplitN(e, "=", 2)
if len(s) != 2 {
return fmt.Errorf("wrong format for type definition '%s'"
, e)
}
o.CustomTypes[s[0]] = s[1]
}
// parse type definition, e.g. '*.pl,*.pm;\bperl\b'
for name, e := range o.CustomTypes {
var ft FileType
s := strings.SplitN(e, ";", 2)
if len(s) == 2 && s[1] != "" {
re, err := regexp.Compile(s[1])
if err != nil {
return fmt.Errorf("cannot parse regular expressio
n '%s' for custom type '%s': %s", s[1], name, err)
}
ft.ShebangRegex = re
}
patterns := strings.Split(s[0], ",")
ft.Patterns = patterns
global.fileTypesMap[name] = ft
}
if o.ListTypes {
listTypes()
}
return nil
}
// checkFormats checks options for illegal formats // checkFormats checks options for illegal formats
func (o *Options) checkFormats() error { func (o *Options) checkFormats() error {
if o.ExcludePath != "" { if o.ExcludePath != "" {
var err error var err error
global.excludeFilepathRegex, err = regexp.Compile(o.ExcludePath) global.excludeFilepathRegex, err = regexp.Compile(o.ExcludePath)
if err != nil { if err != nil {
return fmt.Errorf("cannot parse exclude filepath pattern '%s': %s\n", o.ExcludePath, err) return fmt.Errorf("cannot parse exclude filepath pattern '%s': %s\n", o.ExcludePath, err)
} }
} }
if o.ExcludeIPath != "" { if o.ExcludeIPath != "" {
 End of changes. 17 change blocks. 
40 lines changed or deleted 131 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)