diff --git a/bin/ec/main_test.go b/bin/ec/main_test.go index 73fc94e..7ed2286 100644 --- a/bin/ec/main_test.go +++ b/bin/ec/main_test.go @@ -212,7 +212,7 @@ var _ = Describe("main", func() { fmt.Println("Removing node@6.4.0") - fmt.Println("Install tmp version") + fmt.Println("Install 5.1.0 version") Execute("go", "run", path, "node@5.1.0") Execute("go", "run", path, "rm", "node@6.4.0") @@ -288,6 +288,14 @@ var _ = Describe("main", func() { Expect(result).To(Equal(true)) }) + + It("should install yarn", func() { + yarnBin := filepath.Join(variables.Path("node", "5.1.0"), "bin/yarn") + + bytes, _ := Command(yarnBin, "--help").CombinedOutput() + + Expect(string(bytes)).To(ContainSubstring("Usage: yarn [command] [flags]")) + }) }) Describe("elm", func() { diff --git a/plugins/nodejs/nodejs.go b/plugins/nodejs/nodejs.go index e205283..2454622 100644 --- a/plugins/nodejs/nodejs.go +++ b/plugins/nodejs/nodejs.go @@ -45,14 +45,16 @@ func (node Node) Install() error { return nil } -func (node Node) PostInstall() error { - path := variables.Path("node", node.Version) - etc := filepath.Join(path, "etc") - npmrc := filepath.Join(etc, "npmrc") +func (node Node) PostInstall() (err error) { + err = node.setNpm() + if err != nil { + return err + } - // Remove needless warnings from npm output - io.CreateDir(etc) - io.WriteFile(npmrc, "scripts-prepend-node-path=false") + ok, err := node.Yarn() + if err != nil && ok == false { + return err + } return nil } @@ -125,3 +127,22 @@ func (node Node) ListRemote() ([]string, error) { return result, nil } + +// Removes needless warnings from npm output +func (node Node) setNpm() (err error) { + path := variables.Path("node", node.Version) + etc := filepath.Join(path, "etc") + npmrc := filepath.Join(etc, "npmrc") + + _, err = io.CreateDir(etc) + if err != nil { + return + } + + err = io.WriteFile(npmrc, "scripts-prepend-node-path=false") + if err != nil { + return + } + + return nil +} diff --git a/plugins/nodejs/yarn.go b/plugins/nodejs/yarn.go new file mode 100644 index 0000000..47dd9fa --- /dev/null +++ b/plugins/nodejs/yarn.go @@ -0,0 +1,73 @@ +package nodejs + +import ( + "errors" + "os" + "path/filepath" + + "github.com/blang/semver" + "github.com/cavaliercoder/grab" + "github.com/markelog/archive" + "github.com/markelog/cprf" + + "github.com/markelog/eclectica/io" + "github.com/markelog/eclectica/variables" +) + +var ( + minimalForYarn, _ = semver.Make("4.0.0") + yarnUrl = "https://yarnpkg.com/latest.tar.gz" +) + +func (node Node) download(path string) (err error) { + _, err = grab.Get(path, yarnUrl) + if err != nil { + return + } + + return +} + +func (node Node) Yarn() (ok bool, err error) { + version, _ := semver.Make(node.Version) + ok = false + + path := variables.Path("node", node.Version) + modules := filepath.Join(path, "lib/node_modules") + dist := filepath.Join(modules, "yarn-archive") + temp := filepath.Join(modules, "yarn-temp") + from := filepath.Join(temp, "dist/") + dest := filepath.Join(modules, "yarn") + + if version.LT(minimalForYarn) { + return true, errors.New("\"" + node.Version + "\" version is not supported by yarn") + } + + err = node.download(dist) + if err != nil { + return + } + + err = archive.Extract(dist, temp) + if err != nil { + return + } + + err = cprf.Copy(from+"/", dest) + if err != nil { + return + } + + os.RemoveAll(dist) + os.RemoveAll(temp) + + current := filepath.Join(modules, "yarn/bin/yarn.js") + base := filepath.Join(path, "bin/yarn") + + err = io.Symlink(base, current) + if err != nil { + return + } + + return true, nil +} diff --git a/plugins/nodejs/yarn_test.go b/plugins/nodejs/yarn_test.go new file mode 100644 index 0000000..18f5128 --- /dev/null +++ b/plugins/nodejs/yarn_test.go @@ -0,0 +1,93 @@ +package nodejs_test + +import ( + "os" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + + "github.com/bouk/monkey" + "github.com/cavaliercoder/grab" + "github.com/markelog/archive" + "github.com/markelog/cprf" + + "github.com/markelog/eclectica/io" + . "github.com/markelog/eclectica/plugins/nodejs" +) + +var _ = Describe("yarn", func() { + var ( + grabGet bool + archiveExtract bool + cprfCopy bool + osRemovaAll bool + ioSymlink bool + ) + + BeforeEach(func() { + grabGet = false + archiveExtract = false + cprfCopy = false + osRemovaAll = false + ioSymlink = false + + monkey.Patch(grab.Get, func(path, url string) (*grab.Response, error) { + grabGet = true + return nil, nil + }) + + monkey.Patch(archive.Extract, func(from, to string) error { + archiveExtract = true + return nil + }) + + monkey.Patch(cprf.Copy, func(from, to string) error { + cprfCopy = true + return nil + }) + + monkey.Patch(os.RemoveAll, func(path string) error { + osRemovaAll = true + return nil + }) + + monkey.Patch(io.Symlink, func(from, to string) error { + ioSymlink = true + return nil + }) + }) + + AfterEach(func() { + monkey.Unpatch(grab.Get) + monkey.Unpatch(archive.Extract) + monkey.Unpatch(cprf.Copy) + monkey.Unpatch(os.RemoveAll) + monkey.Unpatch(io.Symlink) + }) + + It("should not try to install yarn for unsupported node version", func() { + working, err := (&Node{Version: "0.10.0"}).Yarn() + + Expect(grabGet).To(Equal(false)) + Expect(archiveExtract).To(Equal(false)) + Expect(cprfCopy).To(Equal(false)) + Expect(osRemovaAll).To(Equal(false)) + Expect(ioSymlink).To(Equal(false)) + + Expect(working).To(Equal(true)) + Expect(err.Error()).To(Equal("\"0.10.0\" version is not supported by yarn")) + }) + + It("installs yarn", func() { + working, err := (&Node{Version: "6.10.0"}).Yarn() + + Expect(grabGet).To(Equal(true)) + Expect(archiveExtract).To(Equal(true)) + Expect(cprfCopy).To(Equal(true)) + Expect(osRemovaAll).To(Equal(true)) + Expect(ioSymlink).To(Equal(true)) + + Expect(working).To(Equal(true)) + Expect(err).To(BeNil()) + }) +})