コード例 #1
0
ファイル: pull.go プロジェクト: willdr3/lingo
func pull(c *cli.Context) {
	all := c.Bool("all")
	expectedArgs := 1
	if all {
		expectedArgs = 0
	}
	if l := len(c.Args()); l != expectedArgs {
		common.OSErrf("expected %d argument(s), got %d", expectedArgs, l)
		return
	}

	if all {
		fmt.Println("pulling all tenets found in .lingo ...")
		if err := pullAll(c); err != nil {
			common.OSErrf(err.Error())
		}
		return
	}

	// TODO(waigani) It doesn't make sense to have both registry and source.
	// Either registry for docker or source for binary.
	reg := c.String("registry")
	source := c.String("source")
	driver := c.String("driver")

	if err := pullOne(c, c.Args().First(), driver, reg, source); err != nil {
		common.OSErrf(err.Error())
	}
}
コード例 #2
0
ファイル: tenet.go プロジェクト: howbazaar/lingo
// TenetCMD is a fallthrough CMD which treats command as the tenet name and
// passes through any arguments to the tenet.
func TenetCMD(ctx *cli.Context, command string) {
	var commandIsTenet bool
	var cfg common.TenetConfig
	// Does the command match an installed tenet?
	for _, cfg = range listTenets(ctx) {
		if command == cfg.Name {
			commandIsTenet = true
			break
		}
	}
	if !commandIsTenet {
		fmt.Println("command not found")
		return
	}

	tnCMDs, err := newTenetCMDs(ctx, cfg)
	if err != nil {
		common.OSErrf(err.Error())
		return
	}
	defer tnCMDs.closeService()

	if err := tnCMDs.run(); err != nil {
		common.OSErrf(err.Error())
		return
	}
	return
}
コード例 #3
0
ファイル: review.go プロジェクト: howbazaar/lingo
func reviewAction(ctx *cli.Context) {
	opts := review.Options{
		Files:      ctx.Args(),
		Diff:       ctx.Bool("diff"),
		SaveToFile: ctx.String("save"),
		KeepAll:    ctx.Bool("keep-all"),
	}
	issues, err := review.Review(opts)
	if err != nil {
		common.OSErrf(err.Error())
		return
	}

	// TODO(waigani) I'm not happy that we're doing this here, can't find a
	// better place though.
	saveToFile := ctx.String("save")
	if saveToFile != "" {
		err := review.Save(saveToFile, issues)
		if err != nil {
			common.OSErrf("could not save to file: %s", err.Error())
			return
		}
		fmt.Printf("review saved to %s\n", saveToFile)
	}

	// TODO(waigani) make more informative
	// TODO(waigani) if !ctx.String("quiet")
	fmt.Printf("Done! Found %d issues \n", len(issues))
}
コード例 #4
0
ファイル: pull.go プロジェクト: howbazaar/lingo
func pull(c *cli.Context) {
	all := c.Bool("all")
	expectedArgs := 1
	if all {
		expectedArgs = 0
	}
	if l := len(c.Args()); l != expectedArgs {
		common.OSErrf("expected %d argument(s), got %d", expectedArgs, l)
		return
	}

	if all {
		fmt.Println("pulling all tenets found in .lingo ...")
		if err := pullAll(c); err != nil {
			common.OSErrf(err.Error())
		}
		return
	}

	reg := c.String("registry")
	driver := c.String("driver")

	if err := pullOne(c, c.Args().First(), driver, reg); err != nil {
		common.OSErrf(err.Error())
	}
}
コード例 #5
0
ファイル: add.go プロジェクト: howbazaar/lingo
func add(c *cli.Context) {
	if l := len(c.Args()); l != 1 {
		common.OSErrf("expected 1 argument, got %d", l)
		return
	}

	cfgPath, err := common.TenetCfgPath(c)
	if err != nil {
		common.OSErrf("reading config file: %s", err.Error())
		return
	}
	cfg, err := common.BuildConfig(cfgPath, common.CascadeNone)
	if err != nil {
		common.OSErrf("reading config file: %s", err.Error())
		return
	}

	imageName := c.Args().First()

	groupName := c.String("group")
	g, err := cfg.FindTenetGroup(groupName)
	if err == nil && common.HasTenet(g.Tenets, imageName) {
		common.OSErrf(`error: tenet "%s" already added`, imageName)
		return
	}

	// TODO(waigani) DEMOWARE. This will panic with wrong input. Matt didn't
	// your first PR bring in options?
	opts := map[string]interface{}{}
	if optStr := c.String("options"); optStr != "" {
		// TODO: DEMOWARE. Only set one option at a time to allow spaces in value
		//for _, part := range strings.Split(optStr, " ") {
		p := strings.Split(optStr, "=")
		opts[p[0]] = p[1]
		//}
	}

	var registry string
	driver := c.String("driver")
	if driver == "docker" {
		registry = c.String("registry")
	}

	cfg.AddTenet(common.TenetConfig{
		Name:     imageName,
		Driver:   driver,
		Registry: registry,
		Options:  opts,
	}, groupName)

	if err := common.WriteConfigFile(c, cfg); err != nil {
		common.OSErrf(err.Error())
		return
	}

	// TODO(waigani) open an interactive shell, prompt to set options.
}
コード例 #6
0
ファイル: copr.go プロジェクト: howbazaar/lingo
func copr(c *cli.Context) {
	cliArgs := c.Args()
	if err := common.ExactArgs(c, 1); err != nil {
		common.OSErrf(err.Error())
		return
	}

	repoPath, err := exec.Command("git", "rev-parse", "--show-toplevel").Output()
	if err != nil {
		common.OSErrf(err.Error())
		return
	}
	repo := path.Base(strings.Trim(string(repoPath), "\n"))
	var fetchAll string
	if !c.Bool("skip-fetch-all") {
		fetchAll = "git fetch --all"
	}

	argParts := strings.Split(cliArgs[0], ":")
	args := map[string]string{
		"User":     argParts[0],
		"Repo":     repo,
		"Branch":   argParts[1],
		"Base":     strings.Replace(c.String("base"), ":", "/", -1),
		"FetchAll": fetchAll,
		"Host":     c.String("host"),
	}
	bashScript, err := util.FormatOutput(args, coprcmd)
	if err != nil {
		common.OSErrf(err.Error())
		return
	}

	if c.Bool("dry-run") {
		fmt.Println("execute the following bash script:")
		fmt.Println(bashScript)
		return
	}

	cmd := exec.Command("bash", "-c", bashScript)
	cmd.Stderr = os.Stderr
	cmd.Stdout = os.Stdout
	err = cmd.Run()
	if err != nil {
		common.OSErrf(err.Error())
		return
	}
}
コード例 #7
0
ファイル: reviewboard.go プロジェクト: howbazaar/lingo
func rbAction(ctx *cli.Context) {
	if err := rb(ctx); err != nil {
		common.OSErrf(err.Error())
		return
	}
	fmt.Println("Done! Review sent to Review Board.")
}
コード例 #8
0
ファイル: validate.go プロジェクト: howbazaar/lingo
func validate(c *cli.Context) {
	if err := common.ExactArgs(c, 1); err != nil {
		common.OSErrf(err.Error())
		return
	}

	// imageName := c.Args().First()
}
コード例 #9
0
ファイル: list.go プロジェクト: howbazaar/lingo
func listTenets(c *cli.Context) []common.TenetConfig {
	cfgPath, err := common.TenetCfgPath(c)
	if err != nil {
		if _, ok := err.(*os.PathError); ok {
			// For missing config files, there are just no tenets
			return nil
		}
		// For malformed config show the error to the user
		common.OSErrf("could not read configuration: %s", err.Error())
		return nil
	}
	cfg, err := common.BuildConfig(cfgPath, common.CascadeNone)
	if err != nil {
		common.OSErrf("could not read configuration: %s", err.Error())
		return nil
	}
	return cfg.AllTenets()
}
コード例 #10
0
ファイル: config.go プロジェクト: howbazaar/lingo
func editConfigAction(ctx *cli.Context) {
	cfg := config.DefaultsCfgFile
	if args := ctx.Args(); len(args) > 0 {
		cfg = args[0] + ".yaml"
	}

	if err := config.Edit(cfg, "vi"); err != nil {
		common.OSErrf(err.Error())
	}
}
コード例 #11
0
ファイル: build.go プロジェクト: willdr3/lingo
func buildAction(ctx *cli.Context) {
	drivers := ctx.Args()
	if len(drivers) == 0 {
		drivers = allDrivers
	}

	if err := build(drivers, ctx.Bool("all")); err != nil {
		common.OSErrf(err.Error())
	}
}
コード例 #12
0
ファイル: docs.go プロジェクト: howbazaar/lingo
func docs(c *cli.Context) {

	fmt.Println("Opening tenet documentation in a new browser window ...")

	var mdBuf bytes.Buffer
	if err := writeTenetDoc(c, "", &mdBuf); err != nil {
		common.OSErrf("%v", err)
		return
	}

	// Render markdown to HTML, and sanitise it to protect from
	// malicious tenets.
	htmlUnsafe := blackfriday.MarkdownBasic(mdBuf.Bytes())
	html := bluemonday.UGCPolicy().SanitizeBytes(htmlUnsafe)

	if err := browser.OpenReader(bytes.NewReader(html)); err != nil {
		common.OSErrf("opening docs in browser: %v", err)
		return
	}
}
コード例 #13
0
ファイル: add.go プロジェクト: howbazaar/lingo
func defaultDriver() string {
	cfg, err := config.Defaults()
	if err != nil {
		return "binary"
	}

	driver := cfg.Tenet.Driver
	if driver != "binary" && driver != "docker" {
		common.OSErrf("invalid driver default: %q", driver)
	}
	return driver
}
コード例 #14
0
ファイル: remove.go プロジェクト: howbazaar/lingo
func remove(c *cli.Context) {
	if l := len(c.Args()); l != 1 {
		common.OSErrf("error: expected 1 argument, got %d", l)
		return
	}

	cfgPath, err := common.TenetCfgPath(c)
	if err != nil {
		common.OSErrf("reading config file: %s", err.Error())
		return
	}
	cfg, err := common.BuildConfig(cfgPath, common.CascadeNone)
	if err != nil {
		common.OSErrf("reading config file: %s", err.Error())
		return
	}

	imageName := c.Args().First()

	if !cfg.HasTenet(imageName) {
		common.OSErrf(`error: tenet "%s" not found in %q`, imageName, c.GlobalString(common.TenetCfgFlg.Long))
		return
	}

	if err := cfg.RemoveTenet(imageName, c.String("group")); err != nil {
		common.OSErrf(err.Error())
		return
	}

	if err := common.WriteConfigFile(c, cfg); err != nil {
		common.OSErrf(err.Error())
		return
	}
}
コード例 #15
0
ファイル: write_doc.go プロジェクト: howbazaar/lingo
func writeDoc(c *cli.Context) {
	outputPath := c.String("output")
	if dir, _ := path.Split(outputPath); dir != "" {
		err := os.MkdirAll(dir, 0775)
		if err != nil {
			common.OSErrf(err.Error())
			return
		}
	}
	outputFile, err := os.Create(outputPath)
	if err != nil {
		common.OSErrf(err.Error())
		return
	}
	defer outputFile.Close()

	if err := writeTenetDoc(c, c.String("template"), outputFile); err != nil {
		common.OSErrf(err.Error())
		return
	}
	fmt.Printf("Tenet documentation written to %s\n", outputFile.Name())
}
コード例 #16
0
ファイル: push.go プロジェクト: willdr3/lingo
func push(ctx *cli.Context) {

	// TODO(waigani) a lot of this code is to support multiple drivers. It's
	// copied from build. It's left so we can easily add remote. We just hard
	// code to docker for now.

	if len(ctx.Args()) > 0 {
		common.OSErrf("push takes no arguments")
	}

	// drivers := ctx.Args()
	// if len(drivers) == 0 {
	// 	drivers = allDrivers
	// }
	drivers := []string{"docker"}

	lingofiles, err := getLingoFiles(ctx.Bool("all"))
	if err != nil {
		common.OSErrf(err.Error())
		return
	}
	fn := len(lingofiles)
	if fn == 0 {
		util.Printf("WARNING tenet not built. No %s found.\n", common.Lingofile)
		return
	}

	// set up drivers, waitgroups and progress bars
	allErrsc := make(chan error)
	allWaits := sync.WaitGroup{}
	dn := len(drivers)
	allWaits.Add(dn)

	driverWaits := make(map[string]*bt.DriverWait, dn)
	for _, driver := range drivers {
		bar := pb.New(fn)
		bar.Prefix(driver + " ")

		start := &sync.WaitGroup{}
		start.Add(fn)
		end := &sync.WaitGroup{}
		end.Add(fn)
		driverWaits[driver] = &bt.DriverWait{
			Start: start,
			End:   end,
			Bar:   bar,
		}

		errsc := make(chan error)
		go func(wg *sync.WaitGroup, errc chan error) {
			wg.Wait()
			bar.FinishPrint("Success! All " + driver + " tenets built.")

			close(errsc)
			allWaits.Done()

		}(end, errsc)

		go func(errsc chan error) {
			for err := range errsc {
				allErrsc <- err
			}

		}(errsc)
	}

	// print progress bars to user
	for driver, dw := range driverWaits {
		go func(dw *bt.DriverWait) {
			dw.Start.Wait()
			msg := "The %s tenet is being pushed ..."
			if fn > 0 {
				msg = "All %s tenets are being pushed ..."
			}
			util.Printf(msg, driver)
			dw.Bar.Start()
		}(dw)
	}

	// start building all tenets
	for _, f := range lingofiles {
		go func(f string) {
			errs := pushTenet(f, driverWaits)
			for _, err := range errs {
				allErrsc <- err
			}
		}(f)
	}

	// wait for all results and print errors at the end
	go func() {
		allWaits.Wait()
		close(allErrsc)
	}()

	var errs []error
	for err := range allErrsc {
		errs = append(errs, err)
	}
	// util.NoPrint = false
	for _, err := range errs {
		util.Printf("push error: %v\n", err)
	}

}
コード例 #17
0
ファイル: build.go プロジェクト: howbazaar/lingo
// TODO(waigani) add more user output
func build(ctx *cli.Context) {
	drivers := ctx.Args()
	if len(drivers) == 0 {
		drivers = allDrivers
	}

	lingofiles, err := getLingofiles(ctx)
	if err != nil {
		common.OSErrf(err.Error())
		return
	}
	fn := len(lingofiles)
	if fn == 0 {
		util.Printf("WARNING tenet not built. No %s found.\n", lingofile)
		return
	}

	// set up drivers, waitgroups and progress bars
	allErrsc := make(chan error)
	allWaits := sync.WaitGroup{}
	dn := len(drivers)
	allWaits.Add(dn)

	driverWaits := make(map[string]*driverWait, dn)
	for _, driver := range drivers {
		bar := pb.New(fn)
		bar.Prefix(driver + " ")

		start := &sync.WaitGroup{}
		start.Add(fn)
		end := &sync.WaitGroup{}
		end.Add(fn)
		driverWaits[driver] = &driverWait{
			start: start,
			end:   end,
			bar:   bar,
		}

		errsc := make(chan error)
		go func(wg *sync.WaitGroup, errc chan error) {
			wg.Wait()
			bar.FinishPrint("Success! All " + driver + " tenets built.")

			close(errsc)
			allWaits.Done()

		}(end, errsc)

		go func(errsc chan error) {
			for err := range errsc {
				allErrsc <- err
			}

		}(errsc)
	}

	// print progress bars to user
	for driver, dw := range driverWaits {
		go func(dw *driverWait) {
			dw.start.Wait()
			msg := "The %s tenet has started to build ..."
			if fn > 0 {
				msg = "All %s tenets have started to build ..."
			}
			util.Printf(msg, driver)
			dw.bar.Start()
		}(dw)
	}

	// start building all tenets
	for _, f := range lingofiles {
		go func(f string) {
			errs := buildTenet(f, driverWaits)
			for _, err := range errs {
				allErrsc <- err
			}
		}(f)
	}

	// wait for all results and print errors at the end
	go func() {
		allWaits.Wait()
		close(allErrsc)
	}()

	var errs []error
	for err := range allErrsc {
		errs = append(errs, err)
	}
	// util.NoPrint = false
	for _, err := range errs {
		util.Printf("build error: %v\n", err)
	}

}