Skip to content

Commit d5e6d82

Browse files
committed
Ⓜ️ Add init subcommand
1 parent 98753aa commit d5e6d82

File tree

2 files changed

+151
-0
lines changed

2 files changed

+151
-0
lines changed

cmd/cmd_init.go

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/*
2+
Copyright © 2024 NAME HERE <EMAIL ADDRESS>
3+
*/
4+
package cmd
5+
6+
import (
7+
"os"
8+
9+
"github.com/spf13/cobra"
10+
)
11+
12+
// initCmd represents the init command
13+
var initCmd = &cobra.Command{
14+
Use: "init",
15+
Short: "initialize a virtual environment in the current directory",
16+
Long: `Initialize a virtual environment in the current directory in .venv directory.
17+
If requirements.txt or similar file is present, it will automatically
18+
install the dependenciesfrom it.`,
19+
RunE: func(cmd *cobra.Command, args []string) error {
20+
cmd.SilenceUsage = true
21+
22+
deleteOldEnvFlag, err := cmd.Flags().GetBool("new-environment")
23+
if err != nil {
24+
return err
25+
}
26+
27+
requirementsFileFlag, err := cmd.Flags().GetString("requirements-file")
28+
if err != nil {
29+
return err
30+
}
31+
32+
pythonFlag, err := cmd.Flags().GetString("python")
33+
if err != nil {
34+
return err
35+
}
36+
37+
printProgress("Gathering information about script and environment...")
38+
script, err := NewInitCmd(pythonFlag, requirementsFileFlag)
39+
if err != nil {
40+
return err
41+
}
42+
43+
printProgress("Ensuring virtual environment...")
44+
err = script.EnsureEnv(deleteOldEnvFlag)
45+
if err != nil {
46+
return err
47+
}
48+
49+
printProgress("Done!")
50+
if !flagDebug {
51+
// Clear all progress messages
52+
printProgress("")
53+
}
54+
55+
// Flush the buffers to preserve the output order and avoid interference
56+
// between the script output and the invenv output
57+
os.Stderr.Sync()
58+
os.Stdout.Sync()
59+
return nil
60+
},
61+
}
62+
63+
func init() {
64+
rootCmd.AddCommand(initCmd)
65+
initCmd.Flags().StringP("requirements-file", "r", "",
66+
`use specified requirements file. If not provided, it
67+
will try to guess the requirements file name:
68+
requirements_<script_name>.txt, <script_name>_requirements.txt or
69+
requirements.txt`)
70+
initCmd.Flags().BoolP("new-environment", "n", false, "create a new virtual environment even if it already exists")
71+
initCmd.Flags().StringP("python", "p", "", "use specified Python interpreter")
72+
}

cmd/script.go

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,3 +240,82 @@ func NewScript(scriptName string, interpreterOverride string, requirementsOverri
240240
}
241241
return script, nil
242242
}
243+
244+
// NewInitCmd creates a new Script instance
245+
func NewInitCmd(interpreterOverride string, requirementsOverride string) (*Script, error) {
246+
cwd, err := os.Getwd()
247+
if err != nil {
248+
return nil, err
249+
}
250+
251+
// Try to find requirements.txt file for the script
252+
requirementsFile, err := getRequirementsFileForScript(path.Join(cwd, ".placeholder"), requirementsOverride)
253+
if err != nil {
254+
return nil, err
255+
}
256+
257+
if flagDebug {
258+
if requirementsFile == "" {
259+
loggerErr.Println("No requirements file found")
260+
} else {
261+
loggerErr.Println("Found requirements file: ", requirementsFile)
262+
}
263+
}
264+
265+
requirementsHash := ""
266+
if requirementsFile != "" {
267+
requirementsHash, err = getFileHash(requirementsFile)
268+
if err != nil {
269+
return nil, err
270+
}
271+
}
272+
273+
if flagDebug {
274+
loggerErr.Printf("Requirements file hash: %s\n", requirementsHash)
275+
}
276+
277+
var pythonInterpreter string
278+
if interpreterOverride == "" {
279+
pythonInterpreter = "python"
280+
} else {
281+
pythonInterpreter = interpreterOverride
282+
}
283+
284+
// Check if the python interpreter exists in path
285+
_, err = exec.LookPath(pythonInterpreter)
286+
if err != nil && interpreterOverride != "" {
287+
return nil, fmt.Errorf("failed to find python interpreter %s: %s", pythonInterpreter, err)
288+
} else if err != nil {
289+
if flagDebug {
290+
loggerErr.Printf("Failed to find python interpreter %s: %s, assuming `python`...\n", pythonInterpreter, err)
291+
}
292+
pythonInterpreter = "python"
293+
_, err = exec.LookPath(pythonInterpreter)
294+
if err != nil {
295+
return nil, fmt.Errorf("failed to find python interpreter %s: %s", pythonInterpreter, err)
296+
}
297+
}
298+
299+
pythonVersion, err := getPythonVersion(pythonInterpreter)
300+
if err != nil {
301+
return nil, err
302+
}
303+
304+
if flagDebug {
305+
loggerErr.Printf("Using python interpreter: %s\n", pythonVersion)
306+
}
307+
308+
envDir := ".venv"
309+
310+
if flagDebug {
311+
loggerErr.Println("Using virtual environment: ", envDir)
312+
}
313+
314+
script := &Script{
315+
AbsolutePath: cwd,
316+
EnvDir: envDir,
317+
PythonInterpreter: pythonInterpreter,
318+
RequirementsPath: requirementsFile,
319+
}
320+
return script, nil
321+
}

0 commit comments

Comments
 (0)