func Contracts(sous *core.Sous, args []string) { contractsFlags.Parse(args) args = contractsFlags.Args() timeout := *timeoutFlag targetName := "app" if len(args) != 0 { targetName = args[0] } core.RequireGit() core.RequireDocker() if *dockerImage != "" { cli.Fatalf("-image flag not yet implemented") } target, context := sous.AssembleTargetContext(targetName) sous.RunTarget(target, context) cli.Logf("=> Running Contracts") cli.Logf(`=> **TIP:** Open another terminal in this directory and type **sous logs -f**`) taskHost := core.DivineTaskHost() port0, err := ports.GetFreePort() if err != nil { cli.Fatalf("Unable to get free port: %s", err) } dr := docker.NewRun(context.DockerTag()) dr.AddEnv("PORT0", strconv.Itoa(port0)) dr.AddEnv("TASK_HOST", taskHost) dr.StdoutFile = context.FilePath("stdout") dr.StderrFile = context.FilePath("stderr") container, err := dr.Background().Start() if err != nil { cli.Fatalf("Unable to start container: %s", err) } cli.AddCleanupTask(func() error { return container.KillIfRunning() }) failed := 0 for _, c := range theContracts { cli.Logf(`===> CHECKING CONTRACT: "%s"`, c.Name) cli.Logf(`===> Description: %s`, c.Desc(dr)) if c.Tips != nil { cli.Logf("===> **TIPS for this contract:**") cli.LogBulletList(" -", c.Tips(dr)) } failed += within(timeout, func() bool { return c.Premise(dr) }) } if failed != 0 { cli.Fatalf("%d contracts failed.", failed) } cli.Success() }
// RemoveOnExit is a convenience wrapper that safely ensures the // named file is removed after execution, by adding a cleanup task // to the cli singleton. func RemoveOnExit(path string) { cli.AddCleanupTask(func() error { if Exists(path) { Remove(path) } if Exists(path) { return fmt.Errorf("Unable to remove temporary object %s; please remove it manually.", path) } return nil }) }