Beispiel #1
0
func ExecuteAsCommand(o *common.Opt) (err error) {
	term = os.Getenv("TERM")
	_, err = Execute(o)
	if err != nil {
		if !o.Quiet {
			fmt.Println(err)
		}
		return
	}
	if !o.Quiet {
		for i := range violations {
			if !violations[i].Fixed {
				printViolation(violations[i])
			}
		}
	}

	vcnt := 0
	for i := range violations {
		if !violations[i].Fixed {
			vcnt++
		}
	}
	if 0 < vcnt {
		if !o.Quiet {
			fmt.Printf("\n%d %s generated.\n",
				vcnt, pluralize(vcnt, "warning", "warnings"))
		}
		err = common.NewError("error while executing lint")
	}
	return
}
Beispiel #2
0
func Execute(o *common.Opt) (v []common.Violation, err error) {
	// Clear global vars
	violations = []common.Violation{}
	common.BufSize = 0

	if o.SrcRoot == "" {
		err = common.NewError("source directory is required.")
		return
	}
	if o.Id == "" {
		err = common.NewError("ID of the rule set is required.")
		return
	}
	opt = o
	err = MkReportDir(false)
	if err != nil {
		return
	}

	if opt.ConfigPath == "" {
		err = common.NewError("config directory is required.")
		return
	}

	err = LoadConfig()
	if err != nil {
		return
	}

	printReportHeader()

	err = Lint(opt.SrcRoot)

	finishReportFiles()

	return violations, err
}
Beispiel #3
0
func MkReportDir(whenNotExist bool) (err error) {
	if opt.Html == "" {
		return
	}
	if !whenNotExist {
		if opt.Force {
			os.RemoveAll(opt.Html)
		} else {
			err = common.NewError("report directory already exists. use `-f` option to force reporting.")
			return
		}
	}
	err = os.MkdirAll(opt.Html, 0777)
	return
}
Beispiel #4
0
func LoadConfig() (err error) {
	// Get config directory(.fint)
	pathConfig := opt.ConfigPath
	if err = dirExists(pathConfig); err != nil {
		return
	}

	// Get target ID directory
	pathTarget := filepath.Join(pathConfig, common.DirBuiltin, common.DirTargets, opt.Id)
	if err = dirExists(pathTarget); err != nil {
		return common.NewError("no matching target to [" + opt.Id + "]")
	}

	// Get modules directory
	pathModules := filepath.Join(pathConfig, common.DirBuiltin, common.DirModules)
	if err = dirExists(pathModules); err != nil {
		return common.NewError("modules directory not found in [" + pathModules + "]")
	}

	// Load .fint/builtin/modules/*/config.json
	config = new(common.Config)
	filesModules, _ := ioutil.ReadDir(pathModules)
	for i := range filesModules {
		entry := filesModules[i]
		if entry.IsDir() {
			// entry name is the name of module
			entryPath := filepath.Join(pathModules, entry.Name())
			var configBytes []byte
			configBytes, err = ioutil.ReadFile(filepath.Join(entryPath, common.FileConfig))
			if err != nil {
				return
			}

			var c common.ModuleConfig
			json.Unmarshal(configBytes, &c)

			// Set name as Id to be searchable
			c.Id = entry.Name()
			config.ModuleConfigs = append(config.ModuleConfigs, c)
		}
	}

	// Load target ruleset
	var configBytes []byte
	configBytes, err = ioutil.ReadFile(filepath.Join(pathTarget, common.FileRuleSet))
	if err != nil {
		return common.NewError("no matching target to [" + opt.Id + "]")
	}
	var target common.Target
	json.Unmarshal(configBytes, &target)
	config.Targets = append(config.Targets, target)

	// Load target locales
	filesTargetLocales, _ := ioutil.ReadDir(filepath.Join(pathTarget, common.DirLocales))
	for i := range filesTargetLocales {
		entry := filesTargetLocales[i]
		locale := strings.TrimSuffix(entry.Name(), filepath.Ext(entry.Name()))

		// Get contents of en.json, ja.json, ...
		var configBytes []byte
		configBytes, _ = ioutil.ReadFile(filepath.Join(pathTarget, common.DirLocales, entry.Name()))

		var lt common.LocalizedTarget
		json.Unmarshal(configBytes, &lt)

		for i := range target.RuleSets {
			for j := range target.RuleSets[i].Modules {
				for k := range target.RuleSets[i].Modules[j].Rules {
					// Pass all localized messages for each rules
					if target.RuleSets[i].Modules[j].Rules[k].Message == nil {
						target.RuleSets[i].Modules[j].Rules[k].Message = make(map[string]string)
					}
					target.RuleSets[i].Modules[j].Rules[k].Message[locale] = lt.RuleSets[i].Modules[j].Rules[k].Message
				}
			}
		}
	}
	return
}
Beispiel #5
0
func LintFile(srcRoot string, m common.Module, locale string, fix bool, lintWalkFunc LintWalkFunc) (fmap map[string]map[int][]common.Violation, err error) {
	filename := srcRoot
	if matched, _ := regexp.MatchString(m.Pattern, filename); !matched {
		return
	}
	if fmap == nil {
		fmap = make(map[string]map[int][]common.Violation)
	}
	var f *os.File
	f, err = os.Open(filename)
	if err != nil {
		err = common.NewError("cannot open " + filename)
		return
	}
	defer f.Close()
	var ftmp *os.File
	if fix {
		// Prepare fixed file
		ftmp, _ = os.OpenFile(filename+".tmp", os.O_RDWR|os.O_CREATE, 0666)
		defer ftmp.Close()
	}
	if common.BufSize == 0 {
		common.BufSize = common.DefaultBufSize
	}
	r := bufio.NewReaderSize(f, common.BufSize)
	vmap := make(map[int][]common.Violation)
	for n := 1; true; n++ {
		var line string
		line, err = r.ReadString(common.LinefeedRune)
		if err != io.EOF && err != nil {
			return
		}
		var lvs []common.Violation
		vsr, fixedAny, fixedLine := lintWalkFunc(m, n, filename, strings.TrimSuffix(line, common.Linefeed), locale, fix)
		tmpLine := line
		if vsr != nil {
			lvs = append(lvs, vsr...)
			if fixedAny {
				if strings.HasSuffix(line, common.Linefeed) {
					tmpLine = fixedLine + common.Linefeed
				} else {
					tmpLine = fixedLine
				}
			}
		}
		if fix {
			ftmp.WriteString(tmpLine)
		}
		vmap[n] = lvs
		if err == io.EOF {
			err = nil
			break
		}
	}
	if fix {
		ftmp.Close()
		os.Remove(filename)
		CopyFile(filename+".tmp", filename)
		os.Remove(filename + ".tmp")
	}
	if fmap[filename] == nil {
		fmap[filename] = make(map[int][]common.Violation)
	}
	fmap[filename] = vmap
	return
}