diff --git a/Makefile b/Makefile index 9e7dea9..c3ec9ee 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ GIT_COMMIT=$(shell git describe --always) -.PHONY: all build clean test +.PHONY: all build clean test install-venv update-venv default: build @@ -13,4 +13,16 @@ clean: rm ./gactar test: - go test ./... \ No newline at end of file + go test ./... + +#### +# The following are convenience targets for managing the virtual environment + +# Create the gactar venv (with dev packages) +install-venv: + ./gactar env setup --dev + +# Update the python version in the venv and +# any versions of packages from the requirements files +update-venv: + ./gactar env update --all --dev diff --git a/cmd/env.go b/cmd/env.go index 0ae7c7e..428b627 100644 --- a/cmd/env.go +++ b/cmd/env.go @@ -30,6 +30,12 @@ var ( errPathExists = errors.New("path already exists") flagSetupDev = false + + flagUpdateAll = false + + flagUpdatePython = false + flagUpdatePythonPackages = false + flagUpdateDev = false ) var envCmd = &cobra.Command{ @@ -45,7 +51,7 @@ var setupCmd = &cobra.Command{ Use: "setup", Short: "Setup an environment", Run: func(cmd *cobra.Command, args []string) { - envPath, err := expandPathFlag(cmd.Flags(), "path") + envPath, err := getVirtualEnvironmentPath(cmd.Flags()) if err != nil { chalk.PrintErr(err) return @@ -59,6 +65,31 @@ var setupCmd = &cobra.Command{ }, } +var updateCmd = &cobra.Command{ + Use: "update", + Short: "Update an environment", + PreRun: func(cmd *cobra.Command, args []string) { + devSet, _ := cmd.Flags().GetBool("dev") + allSet, _ := cmd.Flags().GetBool("all") + if devSet && !allSet { + cmd.MarkFlagRequired("pip") + } + }, + Run: func(cmd *cobra.Command, args []string) { + envPath, err := getVirtualEnvironmentPath(cmd.Flags()) + if err != nil { + chalk.PrintErr(err) + return + } + + err = runUpdate(envPath) + if err != nil { + chalk.PrintErr(err) + return + } + }, +} + type errCCLSystem struct { OSName string } @@ -68,11 +99,17 @@ func (e errCCLSystem) Error() string { } func init() { - setupCmd.Flags().StringP("path", "p", "./env", "directory for env files (it will be created if it does not exist)") setupCmd.Flags().BoolVar(&flagSetupDev, "dev", false, "install dev packages") envCmd.AddCommand(setupCmd) + updateCmd.Flags().BoolVar(&flagUpdateAll, "all", false, "update all tools & packages") + updateCmd.Flags().BoolVar(&flagUpdatePython, "python", false, "update python version") + updateCmd.Flags().BoolVar(&flagUpdatePythonPackages, "pip", false, "update python packages") + updateCmd.Flags().BoolVar(&flagUpdateDev, "dev", false, "update dev packages") + + envCmd.AddCommand(updateCmd) + rootCmd.AddCommand(envCmd) } @@ -244,3 +281,67 @@ func downloadGitHubRelease(name, repo, version, archiveFile, target string) (err return } + +func runUpdate(envPath string) (err error) { + fmt.Println("gactar Environment Update\n---") + fmt.Printf("Updating environment: %q\n", envPath) + + if flagUpdateAll || flagUpdatePython { + err = updatePython(envPath) + if err != nil { + return + } + } + + if flagUpdateAll || flagUpdatePythonPackages { + err = updatePipPackages(envPath) + if err != nil { + return + } + } + + return +} + +func updatePython(envPath string) (err error) { + fmt.Println() + fmt.Println("Updating Python\n---") + + path, err := python.FindPython3(true) + if err != nil { + return + } + + output, err := executil.ExecCommand(path, "-m", "venv", "--upgrade", envPath) + if err != nil { + return + } + + fmt.Print(output) + + return +} + +func updatePipPackages(envPath string) (err error) { + fmt.Println() + fmt.Println("Updating Python pip packages\n---") + + err = cli.SetupPaths(envPath) + if err != nil { + return + } + + file := "install/requirements.txt" + if flagUpdateDev { + file = "install/requirements-dev.txt" + } + + output, err := executil.ExecCommand("pip", "install", "-U", "-r", file) + if err != nil { + return + } + + fmt.Print(output) + + return +} diff --git a/cmd/root.go b/cmd/root.go index c2a190e..8c2d7c9 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -253,21 +253,31 @@ func createTempDirFromFlag(flags *pflag.FlagSet) (path string, err error) { return } -// setupVirtualEnvironment will check that the environment exists and set our paths. -func setupVirtualEnvironment(flags *pflag.FlagSet) (path string, err error) { - envPath, err := expandPathFlag(flags, "env") +// getVirtualEnvironmentPath gets the environment path from the flags and checks if it exists. +func getVirtualEnvironmentPath(flags *pflag.FlagSet) (envPath string, err error) { + envPath, err = expandPathFlag(flags, "env") if err != nil { - return + return "", err } if !filesystem.DirExists(envPath) { err = &errVirtualEnvDoesNotExist{path: envPath} - return + return "", err } fmt.Print(chalk.Header("Using virtual environment: ")) fmt.Printf("%q\n", envPath) + return +} + +// setupVirtualEnvironment will check that the environment path exists and set our PATH with it. +func setupVirtualEnvironment(flags *pflag.FlagSet) (path string, err error) { + envPath, err := getVirtualEnvironmentPath(flags) + if err != nil { + return + } + err = cli.SetupPaths(envPath) if err != nil { return