From e2a27a9a640e0125a3d81745fd033af513f47f5b Mon Sep 17 00:00:00 2001 From: Stanley Shyiko Date: Thu, 24 Mar 2016 22:31:13 -0700 Subject: [PATCH] 0.2.0 --- changelog.md | 7 ++++ command/alias.go | 29 +++++++++++++++++ command/current.go | 2 +- command/deactivate.go | 24 ++++++++++++++ command/use.go | 16 ++++++++-- command/which.go | 14 ++++++++ install.sh | 2 ++ jabba.go | 74 +++++++++++++++++++++++++++++++++++++++---- readme.md | 28 ++++++++++++++++ 9 files changed, 186 insertions(+), 10 deletions(-) create mode 100644 command/alias.go create mode 100644 command/deactivate.go create mode 100644 command/which.go diff --git a/changelog.md b/changelog.md index c6de857..75b2c16 100644 --- a/changelog.md +++ b/changelog.md @@ -1,3 +1,10 @@ # Changelog All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). + +## [0.2.0](https://github.com/shyiko/mysql-binlog-connector-java/compare/0.1.0...0.2.0) - 2016-03-24 + +### Added +* `alias default`/`unalias default`, `which`, `deactivate` commands. + +## 0.1.0 - 2016-03-23 diff --git a/command/alias.go b/command/alias.go new file mode 100644 index 0000000..6ebec6d --- /dev/null +++ b/command/alias.go @@ -0,0 +1,29 @@ +package command + +import ( + "errors" + "io/ioutil" + "github.com/shyiko/jabba/cfg" + "path" + "os" +) + +func SetAlias(name string, ver string) (err error) { + if name != "default" { + return errors.New("At this point only 'default' alias is allowed") + } + if ver == "" { + err = os.Remove(path.Join(cfg.Dir(), name + ".alias")) + } else { + err = ioutil.WriteFile(path.Join(cfg.Dir(), name + ".alias"), []byte(ver), 0666) + } + return +} + +func GetAlias(name string) string { + b, err := ioutil.ReadFile(path.Join(cfg.Dir(), name + ".alias")) + if err != nil { + return "" + } + return string(b) +} diff --git a/command/current.go b/command/current.go index 129fab8..86330a6 100644 --- a/command/current.go +++ b/command/current.go @@ -13,7 +13,7 @@ func Current() string { javaPath, err := lookPath("java") if err == nil { prefix := path.Join(cfg.Dir(), "jdk") + "/" - if (strings.HasPrefix(javaPath, prefix)) { + if strings.HasPrefix(javaPath, prefix) { index := strings.Index(javaPath[len(prefix):], "/") if index != -1 { return javaPath[len(prefix):len(prefix) + index] diff --git a/command/deactivate.go b/command/deactivate.go new file mode 100644 index 0000000..371af49 --- /dev/null +++ b/command/deactivate.go @@ -0,0 +1,24 @@ +package command + +import ( + "os" + "github.com/shyiko/jabba/cfg" + "path" + "regexp" +) + +func Deactivate() ([]string, error) { + pth, _ := os.LookupEnv("PATH") + rgxp := regexp.MustCompile(regexp.QuoteMeta(path.Join(cfg.Dir(), "jdk")) + "[^:]+[:]") + // strip references to ~/.jabba/jdk/*, otherwise leave unchanged + pth = rgxp.ReplaceAllString(pth, "") + javaHome, overrideWasSet := os.LookupEnv("JAVA_HOME_BEFORE_JABBA") + if !overrideWasSet { + javaHome, _ = os.LookupEnv("JAVA_HOME") + } + return []string{ + "export PATH=" + pth, + "export JAVA_HOME=" + javaHome, + "unset JAVA_HOME_BEFORE_JABBA", + }, nil +} diff --git a/command/use.go b/command/use.go index 8c6262d..d53b485 100644 --- a/command/use.go +++ b/command/use.go @@ -9,19 +9,29 @@ import ( ) func Use(ver string) ([]string, error) { + aliasValue := GetAlias(ver) + if aliasValue != "" { + ver = aliasValue + } resolved, err := resolveLocal(ver) if err != nil { return nil, err } + pth, _ := os.LookupEnv("PATH") rgxp := regexp.MustCompile(regexp.QuoteMeta(path.Join(cfg.Dir(), "jdk")) + "[^:]+[:]") - p, _ := os.LookupEnv("PATH") - p = rgxp.ReplaceAllString(p, "") + // strip references to ~/.jabba/jdk/*, otherwise leave unchanged + pth = rgxp.ReplaceAllString(pth, "") javaHome := path.Join(cfg.Dir(), "jdk", resolved) if runtime.GOOS == "darwin" { javaHome = path.Join(javaHome, "Contents", "Home") } + systemJavaHome, overrideWasSet := os.LookupEnv("JAVA_HOME_BEFORE_JABBA") + if !overrideWasSet { + systemJavaHome, _ = os.LookupEnv("JAVA_HOME") + } return []string{ - "export PATH=" + path.Join(javaHome, "bin") + ":" + p, + "export PATH=" + path.Join(javaHome, "bin") + ":" + pth, "export JAVA_HOME=" + javaHome, + "export JAVA_HOME_BEFORE_JABBA=" + systemJavaHome, }, nil } diff --git a/command/which.go b/command/which.go new file mode 100644 index 0000000..85cf14c --- /dev/null +++ b/command/which.go @@ -0,0 +1,14 @@ +package command + +import ( + "path" + "github.com/shyiko/jabba/cfg" +) + +func Which(ver string) (string, error) { + resolved, err := resolveLocal(ver) + if err != nil { + return "", err + } + return path.Join(cfg.Dir(), "jdk", resolved), nil +} diff --git a/install.sh b/install.sh index 8ec6f69..a50b15d 100644 --- a/install.sh +++ b/install.sh @@ -41,6 +41,8 @@ jabba() { rm \${fd3} (exit \${exit_code}) } + +[ ! -z "\$(jabba alias default)" ] && jabba use default EOF SOURCE_JABBA="\n[ -s \"$JABBA_DIR/jabba.sh\" ] && source \"$JABBA_DIR/jabba.sh\"" diff --git a/jabba.go b/jabba.go index 7ff1ec2..93cc34d 100644 --- a/jabba.go +++ b/jabba.go @@ -34,7 +34,7 @@ func main() { Use: "install [version to install]", Short: "Download and install JDK", RunE: func(cmd *cobra.Command, args []string) error { - if (len(args) == 0) { + if len(args) == 0 { return pflag.ErrHelp } ver, err := command.Install(args[0]) @@ -51,7 +51,7 @@ func main() { Use: "uninstall [version to uninstall]", Short: "Uninstall JDK", RunE: func(cmd *cobra.Command, args []string) error { - if (len(args) == 0) { + if len(args) == 0 { return pflag.ErrHelp } err := command.Uninstall(args[0]) @@ -66,7 +66,7 @@ func main() { Use: "use [version to use]", Short: "Modify PATH & JAVA_HOME to use specific JDK", RunE: func(cmd *cobra.Command, args []string) error { - if (len(args) == 0) { + if len(args) == 0 { return pflag.ErrHelp } return use(args[0]) @@ -78,7 +78,7 @@ func main() { Short: "Display currently 'use'ed version", Run: func(cmd *cobra.Command, args []string) { ver := command.Current() - if (ver != "") { + if ver != "" { println(ver) } }, @@ -117,6 +117,65 @@ func main() { return nil }, }, + &cobra.Command{ + Use: "deactivate", + Short: "Undo effects of `jabba` on current shell", + RunE: func(cmd *cobra.Command, args []string) error { + out, err := command.Deactivate() + if err != nil { + log.Fatal(err) + } + printForShellToEval(out) + return nil + }, + }, + &cobra.Command{ + Use: "alias [name] [version]", + Short: "Resolve or update an alias", + RunE: func(cmd *cobra.Command, args []string) error { + if len(args) == 0 { + return pflag.ErrHelp + } + if len(args) == 1 { + if value := command.GetAlias(args[0]); value != "" { + fmt.Println(value) + } + } else + if err := command.SetAlias(args[0], args[1]); err != nil { + log.Fatal(err) + } + return nil + }, + Example: " jabba alias default 1.8\n" + + " jabba alias default # show value bound to an alias", + }, + &cobra.Command{ + Use: "unalias [name]", + Short: "Delete an alias", + RunE: func(cmd *cobra.Command, args []string) error { + if len(args) == 0 { + return pflag.ErrHelp + } + if err := command.SetAlias(args[0], ""); err != nil { + log.Fatal(err) + } + return nil + }, + }, + &cobra.Command{ + Use: "which [version]", + Short: "Display path to installed JDK", + RunE: func(cmd *cobra.Command, args []string) error { + if len(args) == 0 { + return pflag.ErrHelp + } + dir, _ := command.Which(args[0]) + if dir != "" { + fmt.Println(dir) + } + return nil + }, + }, ) rootCmd.Flags().Bool("version", false, "version of jabba") if err := rootCmd.Execute(); err != nil { @@ -129,10 +188,13 @@ func use(ver string) error { if err != nil { log.Fatal(err) } - // writing "export ..." to 3rd fd for shell to eval + printForShellToEval(out) + return nil +} + +func printForShellToEval(out []string) { fd3 := os.NewFile(3, "fd3") for _, line := range out { fmt.Fprintln(fd3, line) } - return nil } diff --git a/readme.md b/readme.md index e188506..eab0bad 100644 --- a/readme.md +++ b/readme.md @@ -7,8 +7,26 @@ in Go ([gvm](https://github.com/moovweb/gvm)) or Ruby ([rvm](https://rvm.io)). Tested at this point **very** lightly on Mac OS X and Linux. Windows support is coming in [#1](https://github.com/shyiko/jabba/issues/1). +It's written in [Go](https://golang.org/) to make maintenance easier (significantly shorter, easier to understand and less prone to errors +compared to pure shell implementation). Plus it enables us to support Windows natively (no Cygwin) without rewriting +the whole thing in PowerShell or whatever. + +The goal is to provide unified pain-free experience of installing (and switching between different versions of) JDK. + +How does it compare to "apt-get install" (and alike)? +Single command (`jabba install `) works regardless of the OS (so you don't need to remember different ways to +install JDK on Mac OS X, Arch and two versions of Debian). Package name no longer matters, as well as, whether LTS is over +or not. +And you can install ANY version, not just the latest stable one. Wanna try upcoming 1.9.0 release? No need to wait - +`jabba install 1.9.0-110`. How about specific build of 1.8? No problem - `jabba install 1.8.73`. + +> `jabba` has single responsibility - managing different versions of JDK. Maven/Gradle/SBT/... are out of scope (for those use +[mvnw](https://github.com/shyiko/mvnw)/[gradlew](https://docs.gradle.org/current/userguide/gradle_wrapper.html)/[sbt-launcher](http://www.scala-sbt.org/0.13/docs/Manual-Installation.html)/...). + ## Installation +> (you can use same command to upgrade) + ```sh curl -sL https://github.com/shyiko/jabba/raw/master/install.sh | bash && . ~/.jabba/jabba.sh ``` @@ -30,6 +48,9 @@ jabba use 1.6.65 # list available jdk's jabba ls-remote + +# set default java version on shell (available since 0.2.0) +jabba alias default 1.6.65 ``` For more information see `jabba --help`. @@ -52,6 +73,13 @@ make test # or "test-coverage" if you want to get a coverage breakdown make build # or "build-release" (latter is cross-compiling jabba to different OSs/ARCHs) ``` +## FAQ + +Q: What if I already have `java` installed? + +A: `jabba` feels perfectly fine in the environment where `java` has already been installed using some other means. You + can continue using system JDK and switch to `jabba`-provided one only when needed (`jabba use 1.6.65`). + ## License [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0)