// run the import command func runImport(cmd *Command, args ...string) { if len(args) == 0 { cmd.DisplayUsageAndExit() } // make sure that the manifest file exists if _, err := os.Stat(args[0]); err != nil { fmt.Println(utils.Fail( fmt.Sprintf("error: can't open %s manifest file", args[0]))) os.Exit(2) } options := func(i *Import) { i.Force = forceImport i.Verbose = verboseImport i.Prompt = promptImport i.Manifest = args[0] } i := NewImport(options) out, err := i.Run() if err != nil { fmt.Println(utils.Fail(fmt.Sprintf("error: %v", err))) os.Exit(2) } fmt.Printf("%s\n", utils.Ok(out)) os.Exit(0) }
func copySource(ver string) error { var out []byte fmt.Fprint(Output, "Copying source... ") destination := filepath.Join(CacheDirectory(), ver) os.RemoveAll(destination) curr, err := os.Getwd() if err != nil { return err } defer func() { exec.Command("git", "checkout", "master").Run() os.Chdir(curr) }() os.Chdir(TARGET) if ver != "go" && ver != "tip" { out, err := exec.Command("git", "checkout", ver).CombinedOutput() log.Println(string(out), err) if err != nil { fmt.Fprintln(Output, utils.Fail("✖")) return fmt.Errorf("%s", out) } } out, err = exec.Command("cp", "-R", "../git", destination).CombinedOutput() if err != nil { fmt.Fprintln(Output, utils.Fail("✖")) return err } fmt.Fprintln(Output, utils.Ok("✔")) logOutput(out) return nil }
// export the given environment using a VenGO.manifest file func (e *Export) envExport() (string, error) { fmt.Print("Loading environment... ") environment, err := e.LoadEnvironment() if err != nil { fmt.Println(utils.Fail("✖")) return "", err } fmt.Println(utils.Ok("✔")) fmt.Print("Generating manifest... ") environManifest, err := environment.Manifest() if err != nil { fmt.Println(utils.Fail("✖")) return "", err } manifest, err := environManifest.Generate() if err != nil { fmt.Println(utils.Fail("✖")) return "", err } fmt.Println(utils.Ok("✔")) if e.Prettify { buffer := new(bytes.Buffer) json.Indent(buffer, manifest, "", "\t") manifest = buffer.Bytes() } fmt.Printf("Writing manifest into %s... ", environment.VenGO_PATH) err = ioutil.WriteFile( filepath.Join(environment.VenGO_PATH, e.Name), manifest, 0644) if err != nil { fmt.Println(utils.Fail("✖")) } fmt.Println(utils.Ok("✔")) return "", err }
// run the migrate command func runMigrate(cmd *Command, args ...string) { if len(args) < 2 { cmd.DisplayUsageAndExit() } environName := args[0] goVersion := args[1] if os.Getenv("VENGO_ENV") == environName { fmt.Println( "error:", fmt.Sprintf("%s is currently in use as the active environment")) fmt.Printf("%s: execute 'deactivate' before call this command\n", suggest) os.Exit(2) } envPath := filepath.Join(os.Getenv("VENGO_HOME"), environName) if _, err := os.Stat(envPath); err != nil { fmt.Printf("%s is no a VenGO environment...\n", environName) fmt.Println(err) os.Exit(2) } fmt.Print("Checking installed Go versions...") if !env.LookupInstalledVersion(goVersion) { fmt.Println(utils.Fail("✖")) fmt.Println(fmt.Sprintf( "sorry vengo can't perform the operation because %s is %s", goVersion, utils.Fail("not installed"))) fmt.Printf("%s: run 'vengo install %s'\n", suggest, goVersion) os.Exit(2) } fmt.Println(utils.Ok("✔")) library := filepath.Join(envPath, "lib") installed, _ := os.Readlink(library) if installed == goVersion { fmt.Printf("%s in use Go version is already %s, skipping...", environName, installed) os.Exit(0) } fmt.Printf("unlinking previous %s Go version from %s...", installed, environName) if err := os.Remove(library); err != nil { fmt.Println(utils.Fail("✖")) fmt.Println(err) os.Exit(2) } fmt.Println(utils.Ok("✔")) fmt.Printf("Linking Go version %s...", goVersion) path := filepath.Join(cache.CacheDirectory(), goVersion) err := os.Symlink(path, filepath.Join(envPath, "lib")) if err != nil { fmt.Println(utils.Fail("✖")) fmt.Println(err) os.Exit(2) } fmt.Println(utils.Ok("✔")) fmt.Println("Done. You may want to run 'go build -a ./... in $GOPATH") os.Exit(0) }
// create a string representation of a package func (p *Package) String() string { check := utils.Ok("✔") if !p.Installed { check = utils.Fail("✖") } return fmt.Sprintf(` %s(%s) %s`, p.Name, p.Url, check) }
// fun the install command func runInstall(cmd *Command, args ...string) { if len(args) == 0 { cmd.DisplayUsageAndExit() } options := func(i *Install) { i.Verbose = verboseInstall i.Force = forceInstall i.NoCGO = nocgoInstall i.BootStrap = bootStrap if binaryInstall { i.Source = Binary } else { if sourceInstall { i.Source = Source } } i.Version = args[0] } i := NewInstall(options) data, err := i.Run() if err != nil { fmt.Println(utils.Fail(fmt.Sprintf("error: %v", err))) if !verboseInstall { fmt.Printf( "%s: run the install command with the '-v' option\n", suggest) } os.Exit(2) } fmt.Println(data) os.Exit(0) }
// implements the Runner interface creating the new virtual environment func (m *Mkenv) Run() (string, error) { fmt.Fprint(cache.Output, "Checking installed Go versions... ") if err := m.checkInstalled(); err != nil { fmt.Fprintln(cache.Output, utils.Fail("✖")) return "", err } fmt.Fprintln(cache.Output, utils.Ok("✔")) newEnv := env.NewEnvironment(m.Name, m.Prompt) if newEnv.Exists() && !m.Force { suggest := fmt.Sprintf( " %s: use --force to force reinstallation", utils.Ok("suggestion")) return "", fmt.Errorf("error: %s already exists\n%s", m.Name, suggest) } if err := newEnv.Generate(); err != nil { os.RemoveAll(filepath.Join(os.Getenv("VENGO_HOME"), m.Name)) return "", err } if err := newEnv.Install(m.Version); err != nil { os.RemoveAll(filepath.Join(os.Getenv("VENGO_HOME"), m.Name)) return "", err } return fmt.Sprintf( "%s", utils.Ok(fmt.Sprintf( "Go %s environment created using %s", m.Name, m.Version))), nil }
// run the mkenv command func runMkenv(cmd *Command, args ...string) { if len(args) == 0 { cmd.DisplayUsageAndExit() } options := func(m *Mkenv) { m.Force = forceMkenv if goversionMkenv != "" { m.Version = goversionMkenv } if promptMkenv != "" { m.Prompt = promptMkenv } m.Name = args[0] } mkenv := NewMkenv(options) data, err := mkenv.Run() if err != nil { if IsNotInstalledError(err) { fmt.Println(fmt.Sprintf( "sorry vengo can't perform the operation because %s is %s", mkenv.Version, utils.Fail("not installed"))) fmt.Printf("%s: run 'vengo install %s'\n", suggest, mkenv.Version) os.Exit(2) } fmt.Println(err) os.Exit(2) } fmt.Println(data) }
func checkSource(tag string) error { fmt.Fprintf(Output, "Checking %s... ", tag) out, err := exec.Command("hg", "pull", "-R", TARGET).CombinedOutput() if err != nil { fmt.Fprintln(Output, utils.Fail("✖")) return err } fmt.Fprintln(Output, utils.Ok("✔")) logOutput(out) return nil }
// determine if a Go version has been already compiled in the cache func AlreadyCompiled(ver string) bool { manifest := filepath.Join(CacheDirectory(), ver, ".vengo-manifest") if _, err := os.Stat(manifest); err != nil { return false } fmt.Fprint(Output, "Checking manifest integrity... ") if err := CheckManifestIntegrity(manifest); err != nil { fmt.Println(utils.Fail("✖")) log.Println(err) return false } fmt.Fprintln(Output, utils.Ok("✔")) return true }
// run the export command func runExport(cmd *Command, args ...string) { env := func(e *Export) {} if len(args) == 0 { activeEnv := os.Getenv("VENGO_ENV") if activeEnv == "" { cmd.DisplayUsageAndExit() } } else { env = func(e *Export) { e.Environment = filepath.Join(cache.VenGO_PATH, args[0]) } } options := func(e *Export) { e.Force = forceExport e.Prettify = prettifyExport e.Name = nameExport } e := NewExport(options, env) if e.Err() != nil { fmt.Println(utils.Fail(fmt.Sprint(e.Err()))) os.Exit(2) } if e.Exists() { if !e.Force { p := filepath.Join(e.Environment, e.Name) fmt.Println(utils.Fail(fmt.Sprintf("%s already exists", p))) fmt.Printf("%s: use the -f option to overwrite it\n", suggest) os.Exit(2) } } _, err := e.Run() if err != nil { fmt.Println(utils.Fail(fmt.Sprintf("error: %v", err))) os.Exit(2) } os.Exit(0) }
func pull() error { curr, err := os.Getwd() if err != nil { return err } defer os.Chdir(curr) os.Chdir(TARGET) fmt.Fprintf(Output, "Pulling Go sources from Github... ") out, err := exec.Command("git", "pull").CombinedOutput() if err != nil { fmt.Println(Output, utils.Fail("✖")) return err } fmt.Fprintln(Output, utils.Ok("✔")) logOutput(out) return nil }
// generates the output for the list command func (l *List) display(versions map[string][]string) (string, error) { output := []string{} if l.DisplayAs == Text { if l.ShowBoth || l.ShowInstalled { output = append(output, utils.Ok("Installed")) for _, v := range versions["installed"] { _, err := os.Stat( filepath.Join(cache.CacheDirectory(), v, ".vengo-manifest")) check := utils.Ok("✔") if err != nil { check = utils.Fail("✖") } output = append(output, fmt.Sprintf(" %s %s", v, check)) } } if l.ShowBoth || l.ShowNotInstalled { output = append(output, utils.Ok("Available for Installation")) output = append(output, versions["available"]...) } return strings.Join(output, "\n"), nil } if l.DisplayAs == Json { jsonData := &BriefJSON{[]string{}, []string{}} if l.ShowBoth || l.ShowInstalled { for _, v := range versions["installed"] { v := strings.TrimLeft(v, " ") jsonData.Installed = append(jsonData.Installed, v) } } if l.ShowBoth || l.ShowNotInstalled { for _, v := range versions["available"] { v := strings.TrimLeft(v, " ") jsonData.Available = append(jsonData.Available, v) } } data, err := json.Marshal(jsonData) return string(data), err } return "", fmt.Errorf("List.DisplayAs is not set to a valid value!") }
func cloneSource() error { // check if git command line is installed if _, err := exec.LookPath("git"); err != nil { log.Fatal("Git is not installed on this system.") } if GitExists() { return pull() } fmt.Fprint(Output, "Cloning Go sources from Github... ") out, err := exec.Command("git", "clone", REPO, TARGET).CombinedOutput() if err != nil { fmt.Println(Output, utils.Fail("✖")) return err } fmt.Fprintln(Output, utils.Ok("✔")) logOutput(out) return nil }
// install all the packages in the manifest using their respective revisions func (em *envManifest) installPackages(v bool) error { curr, _ := os.Getwd() environmentPath := filepath.Join(os.Getenv("VENGO_ENV"), "src") if err := os.MkdirAll(environmentPath, 0755); err != nil { return err } defer os.Chdir(curr) os.Chdir(environmentPath) for _, pkg := range em.Packages { if pkg.CodeRevision == "0000000000000000000000000000000000000000" { continue // we are in a test here } fmt.Printf("Cloning %s... ", pkg.Name) if err := pkg.Vcs.Clone(pkg.Url, pkg.CodeRevision, pkg.Root, v); err != nil { fmt.Println(utils.Fail("✖")) return err } fmt.Println(utils.Ok("✔")) } return nil }
// download and extract the given file checking the given sha1 signature func downloadAndExtract(ver, url, expected_sha1 string) error { resp, err := http.Get(url) if err != nil { return err } if resp.StatusCode != 200 { if resp.StatusCode == 400 { log.Fatalf("Version %s can't be found!\n", ver) } return fmt.Errorf("%s", resp.Status) } defer resp.Body.Close() fmt.Fprintf(Output, "downloading Go%s from %s ", ver, url) buf := new(bytes.Buffer) size, err := io.Copy(buf, resp.Body) if err != nil { fmt.Fprintln(Output, utils.Fail("✖")) return err } fmt.Fprintln(Output, utils.Ok("✔")) pkg_sha1 := fmt.Sprintf("%x", sha1.Sum(buf.Bytes())) if pkg_sha1 != expected_sha1 { return fmt.Errorf( "Error: SHA1 is different! expected %s got %s", expected_sha1, pkg_sha1, ) } fmt.Fprintf(Output, "%d bytes donwloaded... decompresssing... ", size) prefix := filepath.Join(CacheDirectory(), ver) extractTar(prefix, readGzipFile(buf)) buf.Reset() buf = nil fmt.Fprintln(Output, utils.Ok("✔")) return nil }
// generates the output for the lsenvs command func (e *EnvironmentsList) display( available, invalid []string) (string, error) { output := []string{} if e.DisplayAs == Text { output = append(output, utils.Ok("Virtual Go Environments")) for _, v := range available { output = append(output, fmt.Sprintf(" %s %s", v, utils.Ok("✔"))) } for _, v := range invalid { output = append( output, fmt.Sprintf(" %s %s", v, utils.Fail("✖"))) } return strings.Join(output, "\n"), nil } if e.DisplayAs == Json { data, err := json.Marshal(&EnvironmentsJSON{available, invalid}) return string(data), err } return "", fmt.Errorf("EnvironmentsList.DisplayAs is not a valid value!") }
Go versions. JSON output: One can pass the -j or --json option to display the output as a JSON structure with the following format: { "installed": [ "1.3rc2", "go1.2.2", "go1.3.2","go1.3.3", "go1.4", "go1.4rc1", "go1.4rc2" ] } `, utils.Ok("✔"), utils.Fail("✖")), Execute: runList, } var ( allList bool nonInstalledList bool asJsonList bool ) // initialize the command func init() { cmdList.Flag.BoolVarP(&allList, "all", "a", false, "") cmdList.Flag.BoolVarP(&nonInstalledList, "non-installed", "n", false, "") cmdList.Flag.BoolVarP(&asJsonList, "json", "j", false, "") cmdList.register()
Describe("String", func() { It("Will return back a right formatted string", func() { options := func(p *env.Package) { p.Name = "GoTest" p.Url = "http://golang.org" p.Installed = true p.Vcs = "hg" } p := env.NewPackage(options) Expect(p).ToNot(BeNil()) Expect(fmt.Sprint(p)).To(Equal(fmt.Sprintf(" %s(%s) %s", p.Name, p.Url, utils.Ok("✔")))) p.Installed = false Expect(fmt.Sprint(p)).To(Equal(fmt.Sprintf(" %s(%s) %s", p.Name, p.Url, utils.Fail("✖")))) }) }) Describe("Manifest", func() { BeforeEach(func() { os.Setenv("VENGO_HOME", "") if _, err := os.Stat(filepath.Join(cache.VenGO_PATH, "goTest")); err != nil { e := env.NewEnvironment("goTest", "(goTest)") Expect(e.Generate()).To(Succeed()) newLib, err := ioutil.TempDir("", "VenGO-") Expect(err).ToNot(HaveOccurred()) Expect(os.MkdirAll(filepath.Join(newLib, "go1.3.2"), 0755)).To(Succeed()) Expect(
Context("Using Text output", func() { It("Should return a title and a list of available/invalid environments", func() { l := commands.NewEnvironmentsList() Expect(l).ToNot(BeNil()) environments, err := l.Run() Expect(err).ToNot(HaveOccurred()) envsSplit := strings.Split(environments, "\n") Expect(envsSplit[0]).To(Equal(utils.Ok("Virtual Go Environments"))) Expect(envsSplit[1]).To(Equal(fmt.Sprintf(" MyEnv1 .VenGO %s", utils.Ok("✔")))) Expect(envsSplit[2]).To(Equal(fmt.Sprintf(" MyEnv2 .VenGO %s", utils.Ok("✔")))) Expect(envsSplit[3]).To(Equal(fmt.Sprintf(" MyEnv3 .VenGO %s", utils.Ok("✔")))) Expect(envsSplit[4]).To(Equal(fmt.Sprintf(" MyInvalidEnv1 %s", utils.Fail("✖")))) Expect(envsSplit[5]).To(Equal(fmt.Sprintf(" MyInvalidEnv2 %s", utils.Fail("✖")))) }) }) Context("using Json output", func() { It("Should return a Json structure with two lists with 3 and 2 elements", func() { jsonOutput := func(e *commands.EnvironmentsList) { e.DisplayAs = commands.Json } l := commands.NewEnvironmentsList(jsonOutput) Expect(l).ToNot(BeNil()) environments, err := l.Run() Expect(err).ToNot(HaveOccurred())
// compile a given version of go in the cache func Compile(ver string, verbose, nocgo bool, boostrap ...string) error { fmt.Fprint(Output, "Compiling... ") if verbose { fmt.Fprint(Output, "\n") } bs := "" if len(boostrap) > 0 { bs = boostrap[0] } currdir, _ := os.Getwd() prefixed := false err := os.Chdir(filepath.Join(CacheDirectory(), ver, "go", "src")) if err != nil { if !strings.HasPrefix(ver, "go") && ver != "tip" { ver = fmt.Sprintf("go%s", ver) } prefixed = true if err := os.Chdir( filepath.Join(CacheDirectory(), ver, "src")); err != nil { if !verbose { fmt.Fprintln(Output, utils.Fail("✖")) } return err } } defer func() { os.Chdir(currdir) }() cmd := "./make.bash" if runtime.GOOS == "windows" { cmd = "./make.bat" } if nocgo { os.Setenv("CGO_ENABLED", "0") } if bs != "" { os.Setenv("GOROOT_BOOTSTRAP", bs) } if err := utils.Exec(verbose, cmd); err != nil { return err } goBin := filepath.Join(CacheDirectory(), ver, "go", "bin", "go") if prefixed { goBin = filepath.Join(CacheDirectory(), ver, "bin", "go") } if _, err := os.Stat(goBin); err != nil { if !verbose { fmt.Fprintln(Output, utils.Fail("✖")) } fmt.Fprintln(Output, err) return fmt.Errorf("Go %s wasn't compiled properly! %v", ver, err) } if !verbose { fmt.Fprintln(Output, utils.Ok("✔")) } fmt.Fprintf(Output, "Generating manifest... ") if err := generateManifest(ver); err != nil { os.RemoveAll(filepath.Join(CacheDirectory(), ver)) fmt.Fprintln(Output, utils.Fail("✖")) return err } fmt.Fprintln(Output, utils.Ok("✔")) return nil }