diff --git a/.gitignore b/.gitignore index 3610bb6..c6be5db 100644 --- a/.gitignore +++ b/.gitignore @@ -31,3 +31,4 @@ coverage.out vendor dist coverage.txt +antibody diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..a8e553a --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "www/themes/hugo-apex-theme"] + path = www/themes/hugo-apex-theme + url = https://github.com/caarlos0/hugo-apex-theme diff --git a/.travis.yml b/.travis.yml index 705ea06..b2423c9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,22 +1,26 @@ language: go -go: 1.9 +go: '1.10' install: - make setup - npm install -g prettier script: make ci after_success: - bash <(curl -s https://codecov.io/bash) - - gem install fpm - - test -n "$TRAVIS_TAG" && curl -sL https://git.io/goreleaser | bash - make static deploy: - provider: pages - skip_cleanup: true - github_token: $GITHUB_TOKEN - repo: getantibody/getantibody.github.io - local_dir: ./dist/getantibody.github.io - target_branch: master - on: - master: true + - provider: pages + skip_cleanup: true + github_token: $GITHUB_TOKEN + local_dir: www/public + target_branch: master + repo: getantibody/getantibody.github.io + verbose: true + on: + branch: master + - provider: script + skip_cleanup: true + script: curl -sL https://git.io/goreleaser | bash -s -- --rm-dist + on: + tags: true notifications: email: false diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index 4e79b4c..314fcf7 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -8,19 +8,19 @@ In the interest of fostering an open and welcoming environment, we as contributo Examples of behavior that contributes to creating a positive environment include: -* Using welcoming and inclusive language -* Being respectful of differing viewpoints and experiences -* Gracefully accepting constructive criticism -* Focusing on what is best for the community -* Showing empathy towards other community members +- Using welcoming and inclusive language +- Being respectful of differing viewpoints and experiences +- Gracefully accepting constructive criticism +- Focusing on what is best for the community +- Showing empathy towards other community members Examples of unacceptable behavior by participants include: -* The use of sexualized language or imagery and unwelcome sexual attention or advances -* Trolling, insulting/derogatory comments, and personal or political attacks -* Public or private harassment -* Publishing others' private information, such as a physical or electronic address, without explicit permission -* Other conduct which could reasonably be considered inappropriate in a professional setting +- The use of sexualized language or imagery and unwelcome sexual attention or advances +- Trolling, insulting/derogatory comments, and personal or political attacks +- Public or private harassment +- Publishing others' private information, such as a physical or electronic address, without explicit permission +- Other conduct which could reasonably be considered inappropriate in a professional setting ## Our Responsibilities diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 08e9f22..6ee0cf6 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -9,9 +9,9 @@ conduct](/CODE_OF_CONDUCT.md). Prerequisites are: -* Build: - * `make` - * [Go 1.8+](http://golang.org/doc/install) +- Build: + - `make` + - [Go 1.8+](http://golang.org/doc/install) Clone `antibody` from source into `$GOPATH`: diff --git a/Gopkg.lock b/Gopkg.lock index 6a795f1..490d1a3 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -2,15 +2,18 @@ [[projects]] + branch = "master" name = "github.com/alecthomas/kingpin" packages = ["."] - revision = "947dcec5ba9c011838740e680966fd7087a71d0d" - version = "v2.2.6" + revision = "a39589180ebd6bbf43076e514b55f20a95d43086" [[projects]] branch = "master" name = "github.com/alecthomas/template" - packages = [".","parse"] + packages = [ + ".", + "parse" + ] revision = "a0175ee3bccc567396460bf5acd36800cb10c49c" [[projects]] @@ -22,8 +25,8 @@ [[projects]] name = "github.com/caarlos0/gohome" packages = ["."] - revision = "677b1a663675ddb3cea3a1e232f5f0c70d39c246" - version = "v2.0" + revision = "c08fdebe2a8b9b92637a423c66ac5d4a8f4e91e8" + version = "v2.1.0" [[projects]] name = "github.com/davecgh/go-spew" @@ -45,37 +48,43 @@ [[projects]] name = "github.com/stretchr/testify" - packages = ["assert"] - revision = "69483b4bd14f5845b5a1e55bca19e954e827f1d0" - version = "v1.1.4" + packages = [ + "assert", + "require" + ] + revision = "12b6f73e6084dad08a7c6e575284b177ecafbc71" + version = "v1.2.1" [[projects]] branch = "master" name = "golang.org/x/crypto" packages = ["ssh/terminal"] - revision = "94eea52f7b742c7cbe0b03b22f0c4c8631ece122" + revision = "1a580b3eff7814fc9b40602fd35256c63b50f491" [[projects]] branch = "master" name = "golang.org/x/net" packages = ["context"] - revision = "d866cfc389cec985d6fda2859936a575a55a3ab6" + revision = "2491c5de3490fced2f6cff376127c667efeed857" [[projects]] branch = "master" name = "golang.org/x/sync" packages = ["errgroup"] - revision = "fd80eb99c8f653c847d294a001bdf2a3a6f768f5" + revision = "1d60e4601c6fd243af51cc01ddf169918a5407ca" [[projects]] branch = "master" name = "golang.org/x/sys" - packages = ["unix","windows"] - revision = "571f7bbbe08da2a8955aed9d4db316e78630e9a3" + packages = [ + "unix", + "windows" + ] + revision = "7c87d13f8e835d2fb3a70a2912c811ed0c1d241b" [solve-meta] analyzer-name = "dep" analyzer-version = 1 - inputs-digest = "4b140a3aac0174bdf1b16a983238e58a8ee1c504cf8fc2eebb993bc14c454196" + inputs-digest = "5b4936a2f8bcec148b0561d14a01beadd347d2669c5eda2de7291ff404f86c52" solver-name = "gps-cdcl" solver-version = 1 diff --git a/Gopkg.toml b/Gopkg.toml index a6bee6a..0786e78 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -14,10 +14,6 @@ branch = "master" name = "golang.org/x/crypto" -[[constraint]] - branch = "master" - name = "golang.org/x/net" - [[constraint]] branch = "master" name = "golang.org/x/sync" diff --git a/Makefile b/Makefile index c272b7b..a37bce8 100644 --- a/Makefile +++ b/Makefile @@ -1,21 +1,25 @@ SOURCE_FILES?=./... TEST_PATTERN?=. TEST_OPTIONS?= +OS=$(shell uname -s) + +export PATH := ./bin:$(PATH) # Install all the build and lint dependencies setup: - go get -u github.com/alecthomas/gometalinter - go get -u github.com/golang/dep/cmd/dep - go get -u github.com/pierrre/gotestcover - go get -u golang.org/x/tools/cmd/cover - go get -u github.com/apex/static/cmd/static-docs - dep ensure - gometalinter --install + curl -sfL https://install.goreleaser.com/github.com/gohugoio/hugo.sh | sh + curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh +ifeq ($(OS), Darwin) + brew install dep +else + curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh +endif + dep ensure -vendor-only .PHONY: setup # Run all the tests test: - gotestcover $(TEST_OPTIONS) -covermode=atomic -coverprofile=coverage.txt $(SOURCE_FILES) -run $(TEST_PATTERN) -timeout=60s + go test $(TEST_OPTIONS) -failfast -race -coverpkg=./... -covermode=atomic -coverprofile=coverage.txt $(SOURCE_FILES) -run $(TEST_PATTERN) -timeout=2m .PHONY: test # Run all the tests and opens the coverage report @@ -25,12 +29,12 @@ cover: test # Run all the linters lint: - gometalinter --vendor ./... + ./bin/golangci-lint run --enable-all ./... find . -name '*.md' -not -wholename './vendor/*' | xargs prettier -l .PHONY: lint # Run all the tests and code checks -ci: lint test +ci: build test lint .PHONY: ci # Build a beta version @@ -44,28 +48,19 @@ fmt: find . -name '*.md' -not -wholename './vendor/*' | xargs prettier --write .PHONY: fmt -# Generates the static documentation -static-gen: - @rm -rf dist/getantibody.github.io/theme - @static-docs \ - --in docs \ - --out dist/getantibody.github.io \ - --title Antibody \ - --subtitle "The fastest shell plugin manager" \ - --google UA-68164063-1 -.PHONY: static-gen - -# Downloads and generates the static documentation +# Generate the static documentation static: - @rm -rf dist/getantibody.github.io - @mkdir -p dist - @git clone https://github.com/getantibody/getantibody.github.io.git dist/getantibody.github.io - @make static-gen + @hugo --enableGitInfo --source www .PHONY: static -# Opens the current docs on the default browser -static-open: - open dist/getantibody.github.io/index.html -.PHONY: static-open +serve: + @hugo server --enableGitInfo --watch --source www +.PHONY: serve + +favicon: + wget -O www/static/avatar.png https://avatars2.githubusercontent.com/u/16625397 + convert www/static/avatar.png -define icon:auto-resize=64,48,32,16 www/static/favicon.ico + convert www/static/avatar.png -resize x120 www/static/apple-touch-icon.png +.PHONY: favicon .DEFAULT_GOAL := build diff --git a/README.md b/README.md index c91ec70..034fad2 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@

Release Software License - Travis + Travis Codecov branch Go Report Card Go Doc @@ -21,23 +21,23 @@ performance. ## Documentation -Documentation can be found in the [docs folder](docs) and live +Documentation can be found in the [docs folder](www/content) and live at https://getantibody.github.io ## In the wild -* I did this mostly for myself, so, my [dotfiles](https://github.com/caarlos0/dotfiles); -* @mkwmms' [dotfiles](https://github.com/mkwmms/dotfiles); -* @oieduardorabelo's [dotfiles](https://github.com/oieduardorabelo/dotfiles); -* @nisaacson's [dotfiles](https://github.com/nisaacson/dotfiles); -* @pragmaticivan's [dotfiles](https://github.com/pragmaticivan/dotfiles); -* @wkentaro's [dotfiles](https://github.com/wkentaro/dotfiles); -* @marceldias' [dotfiles](https://github.com/marceldiass/dotfiles); -* @davidkna's [dotfiles](https://github.com/davidkna/dotfiles); -* @sobolevn's [dotfiles](https://github.com/sobolevn/dotfiles); -* and probably [many others](https://github.com/search?q=antibody&type=Code); +- I did this mostly for myself, so, my [dotfiles](https://github.com/caarlos0/dotfiles); +- @mkwmms' [dotfiles](https://github.com/mkwmms/dotfiles); +- @oieduardorabelo's [dotfiles](https://github.com/oieduardorabelo/dotfiles); +- @nisaacson's [dotfiles](https://github.com/nisaacson/dotfiles); +- @pragmaticivan's [dotfiles](https://github.com/pragmaticivan/dotfiles); +- @wkentaro's [dotfiles](https://github.com/wkentaro/dotfiles); +- @marceldias' [dotfiles](https://github.com/marceldiass/dotfiles); +- @davidkna's [dotfiles](https://github.com/davidkna/dotfiles); +- @sobolevn's [dotfiles](https://github.com/sobolevn/dotfiles); +- and probably [many others](https://github.com/search?q=antibody&type=Code); ## Thanks -* [@pragmaticivan](https://github.com/pragmaticivan), for the logo design; -* All the amazing [contributors](https://github.com/getantibody/antibody/graphs/contributors). +- [@pragmaticivan](https://github.com/pragmaticivan), for the logo design; +- All the amazing [contributors](https://github.com/getantibody/antibody/graphs/contributors). diff --git a/antibodylib/antibody.go b/antibodylib/antibody.go index 4fe292f..c45ff6c 100644 --- a/antibodylib/antibody.go +++ b/antibodylib/antibody.go @@ -51,7 +51,7 @@ func (a *Antibody) Bundle() (result string, err error) { } s, berr := bundle.New(a.Home, l).Get() lock.Lock() - shs = append(shs, indexedLine{index, s}) + shs = append(shs, indexedLine{idx: index, line: s}) lock.Unlock() return berr }) diff --git a/antibodylib/antibody_test.go b/antibodylib/antibody_test.go index ac856e1..dc9c19a 100644 --- a/antibodylib/antibody_test.go +++ b/antibodylib/antibody_test.go @@ -9,7 +9,7 @@ import ( "testing" "github.com/getantibody/antibody/antibodylib" - "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestAntibody(t *testing.T) { @@ -29,22 +29,23 @@ func TestAntibody(t *testing.T) { bytes.NewBufferString(strings.Join(bundles, "\n")), runtime.NumCPU(), ).Bundle() - assert.NoError(t, err) + require.NoError(t, err) files, err := ioutil.ReadDir(home) - assert.NoError(t, err) - assert.Len(t, files, 3) - assert.Contains(t, sh, `export PATH="/tmp:$PATH"`) - assert.Contains(t, sh, `export PATH="`+home+`/https-COLON--SLASH--SLASH-github.com-SLASH-caarlos0-SLASH-ports:$PATH"`) - assert.Contains(t, sh, `export PATH="`+home+`/https-COLON--SLASH--SLASH-github.com-SLASH-caarlos0-SLASH-jvm:$PATH"`) - assert.Contains(t, sh, `source `+home+`/https-COLON--SLASH--SLASH-github.com-SLASH-caarlos0-SLASH-zsh-open-pr/git-open-pr.plugin.zsh`) + require.NoError(t, err) + require.Len(t, files, 3) + require.Contains(t, sh, `export PATH="/tmp:$PATH"`) + require.Contains(t, sh, `export PATH="`+home+`/https-COLON--SLASH--SLASH-github.com-SLASH-caarlos0-SLASH-ports:$PATH"`) + require.Contains(t, sh, `export PATH="`+home+`/https-COLON--SLASH--SLASH-github.com-SLASH-caarlos0-SLASH-jvm:$PATH"`) + // nolint: lll + require.Contains(t, sh, `source `+home+`/https-COLON--SLASH--SLASH-github.com-SLASH-caarlos0-SLASH-zsh-open-pr/git-open-pr.plugin.zsh`) } func TestAntibodyError(t *testing.T) { home := home() bundles := bytes.NewBufferString("invalid-repo") sh, err := antibodylib.New(home, bundles, runtime.NumCPU()).Bundle() - assert.Error(t, err) - assert.Empty(t, sh) + require.Error(t, err) + require.Empty(t, sh) } func TestMultipleRepositories(t *testing.T) { @@ -65,6 +66,8 @@ func TestMultipleRepositories(t *testing.T) { "zsh-users/zsh-completions", "zsh-users/zsh-autosuggestions", "", + "robbyrussell/oh-my-zsh folder:plugins/asdf", + "robbyrussell/oh-my-zsh folder:plugins/autoenv", "# these should be at last!", "sindresorhus/pure", "zsh-users/zsh-syntax-highlighting", @@ -75,17 +78,57 @@ func TestMultipleRepositories(t *testing.T) { bytes.NewBufferString(strings.Join(bundles, "\n")), runtime.NumCPU(), ).Bundle() - assert.NoError(t, err) - assert.Len(t, strings.Split(sh, "\n"), 16) + require.NoError(t, err) + require.Len(t, strings.Split(sh, "\n"), 31) +} + +// BenchmarkDownload-8 1 2907868713 ns/op 480296 B/op 2996 allocs/op v1 +// BenchmarkDownload-8 1 2708120385 ns/op 475904 B/op 3052 allocs/op v2 +func BenchmarkDownload(b *testing.B) { + var bundles = strings.Join([]string{ + "robbyrussell/oh-my-zsh folder:plugins/aws", + "caarlos0/git-add-remote kind:path", + "caarlos0/jvm", + "caarlos0/ports kind:path", + "", + "# comment whatever", + "caarlos0/zsh-git-fetch-merge kind:path", + "robbyrussell/oh-my-zsh folder:plugins/battery", + "caarlos0/zsh-git-sync kind:path", + "caarlos0/zsh-mkc", + "caarlos0/zsh-open-pr kind:path", + "robbyrussell/oh-my-zsh folder:plugins/asdf", + "mafredri/zsh-async", + "rupa/z", + "Tarrasch/zsh-bd", + "", + "wbinglee/zsh-wakatime", + "zsh-users/zsh-completions", + "zsh-users/zsh-autosuggestions", + "robbyrussell/oh-my-zsh folder:plugins/autoenv", + "# these should be at last!", + "sindresorhus/pure", + "zsh-users/zsh-syntax-highlighting", + "zsh-users/zsh-history-substring-search", + }, "\n") + for i := 0; i < b.N; i++ { + home := home() + _, err := antibodylib.New( + home, + bytes.NewBufferString(bundles), + runtime.NumCPU(), + ).Bundle() + require.NoError(b, err) + } } func TestHome(t *testing.T) { - assert.Contains(t, antibodylib.Home(), "antibody") + require.Contains(t, antibodylib.Home(), "antibody") } func TestHomeFromEnvironmentVariable(t *testing.T) { - assert.NoError(t, os.Setenv("ANTIBODY_HOME", "/tmp")) - assert.Equal(t, "/tmp", antibodylib.Home()) + require.NoError(t, os.Setenv("ANTIBODY_HOME", "/tmp")) + require.Equal(t, "/tmp", antibodylib.Home()) } func home() string { diff --git a/antibodylib/sort.go b/antibodylib/sort.go index ed36989..a22dff9 100644 --- a/antibodylib/sort.go +++ b/antibodylib/sort.go @@ -30,6 +30,7 @@ func (slice indexedLines) Swap(i, j int) { // Sort all lines and join them in a string func (slice indexedLines) String() string { sort.Sort(slice) + // nolint: prealloc var lines []string for _, line := range slice { lines = append(lines, line.line) diff --git a/bundle/bundle.go b/bundle/bundle.go index f7d0fd4..dddb179 100644 --- a/bundle/bundle.go +++ b/bundle/bundle.go @@ -29,12 +29,12 @@ func New(home, line string) Bundle { kind := extract(line) proj := project.New(home, line) if kind == "path" { - return pathBundle{proj} + return pathBundle{Project: proj} } if kind == "dummy" { - return dummyBundle{proj} + return dummyBundle{Project: proj} } - return zshBundle{proj} + return zshBundle{Project: proj} } func extract(line string) string { diff --git a/bundle/bundle_test.go b/bundle/bundle_test.go index 7f7bf21..13d3bdf 100644 --- a/bundle/bundle_test.go +++ b/bundle/bundle_test.go @@ -6,7 +6,7 @@ import ( "testing" "github.com/getantibody/antibody/bundle" - "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestSuccessfullGitBundles(t *testing.T) { @@ -15,7 +15,7 @@ func TestSuccessfullGitBundles(t *testing.T) { }{ { "caarlos0/jvm", - "jvm.plugin.zsh", + "jvm.plugin.zsh\nfpath+=( ", }, { "caarlos0/jvm kind:path", @@ -36,10 +36,11 @@ func TestSuccessfullGitBundles(t *testing.T) { } for _, row := range table { t.Run(row.line, func(t *testing.T) { + t.Parallel() home := home() result, err := bundle.New(home, row.line).Get() - assert.Contains(t, result, row.result) - assert.NoError(t, err) + require.Contains(t, result, row.result) + require.NoError(t, err) }) } } @@ -47,41 +48,41 @@ func TestSuccessfullGitBundles(t *testing.T) { func TestZshInvalidGitBundle(t *testing.T) { home := home() _, err := bundle.New(home, "doesnt exist").Get() - assert.Error(t, err) + require.Error(t, err) } func TestZshLocalBundle(t *testing.T) { home := home() - assert.NoError(t, ioutil.WriteFile(home+"/a.sh", []byte("echo 9"), 0644)) + require.NoError(t, ioutil.WriteFile(home+"/a.sh", []byte("echo 9"), 0644)) result, err := bundle.New(home, home).Get() - assert.Contains(t, result, "a.sh") - assert.NoError(t, err) + require.Contains(t, result, "a.sh") + require.NoError(t, err) } func TestZshInvalidLocalBundle(t *testing.T) { home := home() _, err := bundle.New(home, "/asduhasd/asdasda").Get() - assert.Error(t, err) + require.Error(t, err) } func TestZshBundleWithNoShFiles(t *testing.T) { home := home() _, err := bundle.New(home, "getantibody/antibody").Get() - assert.NoError(t, err) + require.NoError(t, err) } func TestPathInvalidLocalBundle(t *testing.T) { home := home() _, err := bundle.New(home, "/asduhasd/asdasda kind:path").Get() - assert.Error(t, err) + require.Error(t, err) } func TestPathLocalBundle(t *testing.T) { home := home() - assert.NoError(t, ioutil.WriteFile(home+"whatever.sh", []byte(""), 0644)) + require.NoError(t, ioutil.WriteFile(home+"whatever.sh", []byte(""), 0644)) result, err := bundle.New(home, home+" kind:path").Get() - assert.Equal(t, "export PATH=\""+home+":$PATH\"", result) - assert.NoError(t, err) + require.Equal(t, "export PATH=\""+home+":$PATH\"", result) + require.NoError(t, err) } func home() string { diff --git a/bundle/zsh.go b/bundle/zsh.go index 2f346b9..0ba2679 100644 --- a/bundle/zsh.go +++ b/bundle/zsh.go @@ -1,6 +1,7 @@ package bundle import ( + "fmt" "os" "path/filepath" "strings" @@ -38,7 +39,7 @@ func (bundle zshBundle) Get() (result string, err error) { for _, file := range files { lines = append(lines, "source "+file) } - + lines = append(lines, fmt.Sprintf("fpath+=( %s )", bundle.Project.Folder())) return strings.Join(lines, "\n"), err } diff --git a/goreleaser.yml b/goreleaser.yml index f097f52..fe54952 100644 --- a/goreleaser.yml +++ b/goreleaser.yml @@ -2,6 +2,7 @@ build: goos: - linux - darwin + - freebsd goarch: - 386 - amd64 @@ -24,7 +25,7 @@ brew: description: The fastest shell plugin manager dependencies: - git -fpm: +nfpm: homepage: http://getantibody.github.io description: The fastest shell plugin manager maintainer: Carlos Alexandro Becker diff --git a/main.go b/main.go index 814618d..b11aeff 100644 --- a/main.go +++ b/main.go @@ -4,16 +4,19 @@ import ( "bytes" "fmt" "io" + "log" "os" "path/filepath" "runtime" "strconv" "strings" + "text/tabwriter" "github.com/alecthomas/kingpin" "github.com/getantibody/antibody/antibodylib" "github.com/getantibody/antibody/project" "github.com/getantibody/antibody/shell" + "github.com/getantibody/folder" "golang.org/x/crypto/ssh/terminal" ) @@ -30,11 +33,17 @@ var ( updateCmd = app.Command("update", "updates all previously bundled bundles") homeCmd = app.Command("home", "prints where antibody is cloning the bundles") purgeCmd = app.Command("purge", "purges a bundle from your computer") - purgee = purgeCmd.Arg("bundle", "bundle to be purged").String() + purgee = purgeCmd.Arg("bundle", "bundle to be purged").Required().String() listCmd = app.Command("list", "lists all currently installed bundles").Alias("ls") initCmd = app.Command("init", "initializes the shell so Antibody can work as expected") ) +func init() { + log.SetOutput(os.Stderr) + log.SetPrefix("antibody: ") + log.SetFlags(0) +} + func main() { app.Author("Carlos Alexandro Becker ") app.Version("antibody version " + version) @@ -88,7 +97,9 @@ func list() { home := antibodylib.Home() projects, err := project.List(home) app.FatalIfError(err, "failed to list bundles") + w := tabwriter.NewWriter(os.Stdout, 0, 1, 4, ' ', tabwriter.TabIndent) for _, b := range projects { - fmt.Println(filepath.Join(home, b)) + fmt.Fprintf(w, "%s\t%s\n", folder.ToURL(b), filepath.Join(home, b)) } + app.FatalIfError(w.Flush(), "failed to flush") } diff --git a/project/git.go b/project/git.go index 2e1182a..a885631 100644 --- a/project/git.go +++ b/project/git.go @@ -1,11 +1,13 @@ package project import ( + "fmt" "log" "os" "os/exec" "path/filepath" "strings" + "sync" "github.com/getantibody/folder" ) @@ -20,13 +22,14 @@ type gitProject struct { // NewClonedGit is a git project that was already cloned, so, only Update // will work here. func NewClonedGit(home, folderName string) Project { - version, err := branch(folderName) + folderPath := filepath.Join(home, folderName) + version, err := branch(folderPath) if err != nil { version = "master" } url := folder.ToURL(folderName) return gitProject{ - folder: filepath.Join(home, folderName), + folder: folderPath, Version: version, URL: url, } @@ -80,7 +83,13 @@ func NewGit(cwd, line string) Project { } } +var locks sync.Map + func (g gitProject) Download() error { + l, _ := locks.LoadOrStore(g.folder, &sync.Mutex{}) + lock := l.(*sync.Mutex) + lock.Lock() + defer lock.Unlock() if _, err := os.Stat(g.folder); os.IsNotExist(err) { // #nosec var cmd = exec.Command("git", "clone", @@ -89,7 +98,8 @@ func (g gitProject) Download() error { "-b", g.Version, g.URL, g.folder) - cmd.Env = append(cmd.Env, "GIT_TERMINAL_PROMPT=0") + cmd.Env = append(os.Environ(), "GIT_TERMINAL_PROMPT=0") + if bts, err := cmd.CombinedOutput(); err != nil { log.Println("git clone failed for", g.URL, string(bts)) return err @@ -99,6 +109,7 @@ func (g gitProject) Download() error { } func (g gitProject) Update() error { + fmt.Println("updating:", g.URL) // #nosec if bts, err := exec.Command( "git", "-C", g.folder, "pull", diff --git a/project/git_test.go b/project/git_test.go index 62e74ff..dfcd9d4 100644 --- a/project/git_test.go +++ b/project/git_test.go @@ -8,7 +8,7 @@ import ( "testing" "github.com/getantibody/antibody/project" - "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestDownloadAllKinds(t *testing.T) { @@ -27,7 +27,7 @@ func TestDownloadAllKinds(t *testing.T) { } for _, url := range urls { home := home() - assert.NoError( + require.NoError( t, project.NewGit(home, url).Download(), "Repo "+url+" failed to download", @@ -39,48 +39,64 @@ func TestDownloadSubmodules(t *testing.T) { var home = home() var proj = project.NewGit(home, "fribmendes/geometry") var module = filepath.Join(proj.Folder(), "lib/zsh-async") - assert.NoError(t, proj.Download()) - assert.NoError(t, proj.Update()) + require.NoError(t, proj.Download()) + require.NoError(t, proj.Update()) files, err := ioutil.ReadDir(module) - assert.NoError(t, err) - assert.True(t, len(files) > 1) + require.NoError(t, err) + require.True(t, len(files) > 1) } func TestDownloadAnotherBranch(t *testing.T) { home := home() - assert.NoError(t, project.NewGit(home, "caarlos0/jvm branch:gh-pages").Download()) + require.NoError(t, project.NewGit(home, "caarlos0/jvm branch:gh-pages").Download()) +} + +func TestUpdateAnotherBranch(t *testing.T) { + home := home() + repo := project.NewGit(home, "caarlos0/jvm branch:gh-pages") + require.NoError(t, repo.Download()) + alreadyClonedRepo := project.NewClonedGit(home, "https-COLON--SLASH--SLASH-github.com-SLASH-caarlos0-SLASH-jvm") + require.NoError(t, alreadyClonedRepo.Update()) +} + +func TestUpdateExistentLocalRepo(t *testing.T) { + home := home() + repo := project.NewGit(home, "caarlos0/ports") + require.NoError(t, repo.Download()) + alreadyClonedRepo := project.NewClonedGit(home, "https-COLON--SLASH--SLASH-github.com-SLASH-caarlos0-SLASH-ports") + require.NoError(t, alreadyClonedRepo.Update()) } func TestUpdateNonExistentLocalRepo(t *testing.T) { home := home() repo := project.NewGit(home, "caarlos0/ports") - assert.Error(t, repo.Update()) + require.Error(t, repo.Update()) } func TestDownloadNonExistentRepo(t *testing.T) { home := home() repo := project.NewGit(home, "caarlos0/not-a-real-repo") - assert.Error(t, repo.Download()) + require.Error(t, repo.Download()) } func TestDownloadMalformedRepo(t *testing.T) { home := home() repo := project.NewGit(home, "doesn-not-exist-really branch:also-nope") - assert.Error(t, repo.Download()) + require.Error(t, repo.Download()) } func TestDownloadMultipleTimes(t *testing.T) { home := home() repo := project.NewGit(home, "caarlos0/ports") - assert.NoError(t, repo.Download()) - assert.NoError(t, repo.Download()) - assert.NoError(t, repo.Update()) + require.NoError(t, repo.Download()) + require.NoError(t, repo.Download()) + require.NoError(t, repo.Update()) } func TestDownloadFolderNaming(t *testing.T) { home := home() repo := project.NewGit(home, "caarlos0/ports") - assert.Equal( + require.Equal( t, home+"/https-COLON--SLASH--SLASH-github.com-SLASH-caarlos0-SLASH-ports", repo.Folder(), @@ -90,7 +106,7 @@ func TestDownloadFolderNaming(t *testing.T) { func TestSubFolder(t *testing.T) { home := home() repo := project.NewGit(home, "robbyrussell/oh-my-zsh folder:plugins/aws") - assert.True(t, strings.HasSuffix(repo.Folder(), "plugins/aws")) + require.True(t, strings.HasSuffix(repo.Folder(), "plugins/aws")) } func TestPath(t *testing.T) { @@ -101,8 +117,10 @@ func TestPath(t *testing.T) { func TestMultipleSubFolders(t *testing.T) { home := home() - assert.NoError(t, project.NewGit(home, "robbyrussell/oh-my-zsh folder:plugins/aws").Download()) - assert.NoError(t, project.NewGit(home, "robbyrussell/oh-my-zsh folder:plugins/battery").Download()) + require.NoError(t, project.NewGit(home, strings.Join([]string{ + "robbyrussell/oh-my-zsh folder:plugins/aws", + "robbyrussell/oh-my-zsh folder:plugins/battery", + }, "\n")).Download()) } func home() string { diff --git a/project/local.go b/project/local.go index acc4b05..958d140 100644 --- a/project/local.go +++ b/project/local.go @@ -7,7 +7,7 @@ import ( // NewLocal Returns a local project, which can be any folder you want to func NewLocal(folder string) Project { - return localProject{strings.Split(folder, " ")[0]} + return localProject{folder: strings.Split(folder, " ")[0]} } type localProject struct { diff --git a/project/local_test.go b/project/local_test.go index 32dfb66..dc44979 100644 --- a/project/local_test.go +++ b/project/local_test.go @@ -4,12 +4,12 @@ import ( "testing" "github.com/getantibody/antibody/project" - "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestLocalProject(t *testing.T) { proj := project.NewLocal("/tmp") - assert.NoError(t, proj.Download()) - assert.NoError(t, proj.Update()) - assert.Equal(t, "/tmp", proj.Folder()) + require.NoError(t, proj.Download()) + require.NoError(t, proj.Update()) + require.Equal(t, "/tmp", proj.Folder()) } diff --git a/project/project_test.go b/project/project_test.go index d628dc3..1b497c9 100644 --- a/project/project_test.go +++ b/project/project_test.go @@ -7,53 +7,53 @@ import ( "testing" "github.com/getantibody/antibody/project" - "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestList(t *testing.T) { home := home() - assert.NoError(t, project.New(home, "caarlos0/jvm branch:gh-pages").Download()) + require.NoError(t, project.New(home, "caarlos0/jvm branch:gh-pages").Download()) list, err := project.List(home) - assert.NoError(t, err) - assert.Len(t, list, 1) + require.NoError(t, err) + require.Len(t, list, 1) } func TestListEmptyFolder(t *testing.T) { home := home() list, err := project.List(home) - assert.NoError(t, err) - assert.Len(t, list, 0) + require.NoError(t, err) + require.Len(t, list, 0) } func TestListNonExistentFolder(t *testing.T) { list, err := project.List("/tmp/asdasdadadwhateverwtff") - assert.Error(t, err) - assert.Len(t, list, 0) + require.Error(t, err) + require.Len(t, list, 0) } func TestUpdate(t *testing.T) { home := home() repo := project.New(home, "caarlos0/ports") - assert.NoError(t, repo.Download()) - assert.NoError(t, repo.Update()) + require.NoError(t, repo.Download()) + require.NoError(t, repo.Update()) } func TestUpdateHome(t *testing.T) { home := home() - assert.NoError(t, project.New(home, "caarlos0/jvm").Download()) - assert.NoError(t, project.New(home, "caarlos0/ports").Download()) - assert.NoError(t, project.New(home, "/tmp").Download()) - assert.NoError(t, project.Update(home, runtime.NumCPU())) + require.NoError(t, project.New(home, "caarlos0/jvm").Download()) + require.NoError(t, project.New(home, "caarlos0/ports").Download()) + require.NoError(t, project.New(home, "/tmp").Download()) + require.NoError(t, project.Update(home, runtime.NumCPU())) } func TestUpdateNonExistentHome(t *testing.T) { - assert.Error(t, project.Update("/tmp/asdasdasdasksksksksnopeeeee", runtime.NumCPU())) + require.Error(t, project.Update("/tmp/asdasdasdasksksksksnopeeeee", runtime.NumCPU())) } func TestUpdateHomeWithNoGitProjects(t *testing.T) { home := home() repo := project.New(home, "caarlos0/jvm") - assert.NoError(t, repo.Download()) - assert.NoError(t, os.RemoveAll(filepath.Join(repo.Folder(), ".git"))) - assert.Error(t, project.Update(home, runtime.NumCPU())) + require.NoError(t, repo.Download()) + require.NoError(t, os.RemoveAll(filepath.Join(repo.Folder(), ".git"))) + require.Error(t, project.Update(home, runtime.NumCPU())) } diff --git a/shell/init.go b/shell/init.go index b6b025c..0e0dbbd 100644 --- a/shell/init.go +++ b/shell/init.go @@ -10,7 +10,7 @@ const tmpl = `#!/usr/bin/env zsh antibody() { case "$1" in bundle) - source <( {{ . }} $@ ) 2> /dev/null || {{ . }} $@ + source <( {{ . }} $@ ) || {{ . }} $@ ;; *) {{ . }} $@ @@ -19,7 +19,7 @@ antibody() { } _antibody() { - IFS=' ' read -A reply <<< "$(echo "bundle update list home init help")" + IFS=' ' read -A reply <<< "help bundle update home purge list init" } compctl -K _antibody antibody ` diff --git a/shell/init_test.go b/shell/init_test.go index 585db7f..3f0e482 100644 --- a/shell/init_test.go +++ b/shell/init_test.go @@ -4,11 +4,11 @@ import ( "testing" "github.com/getantibody/antibody/shell" - "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestGeneratesInit(t *testing.T) { shell, err := shell.Init() - assert.NoError(t, err) - assert.NotEmpty(t, shell) + require.NoError(t, err) + require.NotEmpty(t, shell) } diff --git a/www/.gitignore b/www/.gitignore new file mode 100644 index 0000000..364fdec --- /dev/null +++ b/www/.gitignore @@ -0,0 +1 @@ +public/ diff --git a/www/config.toml b/www/config.toml new file mode 100644 index 0000000..0616429 --- /dev/null +++ b/www/config.toml @@ -0,0 +1,11 @@ +baseURL = "https://getantibody.github.io/" +languageCode = "en-us" +title = "GetAntibody" +copyright = "Made with ❤️ by GetAntibody contributors." +googleAnalytics = "UA-68164063-1" +theme = "hugo-apex-theme" +pygmentsCodeFences = true +pygmentsStyle = "dracula" + +[params] +logo = "https://avatars2.githubusercontent.com/u/16625397?v=3&s=140" diff --git a/docs/200-compat.md b/www/content/compat.md similarity index 86% rename from docs/200-compat.md rename to www/content/compat.md index 5cebaa2..7d5ebd2 100644 --- a/docs/200-compat.md +++ b/www/content/compat.md @@ -1,9 +1,11 @@ --- title: Compatibility +weight: 200 +menu: true --- Since antibody started as a subset clone of antigen, one might wonder -compatible one is with another. Let's take a look. +how compatible one is with another. Let's take a look. Antibody can only `bundle` and `update` plugins. The `apply` command is not needed because running `antibody bundle` will already download and apply the diff --git a/www/content/even-faster.md b/www/content/even-faster.md new file mode 100644 index 0000000..11dc1b0 --- /dev/null +++ b/www/content/even-faster.md @@ -0,0 +1,13 @@ +--- +title: Make it even faster +weight: 100 +menu: true +--- + +Antibody is faster than other zsh package managers, but you might want to speed it up further. + +Highly recommended to read the following: + +- [Speeding up my ZSH load - Carlos Alexandro Becker](https://carlosbecker.com/posts/speeding-up-zsh/): outlines a few fixes that will speed up the prompt massively. Also explains how to debug your prompt load time. +- [Speed up zsh compinit by only checking cache once a day.](https://gist.github.com/ctechols/ca1035271ad134841284): mentioned in the previous link, but leaving this here for reference as it is helpful for anyone using zsh. +- [How to debug zsh startup time — JB on programming 1.0.0 documentation](http://jb-blog.readthedocs.io/en/latest/posts/0032-debugging-zsh-startup-time.html) diff --git a/docs/100-fast.md b/www/content/fast.md similarity index 99% rename from docs/100-fast.md rename to www/content/fast.md index 8aacff6..6746258 100644 --- a/docs/100-fast.md +++ b/www/content/fast.md @@ -1,5 +1,7 @@ --- title: How much faster? +weight: 100 +menu: true --- Let's see how much faster antibody is over antigen: diff --git a/docs/300-install.md b/www/content/install.md similarity index 81% rename from docs/300-install.md rename to www/content/install.md index 1b5602d..1faa277 100644 --- a/docs/300-install.md +++ b/www/content/install.md @@ -1,13 +1,15 @@ --- title: Install +weight: 300 +menu: true --- -Antibody can be installed trhough a variety of sources. +Antibody can be installed through a variety of sources. The simplest way is to run: ```sh -curl -sL git.io/antibody | bash -s +curl -sL git.io/antibody | sh -s ``` This will put the binary in `/usr/local/bin/antibody` diff --git a/docs/000-intro.md b/www/content/intro.md similarity index 95% rename from docs/000-intro.md rename to www/content/intro.md index 837e41b..6296247 100644 --- a/docs/000-intro.md +++ b/www/content/intro.md @@ -1,5 +1,7 @@ --- title: Introduction +weight: 1 +menu: true --- Antibody is a shell plugin manager made from the ground up thinking about diff --git a/docs/999-links.md b/www/content/links.md similarity index 57% rename from docs/999-links.md rename to www/content/links.md index f2248bc..6c51f30 100644 --- a/docs/999-links.md +++ b/www/content/links.md @@ -1,10 +1,12 @@ --- title: Links +weight: 999 +menu: true --- -* Follow the progress on the [GitHub repository](https://github.com/getantibody/antibody) -* Follow [@caarlos0](https://twitter.com/caarlos0) on Twitter for updates -* [Contributing Guidelines](https://github.com/getantibody/antibody/blob/master/CONTRIBUTING.md) +- Follow the progress on the [GitHub repository](https://github.com/getantibody/antibody) +- Follow [@caarlos0](https://twitter.com/caarlos0) on Twitter for updates +- [Contributing Guidelines](https://github.com/getantibody/antibody/blob/master/CONTRIBUTING.md) This project adheres to the Contributor Covenant [code of conduct](https://github.com/getantibody/antibody/blob/master/CODE_OF_CONDUCT.md). diff --git a/docs/410-options.md b/www/content/options.md similarity index 58% rename from docs/410-options.md rename to www/content/options.md index 86c7fe0..85cff54 100644 --- a/docs/410-options.md +++ b/www/content/options.md @@ -1,5 +1,7 @@ --- title: Options +weight: 410 +menu: true --- There are a few options you can use that should cover most common use cases. @@ -11,10 +13,10 @@ The `kind` annotation can be used to determine how a bundle should be treated. The default is `kind:zsh`, which will look for files that match these globs: -* `*.plugin.zsh` -* `*.zsh` -* `*.sh` -* `*.zsh-theme` +- `*.plugin.zsh` +- `*.zsh` +- `*.sh` +- `*.zsh-theme` And `source` them. @@ -56,4 +58,17 @@ Example: ```console $ antibody bundle robbyrussell/oh-my-zsh folder:plugins/aws source /Users/carlos/Library/Caches/antibody/https-COLON--SLASH--SLASH-github.com-SLASH-robbyrussell-SLASH-oh-my-zsh/plugins/aws/aws.plugin.zsh +fpath+=( /Users/carlos/Library/Caches/antibody/https-COLON--SLASH--SLASH-github.com-SLASH-robbyrussell-SLASH-oh-my-zsh/plugins/aws ) +``` + +If you want multiple folders from the same plugin, you can just repeat the +plugin with a different `folder` option: + +```console +$ antibody bundle "robbyrussell/oh-my-zsh folder:plugins/aws + robbyrussell/oh-my-zsh folder:plugins/asdf" +source /Users/carlos/Library/Caches/antibody/https-COLON--SLASH--SLASH-github.com-SLASH-robbyrussell-SLASH-oh-my-zsh/plugins/aws/aws.plugin.zsh +fpath+=( /Users/carlos/Library/Caches/antibody/https-COLON--SLASH--SLASH-github.com-SLASH-robbyrussell-SLASH-oh-my-zsh/plugins/aws ) +source /Users/carlos/Library/Caches/antibody/https-COLON--SLASH--SLASH-github.com-SLASH-robbyrussell-SLASH-oh-my-zsh/plugins/asdf/asdf.plugin.zsh +fpath+=( /Users/carlos/Library/Caches/antibody/https-COLON--SLASH--SLASH-github.com-SLASH-robbyrussell-SLASH-oh-my-zsh/plugins/asdf ) ``` diff --git a/docs/500-update.md b/www/content/update.md similarity index 72% rename from docs/500-update.md rename to www/content/update.md index b846bc3..1a183c4 100644 --- a/docs/500-update.md +++ b/www/content/update.md @@ -1,5 +1,7 @@ --- title: Outro +weight: 500 +menu: true --- Let's look what other commands antibody has available for us! @@ -33,8 +35,8 @@ course list them: ```console $ antibody list -/Users/carlos/Library/Caches/antibody/https-COLON--SLASH--SLASH-github.com-SLASH-Tarrasch-SLASH-zsh-bd -/Users/carlos/Library/Caches/antibody/https-COLON--SLASH--SLASH-github.com-SLASH-caarlos0-SLASH-git-add-remote +https://github.com/Tarrasch/zsh-bd /Users/carlos/Library/Caches/antibody/https-COLON--SLASH--SLASH-github.com-SLASH-Tarrasch-SLASH-zsh-bd +https://github.com/caarlos0/git-add-remote /Users/carlos/Library/Caches/antibody/https-COLON--SLASH--SLASH-github.com-SLASH-caarlos0-SLASH-git-add-remote # ... ``` diff --git a/docs/400-usage.md b/www/content/usage.md similarity index 98% rename from docs/400-usage.md rename to www/content/usage.md index 855f7cf..81284f3 100644 --- a/docs/400-usage.md +++ b/www/content/usage.md @@ -1,5 +1,7 @@ --- title: Usage +weight: 400 +menu: true --- There are mainly two ways of using antibody: static and dynamic. diff --git a/www/static/apple-touch-icon.png b/www/static/apple-touch-icon.png new file mode 100644 index 0000000..1ea0e89 Binary files /dev/null and b/www/static/apple-touch-icon.png differ diff --git a/www/static/avatar.png b/www/static/avatar.png new file mode 100644 index 0000000..eca288e Binary files /dev/null and b/www/static/avatar.png differ diff --git a/www/static/favicon.ico b/www/static/favicon.ico new file mode 100644 index 0000000..5a1a1e2 Binary files /dev/null and b/www/static/favicon.ico differ diff --git a/www/themes/hugo-apex-theme b/www/themes/hugo-apex-theme new file mode 160000 index 0000000..7a952e6 --- /dev/null +++ b/www/themes/hugo-apex-theme @@ -0,0 +1 @@ +Subproject commit 7a952e65f3dcdc1023f35a7faf83b7b70de4631a