Repository: docker/compose
File: cmd/compose/up.go (Go)

Code before:
	flags.BoolVar(&up.noColor, "no-color", false, "Produce monochrome output.")
	flags.BoolVar(&up.noPrefix, "no-log-prefix", false, "Don't print prefix in logs.")
	flags.BoolVar(&create.forceRecreate, "force-recreate", false, "Recreate containers even if their configuration and image haven't changed.")
	flags.BoolVar(&create.noRecreate, "no-recreate", false, "If containers already exist, don't recreate them. Incompatible with --force-recreate.")
	flags.BoolVar(&up.noStart, "no-start", false, "Don't start the services after creating them.")
	flags.BoolVar(&up.cascadeStop, "abort-on-container-exit", false, "Stops all containers if any container was stopped. Incompatible with -d")
	flags.StringVar(&up.exitCodeFrom, "exit-code-from", "", "Return the exit code of the selected service container. Implies --abort-on-container-exit")
	flags.IntVarP(&create.timeout, "timeout", "t", 10, "Use this timeout in seconds for container shutdown when attached or when containers are already running.")
	flags.BoolVar(&up.noDeps, "no-deps", false, "Don't start linked services.")
	flags.BoolVar(&create.recreateDeps, "always-recreate-deps", false, "Recreate dependent containers. Incompatible with --no-recreate.")
	flags.BoolVarP(&create.noInherit, "renew-anon-volumes", "V", false, "Recreate anonymous volumes instead of retrieving data from the previous containers.")
	flags.BoolVar(&up.attachDependencies, "attach-dependencies", false, "Attach to dependent containers.")
	flags.BoolVar(&create.quietPull, "quiet-pull", false, "Pull without printing progress information.")
	flags.StringArrayVar(&up.attach, "attach", []string{}, "Attach to service output.")
	flags.StringArrayVar(&up.wait, "wait", []string{}, "[SERVICE:]CONDITION Wait for service(s) to reach condition (started|healthy|completed_successfully). implies detached mode.")

	return upCmd
}

func validateFlags(up upOptions, create createOptions) error {
	if up.exitCodeFrom != "" {
		up.cascadeStop = true
	}
	if len(up.wait) > 0 {
		if up.attachDependencies || up.cascadeStop || len(up.attach) > 0 {
			return fmt.Errorf("--wait cannot be combined with --abort-on-container-exit, --attach or --attach-dependencies")
		}
		up.Detach = true
	}
	if create.Build && create.noBuild {
		return fmt.Errorf("--build and --no-build are incompatible")
	}
	if up.Detach && (up.attachDependencies || up.cascadeStop || len(up.attach) > 0) {
		return fmt.Errorf("--detach cannot be combined with --abort-on-container-exit, --attach or --attach-dependencies")
	}
	if create.forceRecreate && create.noRecreate {
		return fmt.Errorf("--force-recreate and --no-recreate are incompatible")
	}
	if create.recreateDeps && create.noRecreate {
		return fmt.Errorf("--always-recreate-deps and --no-recreate are incompatible")
	}
	return nil
}

func runUp(ctx context.Context, backend api.Service, createOptions createOptions, upOptions upOptions, project *types.Project, services []string) error {
	if len(project.Services) == 0 {
		return fmt.Errorf("no service selected")
	}

	createOptions.Apply(project)


Review comment (suggestion):
Shouldn’t all these be
```suggestion
			return errors.New("--wait cannot be combined with --abort-on-container-exit, --attach or --attach-dependencies")
```
?
I believe some linters and IDEs will complain about the `f` and no formatting flags in the string.

Code after:
	flags.BoolVar(&up.noColor, "no-color", false, "Produce monochrome output.")
	flags.BoolVar(&up.noPrefix, "no-log-prefix", false, "Don't print prefix in logs.")
	flags.BoolVar(&create.forceRecreate, "force-recreate", false, "Recreate containers even if their configuration and image haven't changed.")
	flags.BoolVar(&create.noRecreate, "no-recreate", false, "If containers already exist, don't recreate them. Incompatible with --force-recreate.")
	flags.BoolVar(&up.noStart, "no-start", false, "Don't start the services after creating them.")
	flags.BoolVar(&up.cascadeStop, "abort-on-container-exit", false, "Stops all containers if any container was stopped. Incompatible with -d")
	flags.StringVar(&up.exitCodeFrom, "exit-code-from", "", "Return the exit code of the selected service container. Implies --abort-on-container-exit")
	flags.IntVarP(&create.timeout, "timeout", "t", 10, "Use this timeout in seconds for container shutdown when attached or when containers are already running.")
	flags.BoolVar(&up.noDeps, "no-deps", false, "Don't start linked services.")
	flags.BoolVar(&create.recreateDeps, "always-recreate-deps", false, "Recreate dependent containers. Incompatible with --no-recreate.")
	flags.BoolVarP(&create.noInherit, "renew-anon-volumes", "V", false, "Recreate anonymous volumes instead of retrieving data from the previous containers.")
	flags.BoolVar(&up.attachDependencies, "attach-dependencies", false, "Attach to dependent containers.")
	flags.BoolVar(&create.quietPull, "quiet-pull", false, "Pull without printing progress information.")
	flags.StringArrayVar(&up.attach, "attach", []string{}, "Attach to service output.")
	flags.BoolVar(&up.wait, "wait", false, "Wait for services to be running|healthy. Implies detached mode.")

	return upCmd
}

func validateFlags(up *upOptions, create *createOptions) error {
	if up.exitCodeFrom != "" {
		up.cascadeStop = true
	}
	if up.wait {
		if up.attachDependencies || up.cascadeStop || len(up.attach) > 0 {
			return fmt.Errorf("--wait cannot be combined with --abort-on-container-exit, --attach or --attach-dependencies")
		}
		up.Detach = true
	}
	if create.Build && create.noBuild {
		return fmt.Errorf("--build and --no-build are incompatible")
	}
	if up.Detach && (up.attachDependencies || up.cascadeStop || len(up.attach) > 0) {
		return fmt.Errorf("--detach cannot be combined with --abort-on-container-exit, --attach or --attach-dependencies")
	}
	if create.forceRecreate && create.noRecreate {
		return fmt.Errorf("--force-recreate and --no-recreate are incompatible")
	}
	if create.recreateDeps && create.noRecreate {
		return fmt.Errorf("--always-recreate-deps and --no-recreate are incompatible")
	}
	return nil
}

func runUp(ctx context.Context, backend api.Service, createOptions createOptions, upOptions upOptions, project *types.Project, services []string) error {
	if len(project.Services) == 0 {
		return fmt.Errorf("no service selected")
	}

	createOptions.Apply(project)