├── .github ├── codecov.yml ├── delete-merged-branch-config.yml ├── dependabot.yml ├── labeler.yml └── workflows │ ├── cleanup.yml │ ├── commitlint.yml │ ├── depreview.yml │ ├── docs-test.yml │ ├── docs.yml │ ├── go.yml │ ├── greetings.yml │ ├── labeler.yml │ ├── release.yml │ ├── reportcard.yml │ └── stale.yml ├── .gitignore ├── .golangci.yml ├── .goreleaser.yaml ├── CODE_OF_CONDUCT.md ├── Giltfile.yaml ├── LICENSE ├── README.md ├── Taskfile.yml ├── asset ├── favicon.ico ├── gilt.png └── gilt.xcf ├── cmd ├── init.go ├── overlay.go ├── resources │ └── art.txt ├── root.go └── version.go ├── docs ├── .gitignore ├── README.md ├── Taskfile.yml ├── babel.config.js ├── docs │ ├── configuration.md │ ├── contributing.md │ ├── installation.md │ ├── intro.md │ ├── testing.md │ └── usage.md ├── docusaurus.config.js ├── package.json ├── prettier.config.js ├── sidebars.js ├── src │ ├── components │ │ └── HomepageFeatures │ │ │ ├── index.js │ │ │ └── styles.module.css │ └── css │ │ ├── custom.css │ │ └── prism-rose-pine-moon.css ├── static │ ├── .nojekyll │ └── img │ │ ├── favicon.ico │ │ └── gilt.png ├── versioned_docs │ ├── version-2.0.3 │ │ ├── configuration.md │ │ ├── contributing.md │ │ ├── installation.md │ │ ├── intro.md │ │ ├── testing.md │ │ └── usage.md │ ├── version-2.1.1 │ │ ├── configuration.md │ │ ├── contributing.md │ │ ├── installation.md │ │ ├── intro.md │ │ ├── testing.md │ │ └── usage.md │ ├── version-2.1.2 │ │ ├── configuration.md │ │ ├── contributing.md │ │ ├── installation.md │ │ ├── intro.md │ │ ├── testing.md │ │ └── usage.md │ ├── version-2.2.1 │ │ ├── configuration.md │ │ ├── contributing.md │ │ ├── installation.md │ │ ├── intro.md │ │ ├── testing.md │ │ └── usage.md │ ├── version-2.2.2 │ │ ├── configuration.md │ │ ├── contributing.md │ │ ├── installation.md │ │ ├── intro.md │ │ ├── testing.md │ │ └── usage.md │ ├── version-2.2.3 │ │ ├── configuration.md │ │ ├── contributing.md │ │ ├── installation.md │ │ ├── intro.md │ │ ├── testing.md │ │ └── usage.md │ ├── version-2.2 │ │ ├── configuration.md │ │ ├── contributing.md │ │ ├── installation.md │ │ ├── intro.md │ │ ├── testing.md │ │ └── usage.md │ └── version-v2.2.4 │ │ ├── configuration.md │ │ ├── contributing.md │ │ ├── installation.md │ │ ├── intro.md │ │ ├── testing.md │ │ └── usage.md ├── versioned_sidebars │ ├── version-2.0.3-sidebars.json │ ├── version-2.1.1-sidebars.json │ ├── version-2.1.2-sidebars.json │ ├── version-2.2-sidebars.json │ ├── version-2.2.1-sidebars.json │ ├── version-2.2.2-sidebars.json │ ├── version-2.2.3-sidebars.json │ └── version-v2.2.4-sidebars.json ├── versions.json └── yarn.lock ├── examples └── go-client │ ├── go.mod │ ├── go.sum │ └── main.go ├── go.mod ├── go.sum ├── internal ├── exec.go ├── exec │ ├── exec.go │ ├── exec_public_test.go │ └── types.go ├── git.go ├── git │ ├── git.go │ ├── git_public_test.go │ └── types.go ├── mocks │ ├── exec.go │ ├── exec │ │ └── exec_mock.go │ ├── git.go │ ├── git │ │ └── git_mock.go │ ├── repository.go │ └── repository │ │ ├── copy_mock.go │ │ └── repository_mock.go ├── path │ ├── path.go │ └── path_public_test.go ├── repositories.go ├── repositories │ ├── repositories.go │ ├── repositories_public_test.go │ ├── repositories_test.go │ └── types.go ├── repository.go └── repository │ ├── copy.go │ ├── copy_public_test.go │ ├── helper_test.go │ ├── repository.go │ ├── repository_public_test.go │ └── types.go ├── main.go ├── pkg ├── config │ ├── schema.go │ ├── schema_test.go │ └── types.go ├── repositories.go └── repositories │ ├── repositories.go │ └── types.go ├── python └── dist2wheel.py └── test ├── Giltfile.yaml └── integration └── test_cli.bats /.github/codecov.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # codecov: 3 | # require_ci_to_pass: yes 4 | 5 | coverage: 6 | precision: 2 7 | round: down 8 | range: "50...100" 9 | 10 | comment: 11 | layout: "reach,diff,flags,files,footer" 12 | behavior: default 13 | require_changes: false 14 | 15 | ignore: 16 | - "**/*_mock.go" 17 | -------------------------------------------------------------------------------- /.github/delete-merged-branch-config.yml: -------------------------------------------------------------------------------- 1 | --- 2 | exclude: 3 | # dependabot auto deletes it's own branches 4 | - dependabot/* 5 | delete_closed_pr: true 6 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | --- 2 | version: 2 3 | updates: 4 | - package-ecosystem: "github-actions" 5 | directory: "/" 6 | schedule: 7 | interval: "daily" 8 | commit-message: 9 | prefix: chore 10 | 11 | - package-ecosystem: "gomod" 12 | directory: "/" 13 | schedule: 14 | interval: "daily" 15 | commit-message: 16 | prefix: chore 17 | 18 | - package-ecosystem: "gomod" 19 | directory: "examples/go-client/" 20 | schedule: 21 | interval: "daily" 22 | commit-message: 23 | prefix: chore 24 | ignore: 25 | - dependency-name: ".*" 26 | -------------------------------------------------------------------------------- /.github/labeler.yml: -------------------------------------------------------------------------------- 1 | --- 2 | test/unit: 3 | - changed-files: 4 | - any-glob-to-any-file: "**/*_test.go" 5 | 6 | test/integration: 7 | - changed-files: 8 | - any-glob-to-any-file: "tests/*" 9 | - any-glob-to-any-file: "tests/*/**" 10 | 11 | kind/go: 12 | - changed-files: 13 | - any-glob-to-any-file: "**/*.go" 14 | 15 | kind/python: 16 | - changed-files: 17 | - any-glob-to-any-file: "python/*" 18 | 19 | kind/yaml: 20 | - changed-files: 21 | - any-glob-to-any-file: "**/*.yaml" 22 | - any-glob-to-any-file: "**/*.yml" 23 | 24 | kind/docs: 25 | - changed-files: 26 | - any-glob-to-any-file: "docs/*" 27 | - any-glob-to-any-file: "docs/*/**" 28 | 29 | github/action: 30 | - changed-files: 31 | - any-glob-to-any-file: ".github/**/*.yml" 32 | 33 | next: 34 | - base-branch: 'main' 35 | -------------------------------------------------------------------------------- /.github/workflows/cleanup.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Cleanup 3 | 4 | on: 5 | pull_request: 6 | types: [closed] 7 | 8 | jobs: 9 | delete-branch: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: delete branch 13 | uses: SvanBoxel/delete-merged-branch@main 14 | env: 15 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 16 | -------------------------------------------------------------------------------- /.github/workflows/commitlint.yml: -------------------------------------------------------------------------------- 1 | name: Conventional Commits 2 | on: 3 | pull_request: 4 | branches: [ "main" ] 5 | jobs: 6 | build: 7 | name: Conventional Commits 8 | runs-on: ubuntu-latest 9 | steps: 10 | - uses: actions/checkout@v4 11 | - uses: webiny/action-conventional-commits@v1.3.0 12 | with: 13 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 14 | -------------------------------------------------------------------------------- /.github/workflows/depreview.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: 'Dependency Review' 3 | on: [pull_request] 4 | 5 | permissions: 6 | contents: read 7 | 8 | jobs: 9 | dependency-review: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: 'Checkout Repository' 13 | uses: actions/checkout@v4 14 | - name: 'Dependency Review' 15 | uses: actions/dependency-review-action@v4 16 | -------------------------------------------------------------------------------- /.github/workflows/docs-test.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Test Deploy to GitHub Pages 3 | 4 | on: 5 | pull_request: 6 | branches: 7 | - main 8 | 9 | jobs: 10 | test-deploy: 11 | name: Test deployment 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: actions/checkout@v4 15 | - uses: actions/setup-node@v4 16 | with: 17 | node-version: 20 18 | cache: yarn 19 | cache-dependency-path: ./docs/yarn.lock 20 | - name: Install Task 21 | uses: arduino/setup-task@v2 22 | with: 23 | version: 3.x 24 | repo-token: ${{ secrets.GITHUB_TOKEN }} 25 | - name: Lint the website 26 | run: task docs:fmt:check 27 | - name: Test build website 28 | run: task docs:build 29 | -------------------------------------------------------------------------------- /.github/workflows/docs.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Deploy to GitHub Pages 3 | 4 | on: 5 | push: 6 | branches: 7 | - main 8 | # Allows you to run this workflow manually from the Actions tab 9 | workflow_dispatch: 10 | 11 | permissions: 12 | contents: write 13 | 14 | jobs: 15 | deploy: 16 | name: Deploy to GitHub Pages 17 | runs-on: ubuntu-latest 18 | steps: 19 | - uses: actions/checkout@v4 20 | - uses: actions/setup-node@v4 21 | with: 22 | node-version: 20 23 | cache: yarn 24 | cache-dependency-path: ./docs/yarn.lock 25 | - name: Install Task 26 | uses: arduino/setup-task@v2 27 | with: 28 | version: 3.x 29 | repo-token: ${{ secrets.GITHUB_TOKEN }} 30 | - name: Build website 31 | run: task docs:build 32 | 33 | # Popular action to deploy to GitHub Pages: 34 | # Docs: https://github.com/peaceiris/actions-gh-pages#%EF%B8%8F-docusaurus 35 | - name: Deploy to GitHub Pages 36 | uses: peaceiris/actions-gh-pages@v4 37 | with: 38 | github_token: ${{ secrets.GITHUB_TOKEN }} 39 | # Build output to publish to the `gh-pages` branch: 40 | publish_dir: ./docs/build 41 | # The following lines assign commit authorship to the official 42 | # GH-Actions bot for deploys to `gh-pages` branch: 43 | # https://github.com/actions/checkout/issues/13#issuecomment-724415212 44 | # The GH actions bot is used by default if you didn't specify the two fields. 45 | # You can swap them out with your own user credentials. 46 | user_name: github-actions[bot] 47 | user_email: 41898282+github-actions[bot]@users.noreply.github.com 48 | 49 | 50 | -------------------------------------------------------------------------------- /.github/workflows/go.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Go 3 | 4 | on: 5 | push: 6 | branches: [ "main" ] 7 | pull_request: 8 | branches: [ "main" ] 9 | 10 | jobs: 11 | build: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: actions/checkout@v4 15 | - name: Set up Go 16 | uses: actions/setup-go@v5 17 | with: 18 | go-version: '1.23.8' 19 | - name: Install Task 20 | uses: arduino/setup-task@v2 21 | with: 22 | version: 3.x 23 | repo-token: ${{ secrets.GITHUB_TOKEN }} 24 | - name: Test 25 | run: task test 26 | - name: Upload coverage reports to Codecov 27 | uses: codecov/codecov-action@v5 28 | env: 29 | CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} 30 | -------------------------------------------------------------------------------- /.github/workflows/greetings.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Greetings 3 | 4 | on: [pull_request, issues] 5 | 6 | jobs: 7 | greeting: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - uses: actions/first-interaction@v1 11 | if: env.month != 'Oct' 12 | with: 13 | repo-token: ${{ secrets.GITHUB_TOKEN }} 14 | issue-message: 'Thank you for your first issue! 😊🕹️' 15 | pr-message: 'Thank you for contributing to this project! 😊🕹️' 16 | - uses: actions/first-interaction@v1 17 | if: env.month == 'Oct' 18 | with: 19 | repo-token: ${{ secrets.GITHUB_TOKEN }} 20 | issue-message: 'Thank you for your first issue! Happy Hacktoberfest!!! 🎃👕🕹️' 21 | pr-message: 'Thank you for contributing to this project. Happy Hacktoberfest!!! 🎃👕🕹️' 22 | -------------------------------------------------------------------------------- /.github/workflows/labeler.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: "Pull Request Labeler" 3 | on: 4 | - pull_request_target 5 | 6 | jobs: 7 | triage: 8 | permissions: 9 | contents: read 10 | pull-requests: write 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/labeler@v5 14 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: release packages 3 | on: 4 | push: 5 | tags: 6 | - "v*" 7 | 8 | permissions: 9 | contents: write 10 | # packages: write 11 | # issues: write 12 | # permission is mandatory for trusted publishing 13 | id-token: write 14 | 15 | jobs: 16 | release: 17 | runs-on: ubuntu-latest 18 | steps: 19 | - uses: actions/checkout@v4 20 | with: 21 | fetch-depth: 0 22 | - run: git fetch --force --tags 23 | - uses: actions/setup-go@v5 24 | with: 25 | go-version: stable 26 | - uses: goreleaser/goreleaser-action@v6 27 | with: 28 | distribution: goreleaser 29 | version: latest 30 | args: release --clean 31 | env: 32 | GITHUB_TOKEN: ${{ secrets.GH_PAT }} 33 | - name: Install Task 34 | uses: arduino/setup-task@v2 35 | with: 36 | version: 3.x 37 | repo-token: ${{ secrets.GITHUB_TOKEN }} 38 | - name: Build Wheels 39 | run: task build:wheel 40 | - uses: pypa/gh-action-pypi-publish@release/v1 41 | with: 42 | packages-dir: dist/whl/ 43 | -------------------------------------------------------------------------------- /.github/workflows/reportcard.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Go Report Card 3 | 4 | on: 5 | push: 6 | branches: [ "main" ] 7 | 8 | jobs: 9 | action_goreportcard: 10 | runs-on: ubuntu-latest 11 | name: A job to run go report card 12 | steps: 13 | - name: Go Report Card 14 | uses: creekorful/goreportcard-action@v1.0 15 | -------------------------------------------------------------------------------- /.github/workflows/stale.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Mark stale issues and pull requests 3 | 4 | on: 5 | schedule: 6 | - cron: "30 1 * * *" 7 | 8 | jobs: 9 | stale: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/stale@v9 13 | with: 14 | repo-token: ${{ secrets.GITHUB_TOKEN }} 15 | stale-issue-message: 'Stale issue message' 16 | stale-pr-message: 'Stale pull request message' 17 | stale-issue-label: 'no-issue-activity' 18 | stale-pr-label: 'no-pr-activity' 19 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | __pycache__ 2 | cobertura.xml 3 | cover.out 4 | dist/ 5 | result.xml 6 | .task/ 7 | test/integration/tmp/ 8 | test/integration/vendor/ 9 | -------------------------------------------------------------------------------- /.golangci.yml: -------------------------------------------------------------------------------- 1 | # Refer to golangci-lint's example config file for more options and information: 2 | # https://github.com/golangci/golangci-lint/blob/master/.golangci.example.yml 3 | 4 | run: 5 | timeout: 5m 6 | modules-download-mode: readonly 7 | 8 | linters: 9 | enable: 10 | - errcheck 11 | - errname 12 | - goimports 13 | - govet 14 | - prealloc 15 | - predeclared 16 | - revive 17 | - staticcheck 18 | 19 | linters-settings: 20 | revive: 21 | rules: 22 | - name: package-comments 23 | disabled: true 24 | 25 | issues: 26 | exclude-use-default: false 27 | max-issues-per-linter: 0 28 | max-same-issues: 0 29 | exclude-dirs: 30 | - .asdf 31 | -------------------------------------------------------------------------------- /.goreleaser.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | before: 3 | hooks: 4 | - go mod tidy 5 | 6 | builds: 7 | - env: 8 | - CGO_ENABLED=0 9 | goos: 10 | - linux 11 | - darwin 12 | ldflags: 13 | - -s -w -X {{ .ModulePath }}/cmd.date={{ .CommitDate }} 14 | - -X {{ .ModulePath }}/cmd.commit={{ .Commit }} 15 | - -X {{ .ModulePath }}/cmd.version={{ .Version }} 16 | - -X {{ .ModulePath }}/cmd.builtBy=goreleaser 17 | - -X {{ .ModulePath }}/cmd.treestate={{ .IsGitDirty }} 18 | 19 | archives: 20 | - format: binary 21 | checksum: 22 | name_template: 'checksums.txt' 23 | snapshot: 24 | name_template: "{{ incpatch .Version }}.dev" 25 | changelog: 26 | sort: asc 27 | filters: 28 | exclude: 29 | - '^test:' 30 | - "^chore" 31 | - "merge conflict" 32 | - Merge pull request 33 | - Merge remote-tracking branch 34 | - Merge branch 35 | - go mod tidy 36 | groups: 37 | - title: "Features" 38 | regexp: "^.*?feat:.*$" 39 | order: 0 40 | - title: "Bug fixes" 41 | regexp: "^.*?fix:.*$" 42 | order: 1 43 | - title: "Chores" 44 | regexp: "^.*?chore:.*$" 45 | order: 2 46 | - title: "Docs" 47 | regexp: "^.*?docs:.*$" 48 | order: 3 49 | - title: "CI" 50 | regexp: "^.*?ci:.*$" 51 | order: 4 52 | - title: "Build" 53 | regexp: "^.*?build:.*$" 54 | order: 5 55 | - title: Others 56 | order: 999 57 | brews: 58 | - repository: 59 | owner: retr0h 60 | name: homebrew-tap 61 | directory: Formula 62 | goarm: "7" 63 | homepage: https://github.com/retr0h/gilt 64 | description: A GIT layering tool 65 | license: MIT 66 | test: | 67 | system "#{bin}/goreleaser -v" 68 | dependencies: 69 | - name: go 70 | type: optional 71 | - name: git 72 | universal_binaries: 73 | - replace: true 74 | -------------------------------------------------------------------------------- /Giltfile.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | giltDir: ~/.gilt/clone 3 | debug: false 4 | repositories: 5 | - git: https://github.com/retr0h/ansible-etcd.git 6 | version: 77a95b7 7 | dstDir: /tmp/retr0h.ansible-etcd 8 | - git: https://github.com/retr0h/ansible-etcd.git 9 | version: 1.1 10 | dstDir: /tmp/retr0h.ansible-etcd 11 | - git: https://github.com/lorin/openstack-ansible-modules.git 12 | version: 2677cc3 13 | sources: 14 | - src: "*_manage" 15 | dstDir: /tmp/library 16 | - src: nova_quota 17 | dstDir: /tmp/library 18 | - src: neutron_router 19 | dstFile: /tmp/library/neutron_router.py 20 | - src: tests 21 | dstDir: /tmp/tests 22 | commands: 23 | - cmd: touch 24 | args: /tmp/post-command-1 25 | - cmd: touch 26 | args: /tmp/post-command-2 27 | - cmd: ls 28 | args: 29 | - -altr 30 | - /tmp 31 | - cmd: bash 32 | args: 33 | - -c 34 | - who | grep tty 35 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Copyright (c) 2018-2023 John Dewey 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![release](https://img.shields.io/github/release/retr0h/gilt.svg?style=for-the-badge)](https://github.com/retr0h/gilt/releases/latest) 2 | [![codecov](https://img.shields.io/codecov/c/github/retr0h/gilt?token=clAMnFQCEQ&style=for-the-badge)](https://codecov.io/gh/retr0h/gilt) 3 | [![go report card](https://goreportcard.com/badge/github.com/retr0h/gilt?style=for-the-badge)](https://goreportcard.com/report/github.com/retr0h/gilt/v2) 4 | [![license](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=for-the-badge)](LICENSE) 5 | [![build](https://img.shields.io/github/actions/workflow/status/retr0h/gilt/go.yml?style=for-the-badge)](https://github.com/retr0h/gilt/actions/workflows/go.yml) 6 | [![powered by](https://img.shields.io/badge/powered%20by-goreleaser-green.svg?style=for-the-badge)](https://github.com/goreleaser) 7 | [![conventional commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg?style=for-the-badge)](https://conventionalcommits.org) 8 | ![gitHub commit activity](https://img.shields.io/github/commit-activity/m/retr0h/gilt?style=for-the-badge) 9 | 10 | # Gilt 11 | 12 | 13 | 14 | Gilt is a tool which aims to make repo management, manageable. Gilt 15 | clones repositories at a particular version, then overlays the repository to 16 | the provided destination. An alternate approach to "vendoring". 17 | 18 | What makes Gilt interesting, is the ability to overlay particular files and/or 19 | directories from the specified repository to given destinations. Originally, 20 | this was quite helpful for those using Ansible, since libraries, plugins, and 21 | playbooks are often shared, but Ansible's [Galaxy][] has no mechanism to handle 22 | this. Currently, this is proving useful for overlaying [Helm charts][]. 23 | 24 |
25 | 26 | ## Documentation 27 | 28 | [Installation][] | [Usage][] | [Documentation][] 29 | 30 | [Installation]: https://retr0h.github.io/gilt/installation 31 | [Usage]: https://retr0h.github.io/gilt/usage 32 | [Documentation]: https://retr0h.github.io/gilt/ 33 | 34 | ## License 35 | 36 | The [MIT][] License. 37 | 38 | The logo is licensed under the [Creative Commons NoDerivatives 4.0 License][], 39 | and designed by [@nanotron][]. 40 | If you have some other use in mind, contact us. 41 | 42 | [Galaxy]: https://docs.ansible.com/ansible/latest/reference_appendices/galaxy.html 43 | [Helm charts]: https://helm.sh/docs/topics/charts/ 44 | [MIT]: LICENSE 45 | [Creative Commons NoDerivatives 4.0 License]: https://creativecommons.org/licenses/by-nd/4.0/ 46 | [@nanotron]: https://github.com/nanotron 47 | -------------------------------------------------------------------------------- /Taskfile.yml: -------------------------------------------------------------------------------- 1 | --- 2 | version: "3" 3 | 4 | vars: 5 | GIT_ROOT: 6 | sh: git rev-parse --show-toplevel 7 | MAIN_PACKAGE: main.go 8 | 9 | includes: 10 | docs: 11 | taskfile: ./docs 12 | dir: ./docs 13 | 14 | tasks: 15 | deps: 16 | desc: Install dependencies 17 | cmds: 18 | - go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest 19 | - go install github.com/princjef/gomarkdoc/cmd/gomarkdoc@latest 20 | - go install golang.org/x/vuln/cmd/govulncheck@latest 21 | - go install github.com/jstemmer/go-junit-report@latest 22 | - go install github.com/segmentio/golines@latest 23 | - go install github.com/golang/mock/mockgen@latest 24 | - go install github.com/boumenot/gocover-cobertura@latest 25 | - go install mvdan.cc/gofumpt@latest 26 | - go install github.com/goreleaser/goreleaser@latest 27 | - go get github.com/bats-core/bats-core@latest 28 | - bash $(go env GOMODCACHE)/$(go list -m github.com/bats-core/bats-core | tr ' ' @)/install.sh ./test/integration/vendor/bats 29 | 30 | deps:check: 31 | desc: Check dependencies needed for development 32 | cmds: 33 | - echo "Dependency check OK" 34 | preconditions: 35 | - sh: "case '{{OS}}' in darwin|linux) true ;; *) false ;; esac" 36 | msg: Operating System '{{OS}}' not supported 37 | 38 | - sh: command -v jq 39 | msg: | 40 | 'jq' not found in $PATH 41 | 42 | Suggested action: 'brew install jq' 43 | 44 | mod: 45 | desc: Module maintenance 46 | cmds: 47 | - go mod download 48 | - go mod tidy 49 | 50 | vet: 51 | desc: Report likely mistakes in packages 52 | cmds: 53 | - $(go env GOPATH)/bin/golangci-lint run --config {{ .GIT_ROOT }}/.golangci.yml 54 | 55 | vuln: 56 | desc: Run Go's vulnerability scanner 57 | cmds: 58 | - govulncheck ./... 59 | 60 | run: 61 | desc: Compile and run Go program 62 | cmds: 63 | - go run {{ .MAIN_PACKAGE }} {{.CLI_ARGS}} 64 | 65 | unit: 66 | desc: Test packages 67 | cmds: 68 | - go test -parallel 5 -race -v ./... 69 | 70 | unit:int: 71 | desc: Integration test packages 72 | cmds: 73 | - task: unit:bats 74 | 75 | unit:bats: 76 | desc: Integration bats test packages 77 | cmds: 78 | - ./test/integration/vendor/bats/bin/bats test/integration 79 | 80 | 81 | test: 82 | desc: Test all 83 | cmds: 84 | - task: deps 85 | - task: mod 86 | - task: fmt:check 87 | - task: vet 88 | - task: cov 89 | - task: unit:int 90 | 91 | cov: 92 | desc: Generate coverage 93 | env: 94 | # https://github.com/golang/go/issues/65570 95 | GOEXPERIMENT: nocoverageredesign 96 | cmds: 97 | - go test -race -coverprofile=cover.out -v $(go list ./... | grep -v /mocks) 98 | - gocover-cobertura < cover.out > cobertura.xml 99 | - go tool cover -func=cover.out 100 | 101 | cov:map: 102 | desc: Generate coverage and show heatmap 103 | cmds: 104 | - task: cov 105 | - go tool cover -html=cover.out 106 | 107 | fmt: 108 | desc: Reformat files whose formatting differs from `go_fmt_command` 109 | cmds: 110 | - gofumpt -l -w . 111 | - golines --base-formatter=gofumpt -w . 112 | 113 | fmt:check: 114 | desc: Check files whose formatting differs from `go_fmt_command` 115 | cmds: 116 | # https://github.com/mvdan/gofumpt/issues/114 117 | - test -z "$(gofumpt -d -e . | tee /dev/stderr)" 118 | - test -z "$(golines -l --dry-run --base-formatter=gofumpt -w .)" 119 | 120 | build: 121 | desc: Build ARCH compatible binary. 122 | cmds: 123 | - goreleaser release --snapshot --clean 124 | 125 | build:wheel: 126 | desc: Build ARCH Python wheel. Requires running `task build` first. 127 | cmds: 128 | - python/dist2wheel.py 129 | 130 | mockgen: 131 | desc: Generate mock for interface 132 | cmds: 133 | - mockgen -source=internal/git.go -destination=internal/mocks/git/git_mock.go -package=git 134 | - mockgen -source=internal/repository.go -destination=internal/mocks/repository/repository_mock.go -package=repository 135 | - mockgen -source=internal/exec.go -destination=internal/mocks/exec/exec_mock.go -package=exec 136 | - mockgen -source=internal/repository/types.go -destination=internal/mocks/repository/copy_mock.go -package=repository 137 | -------------------------------------------------------------------------------- /asset/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/retr0h/gilt/445b710dfbbb6e8396f47a5217e8112a98de881a/asset/favicon.ico -------------------------------------------------------------------------------- /asset/gilt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/retr0h/gilt/445b710dfbbb6e8396f47a5217e8112a98de881a/asset/gilt.png -------------------------------------------------------------------------------- /asset/gilt.xcf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/retr0h/gilt/445b710dfbbb6e8396f47a5217e8112a98de881a/asset/gilt.xcf -------------------------------------------------------------------------------- /cmd/init.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 John Dewey 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 19 | // DEALINGS IN THE SOFTWARE. 20 | 21 | package cmd 22 | 23 | import ( 24 | "bytes" 25 | "fmt" 26 | "log/slog" 27 | "os" 28 | 29 | "github.com/spf13/cobra" 30 | "github.com/spf13/viper" 31 | "gopkg.in/yaml.v3" 32 | 33 | "github.com/retr0h/gilt/v2/pkg/config" 34 | ) 35 | 36 | // initCmd represents the init command 37 | var initCmd = &cobra.Command{ 38 | Use: "init", 39 | Short: "Initialize Gilt with a Giltfile", 40 | Long: `Initializes Gilt by creating a default config file in the shell's 41 | current working directory.`, 42 | Run: func(cmd *cobra.Command, args []string) { 43 | var b bytes.Buffer 44 | 45 | // set configFile defaults 46 | repo := []config.Repository{ 47 | { 48 | Git: "", 49 | Version: "", 50 | DstDir: "", 51 | }, 52 | } 53 | viper.SetDefault("repositories", repo) 54 | c := viper.AllSettings() 55 | 56 | ye := yaml.NewEncoder(&b) 57 | ye.SetIndent(2) 58 | if err := ye.Encode(c); err != nil { 59 | logFatal( 60 | "failed to encode file", 61 | slog.Group("", 62 | slog.String("err", err.Error()), 63 | ), 64 | ) 65 | } 66 | 67 | configFile := viper.GetString("giltFile") 68 | _, err := os.Stat(configFile) 69 | if err == nil { 70 | logFatal( 71 | "file already exists", 72 | slog.Group("", 73 | slog.String("Giltfile", configFile), 74 | ), 75 | ) 76 | } 77 | 78 | if err := os.WriteFile(configFile, b.Bytes(), 0o644); err != nil { 79 | logFatal( 80 | "failed to write file", 81 | slog.Group("", 82 | slog.String("Giltfile", viper.ConfigFileUsed()), 83 | slog.String("err", err.Error()), 84 | ), 85 | ) 86 | } 87 | 88 | fmt.Printf("wrote %s\n", configFile) 89 | }, 90 | } 91 | 92 | func init() { 93 | rootCmd.AddCommand(initCmd) 94 | } 95 | -------------------------------------------------------------------------------- /cmd/overlay.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018 John Dewey 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 19 | // DEALINGS IN THE SOFTWARE. 20 | 21 | package cmd 22 | 23 | import ( 24 | "github.com/spf13/cobra" 25 | 26 | "github.com/retr0h/gilt/v2/pkg/repositories" 27 | ) 28 | 29 | // overlayCmd represents the overlay command 30 | var overlayCmd = &cobra.Command{ 31 | Use: "overlay", 32 | Short: "Install Gilt dependencies", 33 | Long: `Overlay the repositories from the Giltfile into their respective 34 | destinations.`, 35 | RunE: func(cmd *cobra.Command, args []string) error { 36 | // By the time we reach this point, we know that the arguments were 37 | // properly parsed, and we don't want to show the usage if an error 38 | // occurs 39 | cmd.SilenceUsage = true 40 | // We are logging errors, no need for cobra to re-log the error 41 | cmd.SilenceErrors = true 42 | 43 | initConfig() 44 | initLogger() 45 | 46 | repos := repositories.New( 47 | appConfig, 48 | logger, 49 | ) 50 | return repos.Overlay() 51 | }, 52 | } 53 | 54 | func init() { 55 | rootCmd.AddCommand(overlayCmd) 56 | } 57 | -------------------------------------------------------------------------------- /cmd/resources/art.txt: -------------------------------------------------------------------------------- 1 | 2 | o o 3 | o | | 4 | o--o | -o- 5 | | | | | | 6 | o--O | o o 7 | | 8 | o--o 9 | 10 | -------------------------------------------------------------------------------- /cmd/root.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018 John Dewey 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 19 | // DEALINGS IN THE SOFTWARE. 20 | 21 | package cmd 22 | 23 | import ( 24 | _ "embed" 25 | "fmt" 26 | "log/slog" 27 | "os" 28 | "strings" 29 | "time" 30 | 31 | "github.com/lmittmann/tint" 32 | "github.com/spf13/cobra" 33 | "github.com/spf13/viper" 34 | "golang.org/x/term" 35 | 36 | "github.com/retr0h/gilt/v2/pkg/config" 37 | ) 38 | 39 | var ( 40 | logger *slog.Logger 41 | appConfig config.Repositories 42 | //go:embed resources/art.txt 43 | asciiArt string 44 | ) 45 | 46 | const ( 47 | desc = "A GIT layering command line tool.\n" 48 | website = "https://github.com/retr0h/gilt" 49 | ) 50 | 51 | // rootCmd represents the base command when called without any subcommands 52 | var rootCmd = &cobra.Command{ 53 | Use: "gilt", 54 | Short: "A GIT layering command line tool", 55 | Long: fmt.Sprintf("%sgilt: %s\n%s", asciiArt, desc, website), 56 | } 57 | 58 | // Execute adds all child commands to the root command and sets flags appropriately. 59 | // This is called by main.main(). It only needs to happen once to the rootCmd. 60 | func Execute() { 61 | err := rootCmd.Execute() 62 | if err != nil { 63 | os.Exit(1) 64 | } 65 | } 66 | 67 | func init() { 68 | rootCmd.PersistentFlags().BoolP("debug", "d", false, "Enable or disable debug mode") 69 | rootCmd.PersistentFlags().BoolP("parallel", "p", true, "Fetch clones in parallel") 70 | rootCmd.PersistentFlags().Bool("no-commands", false, "Skip post-commands when overlaying") 71 | rootCmd.PersistentFlags(). 72 | StringP("gilt-dir", "c", "~/.gilt/clone", "Path to Gilt's clone dir") 73 | rootCmd.PersistentFlags(). 74 | StringP("gilt-file", "f", "Giltfile.yaml", "Path to config file") 75 | 76 | _ = viper.BindPFlag("debug", rootCmd.PersistentFlags().Lookup("debug")) 77 | _ = viper.BindPFlag("parallel", rootCmd.PersistentFlags().Lookup("parallel")) 78 | _ = viper.BindPFlag("skipCommands", rootCmd.PersistentFlags().Lookup("no-commands")) 79 | _ = viper.BindPFlag("giltFile", rootCmd.PersistentFlags().Lookup("gilt-file")) 80 | _ = viper.BindPFlag("giltDir", rootCmd.PersistentFlags().Lookup("gilt-dir")) 81 | _ = viper.BindPFlag("repositories", rootCmd.PersistentFlags().Lookup("repositories")) 82 | 83 | cobra.OnInitialize(initLogger) 84 | } 85 | 86 | func logFatal(message string, logGroup any) { 87 | logger.Error( 88 | message, 89 | logGroup, 90 | ) 91 | 92 | os.Exit(1) 93 | } 94 | 95 | func initLogger() { 96 | logLevel := slog.LevelInfo 97 | if viper.GetBool("debug") { 98 | logLevel = slog.LevelDebug 99 | } 100 | 101 | logger = slog.New( 102 | tint.NewHandler(os.Stderr, &tint.Options{ 103 | Level: logLevel, 104 | TimeFormat: time.Kitchen, 105 | NoColor: !term.IsTerminal(int(os.Stdout.Fd())), 106 | }), 107 | ) 108 | } 109 | 110 | func initConfig() { 111 | viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_")) 112 | 113 | viper.SetConfigType("yaml") 114 | viper.AutomaticEnv() 115 | viper.SetEnvPrefix("gilt") 116 | viper.SetConfigFile(viper.GetString("giltFile")) 117 | 118 | if err := viper.ReadInConfig(); err != nil { 119 | logFatal( 120 | "failed to read config", 121 | slog.Group("", 122 | slog.String("Giltfile", viper.ConfigFileUsed()), 123 | slog.String("err", err.Error()), 124 | ), 125 | ) 126 | } 127 | 128 | if err := viper.Unmarshal(&appConfig); err != nil { 129 | logFatal( 130 | "failed to unmarshal config", 131 | slog.Group("", 132 | slog.String("Giltfile", viper.ConfigFileUsed()), 133 | slog.String("err", err.Error()), 134 | ), 135 | ) 136 | } 137 | 138 | err := config.Validate(&appConfig) 139 | if err != nil { 140 | logFatal( 141 | "validation failed", 142 | slog.Group("", 143 | slog.String("Giltfile", viper.ConfigFileUsed()), 144 | slog.String("err", err.Error()), 145 | ), 146 | ) 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /cmd/version.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018 John Dewey 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 19 | // DEALINGS IN THE SOFTWARE. 20 | 21 | package cmd 22 | 23 | import ( 24 | "fmt" 25 | 26 | goversion "github.com/caarlos0/go-version" 27 | "github.com/spf13/cobra" 28 | ) 29 | 30 | func buildVersion(version, commit, date, builtBy, treeState string) goversion.Info { 31 | return goversion.GetVersionInfo( 32 | goversion.WithAppDetails("gilt", desc, website), 33 | goversion.WithASCIIName(asciiArt), 34 | func(i *goversion.Info) { 35 | if commit != "" { 36 | i.GitCommit = commit 37 | } 38 | if treeState != "" { 39 | i.GitTreeState = treeState 40 | } 41 | if date != "" { 42 | i.BuildDate = date 43 | } 44 | if version != "" { 45 | i.GitVersion = version 46 | } 47 | if builtBy != "" { 48 | i.BuiltBy = builtBy 49 | } 50 | }, 51 | ) 52 | } 53 | 54 | // versionCmd represents the version command. 55 | var ( 56 | version = "" 57 | commit = "" 58 | treeState = "" 59 | date = "" 60 | builtBy = "" 61 | versionCmd = &cobra.Command{ 62 | Use: "version", 63 | Short: "Display the version of tool", 64 | Run: func(cmd *cobra.Command, args []string) { 65 | version := buildVersion(version, commit, date, builtBy, treeState) 66 | 67 | jsonOut, _ := version.JSONString() 68 | fmt.Println(jsonOut) 69 | }, 70 | } 71 | ) 72 | 73 | func init() { 74 | rootCmd.AddCommand(versionCmd) 75 | } 76 | -------------------------------------------------------------------------------- /docs/.gitignore: -------------------------------------------------------------------------------- 1 | # Dependencies 2 | /node_modules 3 | 4 | # Production 5 | /build 6 | 7 | # Generated files 8 | .docusaurus 9 | .cache-loader 10 | 11 | # Misc 12 | .DS_Store 13 | .env.local 14 | .env.development.local 15 | .env.test.local 16 | .env.production.local 17 | 18 | npm-debug.log* 19 | yarn-debug.log* 20 | yarn-error.log* 21 | -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | # Website 2 | 3 | This website is built using [Docusaurus](https://docusaurus.io/), a modern static website generator. 4 | 5 | ### Local Development 6 | 7 | ``` 8 | $ task start 9 | ``` 10 | 11 | This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server. 12 | 13 | ### Build 14 | 15 | ``` 16 | $ task build 17 | ``` 18 | 19 | This command generates static content into the `build` directory and can be served using any static contents hosting service. 20 | -------------------------------------------------------------------------------- /docs/Taskfile.yml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | 3 | tasks: 4 | yarn:install: 5 | desc: Setup Docusaurus locally 6 | cmds: 7 | - yarn install 8 | sources: 9 | - package.json 10 | - yarn.lock 11 | 12 | build: 13 | desc: Build website 14 | deps: 15 | - yarn:install 16 | cmds: 17 | - yarn docusaurus build 18 | 19 | start: 20 | desc: Start website 21 | deps: 22 | - yarn:install 23 | vars: 24 | HOST: '{{default "localhost" .HOST}}' 25 | PORT: '{{default "3001" .PORT}}' 26 | cmds: 27 | - yarn docusaurus start --no-open --host={{.HOST}} --port={{.PORT}} 28 | 29 | serve: 30 | desc: Preview website 31 | deps: 32 | - yarn:install 33 | vars: 34 | HOST: '{{default "localhost" .HOST}}' 35 | PORT: '{{default "3001" .PORT}}' 36 | cmds: 37 | - yarn docusaurus serve --no-open --host={{.HOST}} --port={{.PORT}} 38 | 39 | clean: 40 | desc: Clean temp directories 41 | cmds: 42 | - rm -rf ./build 43 | 44 | bump: 45 | desc: Create a new documentation version 46 | vars: 47 | VERSION: '{{.VERSION}}' 48 | cmds: 49 | - yarn docusaurus docs:version {{.VERSION}} 50 | requires: 51 | vars: 52 | - VERSION 53 | 54 | deploy: 55 | desc: Build and deploy Docusaurus 56 | summary: Requires GIT_USER and GIT_PASS envs to be previous set 57 | cmds: 58 | - yarn docusaurus deploy 59 | 60 | fmt: 61 | desc: Reformat files whose formatting differs from `prettier` 62 | deps: 63 | - yarn:install 64 | cmds: 65 | - yarn prettier docs --write --config prettier.config.js 66 | 67 | fmt:check: 68 | desc: Check files whose formatting differs from `prettier` 69 | deps: 70 | - yarn:install 71 | cmds: 72 | - yarn prettier docs --check --config prettier.config.js 73 | -------------------------------------------------------------------------------- /docs/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [require.resolve('@docusaurus/core/lib/babel/preset')], 3 | }; 4 | -------------------------------------------------------------------------------- /docs/docs/contributing.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 6 3 | --- 4 | 5 | # Contributing 6 | 7 | Contributions to Gilt are very welcome, but we ask that you read this document 8 | before submitting a PR. 9 | 10 | :::note 11 | 12 | This document applies to the [Gilt][] repository. 13 | 14 | ::: 15 | 16 | ## Before you start 17 | 18 | - **Check existing work** - Is there an existing PR? Are there issues discussing 19 | the feature/change you want to make? Please make sure you consider/address 20 | these discussions in your work. 21 | - **Backwards compatibility** - Will your change break existing Giltfiles? It is 22 | much more likely that your change will merged if it backwards compatible. Is 23 | there an approach you can take that maintains this compatibility? If not, 24 | consider opening an issue first so that API changes can be discussed before 25 | you invest your time into a PR. 26 | 27 | ## 1. Setup 28 | 29 | - **Go** - Gilt is written in [Go][]. We always support the latest two major Go 30 | versions, so make sure your version is recent enough. 31 | - **Node.js** - [Node.js][] is used to host Gilt's documentation server and is 32 | required if you want to run this server locally. 33 | 34 | ## 2. Making changes 35 | 36 | - **Code style** - Try to maintain the existing code style where possible. Go 37 | code should be formatted by [`gofumpt`][gofumpt] and linted using 38 | [`golangci-lint`][golangci-lint]. Any Markdown or TypeScript files should be 39 | formatted and linted by [Prettier][]. This style is enforced by our CI to 40 | ensure that we have a consistent style across the project. You can use the 41 | `task fmt:check` command to lint the code locally and the `task fmt` command 42 | to automatically fix any issues that are found. 43 | - **Documentation** - Ensure that you add/update any relevant documentation. See 44 | the [updating documentation](#updating-documentation) section below. 45 | - **Tests** - Ensure that you add/update any relevant tests and that all tests 46 | are passing before submitting the PR. See the [writing tests](#writing-tests) 47 | section below. 48 | 49 | ### Running your changes 50 | 51 | To run Gilt with working changes, you can use `go run main.go overlay`. 52 | 53 | ### Updating documentation 54 | 55 | Gilt uses [Docusaurus][] to host a documentation server. The code for this is 56 | located in the Gilt repository. This can be setup and run locally by using 57 | `task docs:start` (requires `nodejs` & `yarn`). All content is written in 58 | Markdown and is located in the `docs/docs` directory. All Markdown documents 59 | should have an 80 character line wrap limit (enforced by Prettier). 60 | 61 | ### Writing tests 62 | 63 | When making changes, consider whether new tests are required. These tests should 64 | ensure that the functionality you are adding will continue to work in the 65 | future. Existing tests may also need updating if you have changed Gilt's 66 | behavior. 67 | 68 | You may also consider adding unit tests for any new functions you have added. 69 | The unit tests should follow the Go convention of being location in a file named 70 | `*_test.go` in the same package as the code being tested. 71 | 72 | Integration tests are located in the `tests` directory and executed by [Bats][]. 73 | 74 | ## 3. Committing your code 75 | 76 | Try to write meaningful commit messages and avoid having too many commits on the 77 | PR. Most PRs should likely have a single commit (although for bigger PRs it may 78 | be reasonable to split it in a few). Git squash and rebase is your friend! 79 | 80 | If you're not sure how to format your commit message, check out [Conventional 81 | Commits][]. This style is enforced, and is a good way to make your commit 82 | messages more readable and consistent. 83 | 84 | ## 4. Submitting a PR 85 | 86 | - **Describe your changes** - Ensure that you provide a comprehensive 87 | description of your changes. 88 | - **Issue/PR links** - Link any previous work such as related issues or PRs. 89 | Please describe how your changes differ to/extend this work. 90 | - **Examples** - Add any examples or screenshots that you think are useful to 91 | demonstrate the effect of your changes. 92 | - **Draft PRs** - If your changes are incomplete, but you would like to discuss 93 | them, open the PR as a draft and add a comment to start a discussion. Using 94 | comments rather than the PR description allows the description to be updated 95 | later while preserving any discussions. 96 | 97 | ## FAQ 98 | 99 | > I want to contribute, where do I start? 100 | 101 | All kinds of contributions are welcome, whether its a typo fix or a shiny new 102 | feature. You can also contribute by upvoting/commenting on issues or helping to 103 | answer questions. 104 | 105 | > I'm stuck, where can I get help? 106 | 107 | If you have questions, feel free open a [Discussion][] on GitHub. 108 | 109 | 110 | [Gilt]: https://github.com/retr0h/gilt 111 | [Go]: https://go.dev 112 | [Node.js]: https://nodejs.org/en/ 113 | [gofumpt]: https://github.com/mvdan/gofumpt 114 | [golangci-lint]: https://golangci-lint.run 115 | [Prettier]: https://prettier.io/ 116 | [Docusaurus]: https://docusaurus.io 117 | [Discussion]: https://github.com/retr0h/gilt/discussions 118 | [Conventional Commits]: https://www.conventionalcommits.org 119 | [Bats]: https://github.com/bats-core/bats-core 120 | 121 | -------------------------------------------------------------------------------- /docs/docs/installation.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 2 3 | --- 4 | 5 | # Installation 6 | 7 | ## Homebrew Tap 8 | 9 | ```bash 10 | brew install retr0h/tap/gilt 11 | ``` 12 | 13 | ## Go Install 14 | 15 | ```bash 16 | go install github.com/retr0h/gilt/v2@latest 17 | ``` 18 | 19 | ## Python 20 | 21 | ```bash 22 | pip3 install python-gilt 23 | ``` 24 | -------------------------------------------------------------------------------- /docs/docs/intro.md: -------------------------------------------------------------------------------- 1 | --- 2 | slug: / 3 | sidebar_position: 1 4 | title: Home 5 | --- 6 | 7 | # Gilt 8 | 9 | 10 | 11 | Gilt is a tool which aims to make repo management, manageable. Gilt clones 12 | repositories at a particular version, then overlays the repository to the 13 | provided destination. An alternate approach to "vendoring". 14 | 15 | What makes Gilt interesting, is the ability to overlay particular files and/or 16 | directories from the specified repository to given destinations. Originally, 17 | this was quite helpful for those using Ansible, since libraries, plugins, and 18 | playbooks are often shared, but Ansible's [Galaxy][] has no mechanism to handle 19 | this. Currently, this is proving useful for overlaying [Helm charts][]. 20 | 21 |
22 | 23 | ## Alternatives 24 | 25 | - [Repo][] 26 | - [Git submodules][] 27 | - [Git subtree][] 28 | 29 | ## History 30 | 31 | This project is a golang port of [Gilt][py-gilt], and aims to correct poor 32 | decisions made in the python version, primarially around config syntax, 33 | portability, and reproducibility. 34 | 35 | 36 | [Galaxy]: https://docs.ansible.com/ansible/latest/reference_appendices/galaxy.html 37 | [Helm charts]: https://helm.sh/docs/topics/charts/ 38 | [Repo]: https://gerrit.googlesource.com/git-repo/+/refs/heads/master/README.md 39 | [Git submodules]: https://git-scm.com/book/en/v2/Git-Tools-Submodules 40 | [Git subtree]: https://github.com/git/git/blob/master/contrib/subtree/git-subtree.txt 41 | [py-gilt]: http://gilt.readthedocs.io/en/latest/ 42 | 43 | -------------------------------------------------------------------------------- /docs/docs/testing.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 5 3 | --- 4 | 5 | # Testing 6 | 7 | Check installed dependencies: 8 | 9 | ```bash 10 | task deps:check 11 | ``` 12 | 13 | To execute tests: 14 | 15 | ```bash 16 | task test 17 | ``` 18 | 19 | Auto format code: 20 | 21 | ```bash 22 | task fmt 23 | ``` 24 | 25 | List helpful targets: 26 | 27 | ```bash 28 | task 29 | ``` 30 | -------------------------------------------------------------------------------- /docs/docs/usage.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 4 3 | --- 4 | 5 | # Usage 6 | 7 | ## CLI 8 | 9 | ### Init Configuration 10 | 11 | Initializes config file in the shell's current working directory: 12 | 13 | ```bash 14 | gilt init 15 | ``` 16 | 17 | ### Overlay Repository 18 | 19 | Overlay a remote repository into the destination provided. 20 | 21 | ```bash 22 | gilt overlay 23 | ``` 24 | 25 | ### Debug 26 | 27 | Display the git commands being executed. 28 | 29 | ```bash 30 | gilt --debug overlay 31 | ``` 32 | 33 | ### Skipping post-commands 34 | 35 | Overlay files only, but run no other commands. 36 | 37 | ```bash 38 | gilt overlay --no-commands 39 | ``` 40 | 41 | ## Package 42 | 43 | ### Overlay Repository 44 | 45 | See example client in `examples/go-client/`. 46 | 47 | ```go 48 | func main() { 49 | debug := true 50 | logger := getLogger(debug) 51 | 52 | c := config.Repositories{ 53 | Debug: debug, 54 | GiltDir: "~/.gilt", 55 | Repositories: []config.Repository{ 56 | { 57 | Git: "https://github.com/retr0h/ansible-etcd.git", 58 | Version: "77a95b7", 59 | DstDir: "../tmp/retr0h.ansible-etcd", 60 | }, 61 | }, 62 | } 63 | 64 | var r repositoriesManager = repositories.New(c, logger) 65 | r.Overlay() 66 | } 67 | ``` 68 | -------------------------------------------------------------------------------- /docs/docusaurus.config.js: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | // `@type` JSDoc annotations allow editor autocompletion and type checking 3 | // (when paired with `@ts-check`). 4 | // There are various equivalent ways to declare your Docusaurus config. 5 | // See: https://docusaurus.io/docs/api/docusaurus-config 6 | 7 | import {themes as prismThemes} from 'prism-react-renderer'; 8 | 9 | /** @type {import('@docusaurus/types').Config} */ 10 | const config = { 11 | title: 'Gilt', 12 | tagline: 'Dinosaurs are cool', 13 | favicon: 'img/favicon.ico', 14 | 15 | // Set the production url of your site here 16 | url: 'https://retr0h.github.io/', 17 | // Set the // pathname under which your site is served 18 | // For GitHub pages deployment, it is often '//' 19 | baseUrl: '/gilt/', 20 | trailingSlash: false, 21 | 22 | // GitHub pages deployment config. 23 | // If you aren't using GitHub pages, you don't need these. 24 | organizationName: 'retr0h', // Usually your GitHub org/user name. 25 | projectName: 'gilt', // Usually your repo name. 26 | 27 | onBrokenLinks: 'throw', 28 | onBrokenMarkdownLinks: 'warn', 29 | 30 | // Even if you don't use internationalization, you can use this field to set 31 | // useful metadata like html lang. For example, if your site is Chinese, you 32 | // may want to replace "en" with "zh-Hans". 33 | i18n: { 34 | defaultLocale: 'en', 35 | locales: ['en'], 36 | }, 37 | 38 | presets: [ 39 | [ 40 | 'classic', 41 | /** @type {import('@docusaurus/preset-classic').Options} */ 42 | ({ 43 | docs: { 44 | routeBasePath: '/', 45 | sidebarPath: './sidebars.js', 46 | }, 47 | blog: {}, 48 | pages: {}, 49 | theme: { 50 | customCss: [ 51 | './src/css/custom.css', 52 | './src/css/prism-rose-pine-moon.css', 53 | ], 54 | }, 55 | }), 56 | ], 57 | ], 58 | 59 | themeConfig: 60 | /** @type {import('@docusaurus/preset-classic').ThemeConfig} */ 61 | ({ 62 | // Replace with your project's social card 63 | // image: 'img/docusaurus-social-card.jpg', 64 | navbar: { 65 | title: 'Gilt', 66 | logo: { 67 | alt: 'Gilt Logo', 68 | src: 'img/gilt.png', 69 | }, 70 | items: [ 71 | { 72 | type: 'doc', 73 | docId: 'installation', 74 | position: 'left', 75 | label: 'Installation' 76 | }, 77 | { 78 | type: 'doc', 79 | docId: 'usage', 80 | position: 'left', 81 | label: 'Usage' 82 | }, 83 | { 84 | type: 'docsVersionDropdown', 85 | position: 'right', 86 | }, 87 | { 88 | href: 'https://github.com/retr0h/gilt', 89 | position: 'right', 90 | className: 'header-github-link', 91 | 'aria-label': 'GitHub repository', 92 | }, 93 | ], 94 | }, 95 | footer: { 96 | style: 'dark', 97 | links: [ 98 | { 99 | title: 'Community', 100 | items: [ 101 | { 102 | label: 'GitHub', 103 | href: 'https://github.com/retr0h/gilt', 104 | }, 105 | ], 106 | }, 107 | ], 108 | copyright: `Copyright © ${new Date().getFullYear()} @retr0h`, 109 | }, 110 | prism: { 111 | theme: prismThemes.github, 112 | darkTheme: prismThemes.dracula, 113 | additionalLanguages: ['bash', 'json', 'yaml'], 114 | }, 115 | colorMode: { 116 | defaultMode: 'dark', 117 | disableSwitch: false, 118 | respectPrefersColorScheme: false, 119 | }, 120 | announcementBar: { 121 | id: 'announcementBar-3', // Increment on change 122 | content: `🎉️ Gilt has been 💯 rewritten in Go! 🥳️`, 123 | }, 124 | }), 125 | }; 126 | 127 | export default config; 128 | -------------------------------------------------------------------------------- /docs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "docs", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "docusaurus": "docusaurus", 7 | "start": "docusaurus start", 8 | "build": "docusaurus build", 9 | "swizzle": "docusaurus swizzle", 10 | "deploy": "docusaurus deploy", 11 | "clear": "docusaurus clear", 12 | "serve": "docusaurus serve", 13 | "write-translations": "docusaurus write-translations", 14 | "write-heading-ids": "docusaurus write-heading-ids" 15 | }, 16 | "dependencies": { 17 | "@docusaurus/core": "3.0.1", 18 | "@docusaurus/preset-classic": "3.0.1", 19 | "@mdx-js/react": "^3.0.0", 20 | "clsx": "^2.0.0", 21 | "prettier": "^3.1.1", 22 | "prism-react-renderer": "^2.3.0", 23 | "react": "^18.0.0", 24 | "react-dom": "^18.0.0" 25 | }, 26 | "devDependencies": { 27 | "@docusaurus/module-type-aliases": "3.0.1", 28 | "@docusaurus/types": "3.0.1" 29 | }, 30 | "browserslist": { 31 | "production": [ 32 | ">0.5%", 33 | "not dead", 34 | "not op_mini all" 35 | ], 36 | "development": [ 37 | "last 3 chrome version", 38 | "last 3 firefox version", 39 | "last 5 safari version" 40 | ] 41 | }, 42 | "engines": { 43 | "node": ">=18.0" 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /docs/prettier.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | trailingComma: 'none', 3 | singleQuote: true, 4 | overrides: [ 5 | { 6 | files: ['*.md', '*.mdx'], 7 | options: { 8 | printWidth: 80, 9 | proseWrap: 'always' 10 | } 11 | } 12 | ] 13 | }; 14 | -------------------------------------------------------------------------------- /docs/sidebars.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Creating a sidebar enables you to: 3 | - create an ordered group of docs 4 | - render a sidebar for each doc of that group 5 | - provide next/previous navigation 6 | 7 | The sidebars can be generated from the filesystem, or explicitly defined here. 8 | 9 | Create as many sidebars as you want. 10 | */ 11 | 12 | // @ts-check 13 | 14 | /** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */ 15 | const sidebars = { 16 | // By default, Docusaurus generates a sidebar from the docs folder structure 17 | docsSidebar: [{type: 'autogenerated', dirName: '.'}], 18 | 19 | // But you can create a sidebar manually 20 | /* 21 | tutorialSidebar: [ 22 | 'intro', 23 | 'hello', 24 | { 25 | type: 'category', 26 | label: 'Tutorial', 27 | items: ['tutorial-basics/create-a-document'], 28 | }, 29 | ], 30 | */ 31 | }; 32 | 33 | export default sidebars; 34 | -------------------------------------------------------------------------------- /docs/src/components/HomepageFeatures/index.js: -------------------------------------------------------------------------------- 1 | import clsx from 'clsx'; 2 | import Heading from '@theme/Heading'; 3 | import styles from './styles.module.css'; 4 | 5 | const FeatureList = [ 6 | { 7 | title: 'Easy to Use', 8 | Svg: require('@site/static/img/undraw_docusaurus_mountain.svg').default, 9 | description: ( 10 | <> 11 | Docusaurus was designed from the ground up to be easily installed and 12 | used to get your website up and running quickly. 13 | 14 | ), 15 | }, 16 | { 17 | title: 'Focus on What Matters', 18 | Svg: require('@site/static/img/undraw_docusaurus_tree.svg').default, 19 | description: ( 20 | <> 21 | Docusaurus lets you focus on your docs, and we'll do the chores. Go 22 | ahead and move your docs into the docs directory. 23 | 24 | ), 25 | }, 26 | { 27 | title: 'Powered by React', 28 | Svg: require('@site/static/img/undraw_docusaurus_react.svg').default, 29 | description: ( 30 | <> 31 | Extend or customize your website layout by reusing React. Docusaurus can 32 | be extended while reusing the same header and footer. 33 | 34 | ), 35 | }, 36 | ]; 37 | 38 | function Feature({Svg, title, description}) { 39 | return ( 40 |
41 |
42 | 43 |
44 |
45 | {title} 46 |

{description}

47 |
48 |
49 | ); 50 | } 51 | 52 | export default function HomepageFeatures() { 53 | return ( 54 |
55 |
56 |
57 | {FeatureList.map((props, idx) => ( 58 | 59 | ))} 60 |
61 |
62 |
63 | ); 64 | } 65 | -------------------------------------------------------------------------------- /docs/src/components/HomepageFeatures/styles.module.css: -------------------------------------------------------------------------------- 1 | .features { 2 | display: flex; 3 | align-items: center; 4 | padding: 2rem 0; 5 | width: 100%; 6 | } 7 | 8 | .featureSvg { 9 | height: 200px; 10 | width: 200px; 11 | } 12 | -------------------------------------------------------------------------------- /docs/src/css/custom.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Any CSS included here will be global. The classic template 3 | * bundles Infima by default. Infima is a CSS framework designed to 4 | * work well for content-centric websites. 5 | */ 6 | 7 | /* You can override the default Infima variables here. */ 8 | :root { 9 | --ifm-color-primary: #2e8555; 10 | --ifm-color-primary-dark: #29784c; 11 | --ifm-color-primary-darker: #277148; 12 | --ifm-color-primary-darkest: #205d3b; 13 | --ifm-color-primary-light: #33925d; 14 | --ifm-color-primary-lighter: #359962; 15 | --ifm-color-primary-lightest: #3cad6e; 16 | --ifm-code-font-size: 95%; 17 | --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.1); 18 | } 19 | 20 | /* For readability concerns, you should choose a lighter palette in dark mode. */ 21 | [data-theme='dark'] { 22 | --ifm-color-primary: #25c2a0; 23 | --ifm-color-primary-dark: #21af90; 24 | --ifm-color-primary-darker: #1fa588; 25 | --ifm-color-primary-darkest: #1a8870; 26 | --ifm-color-primary-light: #29d5b0; 27 | --ifm-color-primary-lighter: #32d8b4; 28 | --ifm-color-primary-lightest: #4fddbf; 29 | --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.3); 30 | } 31 | 32 | /* Taken from docusaurus' website. */ 33 | .header-github-link::before { 34 | content: ''; 35 | width: 24px; 36 | height: 24px; 37 | display: flex; 38 | background-color: var(--ifm-navbar-link-color); 39 | mask-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12'/%3E%3C/svg%3E"); 40 | transition: background-color var(--ifm-transition-fast) 41 | var(--ifm-transition-timing-default); 42 | } 43 | 44 | /* Taken from docusaurus' website. */ 45 | .header-github-link:hover::before { 46 | background-color: var(--ifm-navbar-link-hover-color); 47 | } 48 | 49 | /* Taken from docusaurus' website. */ 50 | div[class^='announcementBar_'] { 51 | font-size: 20px; 52 | 53 | --site-announcement-bar-stripe-color1: #e8d7ff; 54 | --site-announcement-bar-stripe-color2: #ffe9d1; 55 | 56 | background: repeating-linear-gradient( 57 | 35deg, 58 | var(--site-announcement-bar-stripe-color1), 59 | var(--site-announcement-bar-stripe-color1) 20px, 60 | var(--site-announcement-bar-stripe-color2) 10px, 61 | var(--site-announcement-bar-stripe-color2) 40px 62 | ); 63 | font-weight: bold; 64 | } 65 | -------------------------------------------------------------------------------- /docs/src/css/prism-rose-pine-moon.css: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * Rosé Pine Theme 4 | * https://github.com/rose-pine 5 | * Ported for PrismJS by fvrests [@fvrests] 6 | */ 7 | 8 | code[class*="language-"], 9 | pre[class*="language-"] { 10 | color: #e0def4; 11 | background: #232136; 12 | font-family: "Cartograph CF", ui-monospace, SFMono-Regular, Menlo, Monaco, 13 | Consolas, "Liberation Mono", "Courier New", monospace; 14 | text-align: left; 15 | white-space: pre; 16 | word-spacing: normal; 17 | word-break: normal; 18 | word-wrap: normal; 19 | line-height: 1.5; 20 | 21 | -moz-tab-size: 4; 22 | -o-tab-size: 4; 23 | tab-size: 4; 24 | 25 | -webkit-hyphens: none; 26 | -moz-hyphens: none; 27 | -ms-hyphens: none; 28 | hyphens: none; 29 | 30 | @media print { 31 | text-shadow: none; 32 | } 33 | } 34 | 35 | /* Selection */ 36 | code[class*="language-"]::-moz-selection, 37 | pre[class*="language-"]::-moz-selection, 38 | code[class*="language-"] ::-moz-selection, 39 | pre[class*="language-"] ::-moz-selection { 40 | background: #312f44; 41 | } 42 | 43 | code[class*="language-"]::selection, 44 | pre[class*="language-"]::selection, 45 | code[class*="language-"] ::selection, 46 | pre[class*="language-"] ::selection { 47 | background: #312f44; 48 | } 49 | 50 | /* Code (block & inline) */ 51 | :not(pre) > code[class*="language-"], 52 | pre[class*="language-"] { 53 | color: #e0def4; 54 | background: #232136; 55 | } 56 | 57 | /* Code blocks */ 58 | pre[class*="language-"] { 59 | padding: 1em; 60 | margin: 0.5em 0; 61 | overflow: auto; 62 | } 63 | 64 | /* Inline code */ 65 | :not(pre) > code[class*="language-"] { 66 | padding: 0.1em; 67 | border-radius: 0.3em; 68 | white-space: normal; 69 | color: #e0def4; 70 | background: #232136; 71 | } 72 | 73 | /* Text style & opacity */ 74 | .token.entity { 75 | cursor: help; 76 | } 77 | 78 | .token.important, 79 | .token.bold { 80 | font-weight: bold; 81 | } 82 | 83 | .token.italic, 84 | .token.selector, 85 | .token.doctype, 86 | .token.attr-name, 87 | .token.inserted, 88 | .token.deleted, 89 | .token.comment, 90 | .token.prolog, 91 | .token.cdata, 92 | .token.constant, 93 | .token.parameter, 94 | .token.url { 95 | font-style: italic; 96 | } 97 | 98 | .token.url { 99 | text-decoration: underline; 100 | } 101 | 102 | .namespace { 103 | opacity: 0.7; 104 | } 105 | 106 | /* Syntax highlighting */ 107 | .token.constant { 108 | color: #e0def4; 109 | } 110 | 111 | .token.comment, 112 | .token.prolog, 113 | .token.cdata, 114 | .token.punctuation { 115 | color: #59546d; 116 | } 117 | 118 | .token.delimiter, 119 | .token.important, 120 | .token.atrule, 121 | .token.operator, 122 | .token.keyword { 123 | color: #3e8fb0; 124 | } 125 | 126 | .token.tag, 127 | .token.tag .punctuation, 128 | .token.doctype, 129 | .token.variable, 130 | .token.regex, 131 | .token.class-name, 132 | .token.selector, 133 | .token.inserted { 134 | color: #9ccfd8; 135 | } 136 | 137 | .token.boolean, 138 | .token.entity, 139 | .token.number, 140 | .token.symbol, 141 | .token.function { 142 | color: #ea9a97; 143 | } 144 | 145 | .token.string, 146 | .token.char, 147 | .token.property, 148 | .token.attr-value, 149 | .token.attr-value .punctuation { 150 | color: #f6c177; 151 | } 152 | 153 | .token.parameter, 154 | .token.url, 155 | .token.name, 156 | .token.attr-name, 157 | .token.builtin { 158 | color: #c4a7e7; 159 | } 160 | 161 | .token.deleted { 162 | color: #eb6f92; 163 | } 164 | 165 | /* Insertions & deletions */ 166 | .token.inserted { 167 | background: rgba(156 207 216 0.12); 168 | } 169 | 170 | .token.deleted { 171 | background: rgba(235 111 146 0.12); 172 | } 173 | 174 | /* Line highlighting */ 175 | pre[data-line] { 176 | position: relative; 177 | } 178 | 179 | pre[class*="language-"] > code[class*="language-"] { 180 | position: relative; 181 | z-index: 1; 182 | } 183 | 184 | .line-highlight, 185 | .highlight-lines .highlighted { 186 | position: absolute; 187 | left: 0; 188 | right: 0; 189 | padding: inherit 0; 190 | margin-top: 1em; 191 | 192 | background: #312f44; 193 | box-shadow: inset 5px 0 0 #e0def4; 194 | 195 | z-index: 0; 196 | 197 | pointer-events: none; 198 | 199 | line-height: inherit; 200 | white-space: pre; 201 | } 202 | -------------------------------------------------------------------------------- /docs/static/.nojekyll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/retr0h/gilt/445b710dfbbb6e8396f47a5217e8112a98de881a/docs/static/.nojekyll -------------------------------------------------------------------------------- /docs/static/img/favicon.ico: -------------------------------------------------------------------------------- 1 | ../../../asset/favicon.ico -------------------------------------------------------------------------------- /docs/static/img/gilt.png: -------------------------------------------------------------------------------- 1 | ../../../asset/gilt.png -------------------------------------------------------------------------------- /docs/versioned_docs/version-2.0.3/configuration.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 3 3 | --- 4 | 5 | # Configuration 6 | 7 | Gilt uses [Viper][] to load configuation through multiple methods. 8 | 9 | ## Config File 10 | 11 | Create the giltfile (`Giltfile.yaml`). 12 | 13 | Clone the specified `url`@`version` to the configurable path `--gilt-dir`. 14 | Extract the repo the `dstDir` when `dstDir` is provided. Otherwise, copy files 15 | and/or directories to the desired destinations. 16 | 17 | ```yaml 18 | --- 19 | giltDir: ~/.gilt/clone 20 | debug: false 21 | repositories: 22 | - git: https://github.com/retr0h/ansible-etcd.git 23 | version: 77a95b7 24 | dstDir: roles/retr0h.ansible-etcd 25 | - git: https://github.com/retr0h/ansible-etcd.git 26 | version: 1.1 27 | dstDir: roles/retr0h.ansible-etcd-tag 28 | - git: https://github.com/lorin/openstack-ansible-modules.git 29 | version: 2677cc3 30 | sources: 31 | - src: '*_manage' 32 | dstDir: library 33 | - src: nova_quota 34 | dstDir: library 35 | - src: neutron_router 36 | dstFile: library/neutron_router.py 37 | - src: tests 38 | dstDir: tests 39 | commands: 40 | - cmd: ansible-playbook 41 | args: 42 | - -i, 43 | - playbook.yml 44 | - cmd: bash 45 | args: 46 | - -c 47 | - who | grep tty 48 | ``` 49 | 50 | ## Env Vars 51 | 52 | The config file can be overriden/defined through env vars. 53 | 54 | ```bash 55 | GILT_GILTFILE=Giltfile.yaml \ 56 | GILT_GILTDIR=~/.gilt/clone \ 57 | GILT_DEBUG=false \ 58 | gilt overlay 59 | ``` 60 | 61 | ## Command Flags 62 | 63 | The config file and/or env vars can be overriden/defined through cli flags. 64 | 65 | ```bash 66 | gilt \ 67 | --gilt-file=Giltfile.yaml \ 68 | --gilt-dir=~/.gilt/clone \ 69 | --debug \ 70 | overlay 71 | ``` 72 | 73 | 74 | [Viper]: https://github.com/spf13/viper 75 | 76 | -------------------------------------------------------------------------------- /docs/versioned_docs/version-2.0.3/contributing.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 6 3 | --- 4 | 5 | # Contributing 6 | 7 | Contributions to Gilt are very welcome, but we ask that you read this document 8 | before submitting a PR. 9 | 10 | :::note 11 | 12 | This document applies to the [Gilt][] repository. 13 | 14 | ::: 15 | 16 | ## Before you start 17 | 18 | - **Check existing work** - Is there an existing PR? Are there issues discussing 19 | the feature/change you want to make? Please make sure you consider/address 20 | these discussions in your work. 21 | - **Backwards compatibility** - Will your change break existing Giltfiles? It is 22 | much more likely that your change will merged if it backwards compatible. Is 23 | there an approach you can take that maintains this compatibility? If not, 24 | consider opening an issue first so that API changes can be discussed before 25 | you invest your time into a PR. 26 | 27 | ## 1. Setup 28 | 29 | - **Go** - Gilt is written in [Go][]. We always support the latest two major Go 30 | versions, so make sure your version is recent enough. 31 | - **Node.js** - [Node.js][] is used to host Gilt's documentation server and is 32 | required if you want to run this server locally. 33 | 34 | ## 2. Making changes 35 | 36 | - **Code style** - Try to maintain the existing code style where possible. Go 37 | code should be formatted by [`gofumpt`][gofumpt] and linted using 38 | [`golangci-lint`][golangci-lint]. Any Markdown or TypeScript files should be 39 | formatted and linted by [Prettier][]. This style is enforced by our CI to 40 | ensure that we have a consistent style across the project. You can use the 41 | `task fmt:check` command to lint the code locally and the `task fmt` command 42 | to automatically fix any issues that are found. 43 | - **Documentation** - Ensure that you add/update any relevant documentation. See 44 | the [updating documentation](#updating-documentation) section below. 45 | - **Tests** - Ensure that you add/update any relevant tests and that all tests 46 | are passing before submitting the PR. See the [writing tests](#writing-tests) 47 | section below. 48 | 49 | ### Running your changes 50 | 51 | To run Gilt with working changes, you can use `go run main.go overlay`. 52 | 53 | ### Updating documentation 54 | 55 | Gilt uses [Docusaurus][] to host a documentation server. The code for this is 56 | located in the Gilt repository. This can be setup and run locally by using 57 | `task docs:start` (requires `nodejs` & `yarn`). All content is written in 58 | Markdown and is located in the `docs/docs` directory. All Markdown documents 59 | should have an 80 character line wrap limit (enforced by Prettier). 60 | 61 | ### Writing tests 62 | 63 | When making a changes, consider whether new tests are required. These tests 64 | should ensure that the functionality you are adding will continue to work in the 65 | future. Existing tests may also need updating if you have changed Gilt's 66 | behavior. 67 | 68 | You may also consider adding unit tests for any new functions you have added. 69 | The unit tests should follow the Go convention of being location in a file named 70 | `*_test.go` in the same package as the code being tested. 71 | 72 | Integration tests are located in the `tests` directory and executed by [Bats][]. 73 | 74 | ## 3. Committing your code 75 | 76 | Try to write meaningful commit messages and avoid having too many commits on the 77 | PR. Most PRs should likely have a single commit (although for bigger PRs it may 78 | be reasonable to split it in a few). Git squash and rebase is your friend! 79 | 80 | If you're not sure how to format your commit message, check out [Conventional 81 | Commits][]. This style is enforced, and is a good way to make your commit 82 | messages more readable and consistent. 83 | 84 | ## 4. Submitting a PR 85 | 86 | - **Describe your changes** - Ensure that you provide a comprehensive 87 | description of your changes. 88 | - **Issue/PR links** - Link any previous work such as related issues or PRs. 89 | Please describe how your changes differ to/extend this work. 90 | - **Examples** - Add any examples or screenshots that you think are useful to 91 | demonstrate the effect of your changes. 92 | - **Draft PRs** - If your changes are incomplete, but you would like to discuss 93 | them, open the PR as a draft and add a comment to start a discussion. Using 94 | comments rather than the PR description allows the description to be updated 95 | later while preserving any discussions. 96 | 97 | ## FAQ 98 | 99 | > I want to contribute, where do I start? 100 | 101 | All kinds of contributions are welcome, whether its a typo fix or a shiny new 102 | feature. You can also contribute by upvoting/commenting on issues or helping to 103 | answer questions. 104 | 105 | > I'm stuck, where can I get help? 106 | 107 | If you have questions, feel free open a [Discussion][] on GitHub. 108 | 109 | 110 | [Gilt]: https://github.com/retr0h/gilt 111 | [Go]: https://go.dev 112 | [Node.js]: https://nodejs.org/en/ 113 | [gofumpt]: https://github.com/mvdan/gofumpt 114 | [golangci-lint]: https://golangci-lint.run 115 | [Prettier]: https://prettier.io/ 116 | [Docusaurus]: https://docusaurus.io 117 | [Discussion]: https://github.com/retr0h/gilt/discussions 118 | [Conventional Commits]: https://www.conventionalcommits.org 119 | [Bats]: https://github.com/bats-core/bats-core 120 | 121 | -------------------------------------------------------------------------------- /docs/versioned_docs/version-2.0.3/installation.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 2 3 | --- 4 | 5 | # Installation 6 | 7 | ## Homebrew Tap 8 | 9 | ```bash 10 | brew install retr0h/tap/gilt 11 | ``` 12 | 13 | ## Go Install 14 | 15 | ```bash 16 | go install github.com/retr0h/gilt@latest 17 | ``` 18 | -------------------------------------------------------------------------------- /docs/versioned_docs/version-2.0.3/intro.md: -------------------------------------------------------------------------------- 1 | --- 2 | slug: / 3 | sidebar_position: 1 4 | title: Home 5 | --- 6 | 7 | # Gilt 8 | 9 | 10 | 11 | Gilt is a tool which aims to make repo management, manageable. Gilt clones 12 | repositories at a particular version, then overlays the repository to the 13 | provided destination. An alternate approach to "vendoring". 14 | 15 | What makes Gilt interesting, is the ability to overlay particular files and/or 16 | directories from the specified repository to given destinations. Originally, 17 | this was quite helpful for those using Ansible, since libraries, plugins, and 18 | playbooks are often shared, but Ansible's [Galaxy][] has no mechanism to handle 19 | this. Currently, this is proving useful for overlaying [Helm charts][]. 20 | 21 |
22 | 23 | ## Alternatives 24 | 25 | - [Repo][] 26 | - [Git submodules][] 27 | - [Git subtree][] 28 | 29 | ## History 30 | 31 | This project is a golang port of [Gilt][py-gilt], and aims to correct poor decisions 32 | made in the python version, primarially around config syntax, portability, and 33 | reproducibility. 34 | 35 | 36 | [Galaxy]: https://docs.ansible.com/ansible/latest/reference_appendices/galaxy.html 37 | [Helm charts]: https://helm.sh/docs/topics/charts/ 38 | [Repo]: https://gerrit.googlesource.com/git-repo/+/refs/heads/master/README.md 39 | [Git submodules]: https://git-scm.com/book/en/v2/Git-Tools-Submodules 40 | [Git subtree]: https://github.com/git/git/blob/master/contrib/subtree/git-subtree.txt 41 | [py-gilt]: http://gilt.readthedocs.io/en/latest/ 42 | 43 | -------------------------------------------------------------------------------- /docs/versioned_docs/version-2.0.3/testing.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 5 3 | --- 4 | 5 | # Testing 6 | 7 | Check installed dependencies: 8 | 9 | ```bash 10 | task deps:check 11 | ``` 12 | 13 | To execute tests: 14 | 15 | ```bash 16 | task test 17 | ``` 18 | 19 | Auto format code: 20 | 21 | ```bash 22 | task fmt 23 | ``` 24 | 25 | List helpful targets: 26 | 27 | ```bash 28 | task 29 | ``` 30 | -------------------------------------------------------------------------------- /docs/versioned_docs/version-2.0.3/usage.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 4 3 | --- 4 | 5 | # Usage 6 | 7 | ## CLI 8 | 9 | ### Init Configuration 10 | 11 | Initializes config file in the shell's current working directory: 12 | 13 | ```bash 14 | gilt init 15 | ``` 16 | 17 | ### Overlay Repository 18 | 19 | Overlay a remote repository into the destination provided. 20 | 21 | ```bash 22 | gilt overlay 23 | ``` 24 | 25 | ### Debug 26 | 27 | Display the git commands being executed. 28 | 29 | ```bash 30 | gilt --debug overlay 31 | ``` 32 | 33 | ## Package 34 | 35 | ### Overlay Repository 36 | 37 | See example client in `examples/go-client/`. 38 | 39 | ```go 40 | func main() { 41 | debug := true 42 | logger := getLogger(debug) 43 | 44 | c := config.Repositories{ 45 | Debug: debug, 46 | GiltDir: "~/.gilt", 47 | Repositories: []config.Repository{ 48 | { 49 | Git: "https://github.com/retr0h/ansible-etcd.git", 50 | Version: "77a95b7", 51 | DstDir: "../tmp/retr0h.ansible-etcd", 52 | }, 53 | }, 54 | } 55 | 56 | var r repositoriesManager = repositories.New(c, logger) 57 | r.Overlay() 58 | } 59 | ``` 60 | -------------------------------------------------------------------------------- /docs/versioned_docs/version-2.1.1/configuration.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 3 3 | --- 4 | 5 | # Configuration 6 | 7 | Gilt uses [Viper][] to load configuation through multiple methods. 8 | 9 | ## Config File 10 | 11 | Create the giltfile (`Giltfile.yaml`). 12 | 13 | Clone the specified `url`@`version` to the configurable path `--gilt-dir`. 14 | Extract the repo the `dstDir` when `dstDir` is provided. Otherwise, copy files 15 | and/or directories to the desired destinations. 16 | 17 | ```yaml 18 | --- 19 | giltDir: ~/.gilt/clone 20 | debug: false 21 | repositories: 22 | - git: https://github.com/retr0h/ansible-etcd.git 23 | version: 77a95b7 24 | dstDir: roles/retr0h.ansible-etcd 25 | - git: https://github.com/retr0h/ansible-etcd.git 26 | version: 1.1 27 | dstDir: roles/retr0h.ansible-etcd-tag 28 | - git: https://github.com/lorin/openstack-ansible-modules.git 29 | version: 2677cc3 30 | sources: 31 | - src: '*_manage' 32 | dstDir: library 33 | - src: nova_quota 34 | dstDir: library 35 | - src: neutron_router 36 | dstFile: library/neutron_router.py 37 | - src: tests 38 | dstDir: tests 39 | commands: 40 | - cmd: ansible-playbook 41 | args: 42 | - -i, 43 | - playbook.yml 44 | - cmd: bash 45 | args: 46 | - -c 47 | - who | grep tty 48 | ``` 49 | 50 | ## Env Vars 51 | 52 | The config file can be overriden/defined through env vars. 53 | 54 | ```bash 55 | GILT_GILTFILE=Giltfile.yaml \ 56 | GILT_GILTDIR=~/.gilt/clone \ 57 | GILT_DEBUG=false \ 58 | gilt overlay 59 | ``` 60 | 61 | ## Command Flags 62 | 63 | The config file and/or env vars can be overriden/defined through cli flags. 64 | 65 | ```bash 66 | gilt \ 67 | --gilt-file=Giltfile.yaml \ 68 | --gilt-dir=~/.gilt/clone \ 69 | --debug \ 70 | overlay 71 | ``` 72 | 73 | 74 | [Viper]: https://github.com/spf13/viper 75 | 76 | -------------------------------------------------------------------------------- /docs/versioned_docs/version-2.1.1/contributing.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 6 3 | --- 4 | 5 | # Contributing 6 | 7 | Contributions to Gilt are very welcome, but we ask that you read this document 8 | before submitting a PR. 9 | 10 | :::note 11 | 12 | This document applies to the [Gilt][] repository. 13 | 14 | ::: 15 | 16 | ## Before you start 17 | 18 | - **Check existing work** - Is there an existing PR? Are there issues discussing 19 | the feature/change you want to make? Please make sure you consider/address 20 | these discussions in your work. 21 | - **Backwards compatibility** - Will your change break existing Giltfiles? It is 22 | much more likely that your change will merged if it backwards compatible. Is 23 | there an approach you can take that maintains this compatibility? If not, 24 | consider opening an issue first so that API changes can be discussed before 25 | you invest your time into a PR. 26 | 27 | ## 1. Setup 28 | 29 | - **Go** - Gilt is written in [Go][]. We always support the latest two major Go 30 | versions, so make sure your version is recent enough. 31 | - **Node.js** - [Node.js][] is used to host Gilt's documentation server and is 32 | required if you want to run this server locally. 33 | 34 | ## 2. Making changes 35 | 36 | - **Code style** - Try to maintain the existing code style where possible. Go 37 | code should be formatted by [`gofumpt`][gofumpt] and linted using 38 | [`golangci-lint`][golangci-lint]. Any Markdown or TypeScript files should be 39 | formatted and linted by [Prettier][]. This style is enforced by our CI to 40 | ensure that we have a consistent style across the project. You can use the 41 | `task fmt:check` command to lint the code locally and the `task fmt` command 42 | to automatically fix any issues that are found. 43 | - **Documentation** - Ensure that you add/update any relevant documentation. See 44 | the [updating documentation](#updating-documentation) section below. 45 | - **Tests** - Ensure that you add/update any relevant tests and that all tests 46 | are passing before submitting the PR. See the [writing tests](#writing-tests) 47 | section below. 48 | 49 | ### Running your changes 50 | 51 | To run Gilt with working changes, you can use `go run main.go overlay`. 52 | 53 | ### Updating documentation 54 | 55 | Gilt uses [Docusaurus][] to host a documentation server. The code for this is 56 | located in the Gilt repository. This can be setup and run locally by using 57 | `task docs:start` (requires `nodejs` & `yarn`). All content is written in 58 | Markdown and is located in the `docs/docs` directory. All Markdown documents 59 | should have an 80 character line wrap limit (enforced by Prettier). 60 | 61 | ### Writing tests 62 | 63 | When making a changes, consider whether new tests are required. These tests 64 | should ensure that the functionality you are adding will continue to work in the 65 | future. Existing tests may also need updating if you have changed Gilt's 66 | behavior. 67 | 68 | You may also consider adding unit tests for any new functions you have added. 69 | The unit tests should follow the Go convention of being location in a file named 70 | `*_test.go` in the same package as the code being tested. 71 | 72 | Integration tests are located in the `tests` directory and executed by [Bats][]. 73 | 74 | ## 3. Committing your code 75 | 76 | Try to write meaningful commit messages and avoid having too many commits on the 77 | PR. Most PRs should likely have a single commit (although for bigger PRs it may 78 | be reasonable to split it in a few). Git squash and rebase is your friend! 79 | 80 | If you're not sure how to format your commit message, check out [Conventional 81 | Commits][]. This style is enforced, and is a good way to make your commit 82 | messages more readable and consistent. 83 | 84 | ## 4. Submitting a PR 85 | 86 | - **Describe your changes** - Ensure that you provide a comprehensive 87 | description of your changes. 88 | - **Issue/PR links** - Link any previous work such as related issues or PRs. 89 | Please describe how your changes differ to/extend this work. 90 | - **Examples** - Add any examples or screenshots that you think are useful to 91 | demonstrate the effect of your changes. 92 | - **Draft PRs** - If your changes are incomplete, but you would like to discuss 93 | them, open the PR as a draft and add a comment to start a discussion. Using 94 | comments rather than the PR description allows the description to be updated 95 | later while preserving any discussions. 96 | 97 | ## FAQ 98 | 99 | > I want to contribute, where do I start? 100 | 101 | All kinds of contributions are welcome, whether its a typo fix or a shiny new 102 | feature. You can also contribute by upvoting/commenting on issues or helping to 103 | answer questions. 104 | 105 | > I'm stuck, where can I get help? 106 | 107 | If you have questions, feel free open a [Discussion][] on GitHub. 108 | 109 | 110 | [Gilt]: https://github.com/retr0h/gilt 111 | [Go]: https://go.dev 112 | [Node.js]: https://nodejs.org/en/ 113 | [gofumpt]: https://github.com/mvdan/gofumpt 114 | [golangci-lint]: https://golangci-lint.run 115 | [Prettier]: https://prettier.io/ 116 | [Docusaurus]: https://docusaurus.io 117 | [Discussion]: https://github.com/retr0h/gilt/discussions 118 | [Conventional Commits]: https://www.conventionalcommits.org 119 | [Bats]: https://github.com/bats-core/bats-core 120 | 121 | -------------------------------------------------------------------------------- /docs/versioned_docs/version-2.1.1/installation.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 2 3 | --- 4 | 5 | # Installation 6 | 7 | ## Homebrew Tap 8 | 9 | ```bash 10 | brew install retr0h/tap/gilt 11 | ``` 12 | 13 | ## Go Install 14 | 15 | ```bash 16 | go install github.com/retr0h/gilt@latest 17 | ``` 18 | 19 | ## Python 20 | 21 | ```bash 22 | pip3 install python-gilt 23 | ``` 24 | -------------------------------------------------------------------------------- /docs/versioned_docs/version-2.1.1/intro.md: -------------------------------------------------------------------------------- 1 | --- 2 | slug: / 3 | sidebar_position: 1 4 | title: Home 5 | --- 6 | 7 | # Gilt 8 | 9 | 10 | 11 | Gilt is a tool which aims to make repo management, manageable. Gilt clones 12 | repositories at a particular version, then overlays the repository to the 13 | provided destination. An alternate approach to "vendoring". 14 | 15 | What makes Gilt interesting, is the ability to overlay particular files and/or 16 | directories from the specified repository to given destinations. Originally, 17 | this was quite helpful for those using Ansible, since libraries, plugins, and 18 | playbooks are often shared, but Ansible's [Galaxy][] has no mechanism to handle 19 | this. Currently, this is proving useful for overlaying [Helm charts][]. 20 | 21 |
22 | 23 | ## Alternatives 24 | 25 | - [Repo][] 26 | - [Git submodules][] 27 | - [Git subtree][] 28 | 29 | ## History 30 | 31 | This project is a golang port of [Gilt][py-gilt], and aims to correct poor 32 | decisions made in the python version, primarially around config syntax, 33 | portability, and reproducibility. 34 | 35 | 36 | [Galaxy]: https://docs.ansible.com/ansible/latest/reference_appendices/galaxy.html 37 | [Helm charts]: https://helm.sh/docs/topics/charts/ 38 | [Repo]: https://gerrit.googlesource.com/git-repo/+/refs/heads/master/README.md 39 | [Git submodules]: https://git-scm.com/book/en/v2/Git-Tools-Submodules 40 | [Git subtree]: https://github.com/git/git/blob/master/contrib/subtree/git-subtree.txt 41 | [py-gilt]: http://gilt.readthedocs.io/en/latest/ 42 | 43 | -------------------------------------------------------------------------------- /docs/versioned_docs/version-2.1.1/testing.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 5 3 | --- 4 | 5 | # Testing 6 | 7 | Check installed dependencies: 8 | 9 | ```bash 10 | task deps:check 11 | ``` 12 | 13 | To execute tests: 14 | 15 | ```bash 16 | task test 17 | ``` 18 | 19 | Auto format code: 20 | 21 | ```bash 22 | task fmt 23 | ``` 24 | 25 | List helpful targets: 26 | 27 | ```bash 28 | task 29 | ``` 30 | -------------------------------------------------------------------------------- /docs/versioned_docs/version-2.1.1/usage.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 4 3 | --- 4 | 5 | # Usage 6 | 7 | ## CLI 8 | 9 | ### Init Configuration 10 | 11 | Initializes config file in the shell's current working directory: 12 | 13 | ```bash 14 | gilt init 15 | ``` 16 | 17 | ### Overlay Repository 18 | 19 | Overlay a remote repository into the destination provided. 20 | 21 | ```bash 22 | gilt overlay 23 | ``` 24 | 25 | ### Debug 26 | 27 | Display the git commands being executed. 28 | 29 | ```bash 30 | gilt --debug overlay 31 | ``` 32 | 33 | ## Package 34 | 35 | ### Overlay Repository 36 | 37 | See example client in `examples/go-client/`. 38 | 39 | ```go 40 | func main() { 41 | debug := true 42 | logger := getLogger(debug) 43 | 44 | c := config.Repositories{ 45 | Debug: debug, 46 | GiltDir: "~/.gilt", 47 | Repositories: []config.Repository{ 48 | { 49 | Git: "https://github.com/retr0h/ansible-etcd.git", 50 | Version: "77a95b7", 51 | DstDir: "../tmp/retr0h.ansible-etcd", 52 | }, 53 | }, 54 | } 55 | 56 | var r repositoriesManager = repositories.New(c, logger) 57 | r.Overlay() 58 | } 59 | ``` 60 | -------------------------------------------------------------------------------- /docs/versioned_docs/version-2.1.2/configuration.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 3 3 | --- 4 | 5 | # Configuration 6 | 7 | Gilt uses [Viper][] to load configuation through multiple methods. 8 | 9 | ## Config File 10 | 11 | Create the giltfile (`Giltfile.yaml`). 12 | 13 | Clone the specified `url`@`version` to the configurable path `--gilt-dir`. 14 | Extract the repo the `dstDir` when `dstDir` is provided. Otherwise, copy files 15 | and/or directories to the desired destinations. 16 | 17 | ```yaml 18 | --- 19 | giltDir: ~/.gilt/clone 20 | debug: false 21 | repositories: 22 | - git: https://github.com/retr0h/ansible-etcd.git 23 | version: 77a95b7 24 | dstDir: roles/retr0h.ansible-etcd 25 | - git: https://github.com/retr0h/ansible-etcd.git 26 | version: 1.1 27 | dstDir: roles/retr0h.ansible-etcd-tag 28 | - git: https://github.com/lorin/openstack-ansible-modules.git 29 | version: 2677cc3 30 | sources: 31 | - src: '*_manage' 32 | dstDir: library 33 | - src: nova_quota 34 | dstDir: library 35 | - src: neutron_router 36 | dstFile: library/neutron_router.py 37 | - src: tests 38 | dstDir: tests 39 | commands: 40 | - cmd: ansible-playbook 41 | args: 42 | - -i, 43 | - playbook.yml 44 | - cmd: bash 45 | args: 46 | - -c 47 | - who | grep tty 48 | ``` 49 | 50 | ## Env Vars 51 | 52 | The config file can be overriden/defined through env vars. 53 | 54 | ```bash 55 | GILT_GILTFILE=Giltfile.yaml \ 56 | GILT_GILTDIR=~/.gilt/clone \ 57 | GILT_DEBUG=false \ 58 | gilt overlay 59 | ``` 60 | 61 | ## Command Flags 62 | 63 | The config file and/or env vars can be overriden/defined through cli flags. 64 | 65 | ```bash 66 | gilt \ 67 | --gilt-file=Giltfile.yaml \ 68 | --gilt-dir=~/.gilt/clone \ 69 | --debug \ 70 | overlay 71 | ``` 72 | 73 | 74 | [Viper]: https://github.com/spf13/viper 75 | 76 | -------------------------------------------------------------------------------- /docs/versioned_docs/version-2.1.2/contributing.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 6 3 | --- 4 | 5 | # Contributing 6 | 7 | Contributions to Gilt are very welcome, but we ask that you read this document 8 | before submitting a PR. 9 | 10 | :::note 11 | 12 | This document applies to the [Gilt][] repository. 13 | 14 | ::: 15 | 16 | ## Before you start 17 | 18 | - **Check existing work** - Is there an existing PR? Are there issues discussing 19 | the feature/change you want to make? Please make sure you consider/address 20 | these discussions in your work. 21 | - **Backwards compatibility** - Will your change break existing Giltfiles? It is 22 | much more likely that your change will merged if it backwards compatible. Is 23 | there an approach you can take that maintains this compatibility? If not, 24 | consider opening an issue first so that API changes can be discussed before 25 | you invest your time into a PR. 26 | 27 | ## 1. Setup 28 | 29 | - **Go** - Gilt is written in [Go][]. We always support the latest two major Go 30 | versions, so make sure your version is recent enough. 31 | - **Node.js** - [Node.js][] is used to host Gilt's documentation server and is 32 | required if you want to run this server locally. 33 | 34 | ## 2. Making changes 35 | 36 | - **Code style** - Try to maintain the existing code style where possible. Go 37 | code should be formatted by [`gofumpt`][gofumpt] and linted using 38 | [`golangci-lint`][golangci-lint]. Any Markdown or TypeScript files should be 39 | formatted and linted by [Prettier][]. This style is enforced by our CI to 40 | ensure that we have a consistent style across the project. You can use the 41 | `task fmt:check` command to lint the code locally and the `task fmt` command 42 | to automatically fix any issues that are found. 43 | - **Documentation** - Ensure that you add/update any relevant documentation. See 44 | the [updating documentation](#updating-documentation) section below. 45 | - **Tests** - Ensure that you add/update any relevant tests and that all tests 46 | are passing before submitting the PR. See the [writing tests](#writing-tests) 47 | section below. 48 | 49 | ### Running your changes 50 | 51 | To run Gilt with working changes, you can use `go run main.go overlay`. 52 | 53 | ### Updating documentation 54 | 55 | Gilt uses [Docusaurus][] to host a documentation server. The code for this is 56 | located in the Gilt repository. This can be setup and run locally by using 57 | `task docs:start` (requires `nodejs` & `yarn`). All content is written in 58 | Markdown and is located in the `docs/docs` directory. All Markdown documents 59 | should have an 80 character line wrap limit (enforced by Prettier). 60 | 61 | ### Writing tests 62 | 63 | When making a changes, consider whether new tests are required. These tests 64 | should ensure that the functionality you are adding will continue to work in the 65 | future. Existing tests may also need updating if you have changed Gilt's 66 | behavior. 67 | 68 | You may also consider adding unit tests for any new functions you have added. 69 | The unit tests should follow the Go convention of being location in a file named 70 | `*_test.go` in the same package as the code being tested. 71 | 72 | Integration tests are located in the `tests` directory and executed by [Bats][]. 73 | 74 | ## 3. Committing your code 75 | 76 | Try to write meaningful commit messages and avoid having too many commits on the 77 | PR. Most PRs should likely have a single commit (although for bigger PRs it may 78 | be reasonable to split it in a few). Git squash and rebase is your friend! 79 | 80 | If you're not sure how to format your commit message, check out [Conventional 81 | Commits][]. This style is enforced, and is a good way to make your commit 82 | messages more readable and consistent. 83 | 84 | ## 4. Submitting a PR 85 | 86 | - **Describe your changes** - Ensure that you provide a comprehensive 87 | description of your changes. 88 | - **Issue/PR links** - Link any previous work such as related issues or PRs. 89 | Please describe how your changes differ to/extend this work. 90 | - **Examples** - Add any examples or screenshots that you think are useful to 91 | demonstrate the effect of your changes. 92 | - **Draft PRs** - If your changes are incomplete, but you would like to discuss 93 | them, open the PR as a draft and add a comment to start a discussion. Using 94 | comments rather than the PR description allows the description to be updated 95 | later while preserving any discussions. 96 | 97 | ## FAQ 98 | 99 | > I want to contribute, where do I start? 100 | 101 | All kinds of contributions are welcome, whether its a typo fix or a shiny new 102 | feature. You can also contribute by upvoting/commenting on issues or helping to 103 | answer questions. 104 | 105 | > I'm stuck, where can I get help? 106 | 107 | If you have questions, feel free open a [Discussion][] on GitHub. 108 | 109 | 110 | [Gilt]: https://github.com/retr0h/gilt 111 | [Go]: https://go.dev 112 | [Node.js]: https://nodejs.org/en/ 113 | [gofumpt]: https://github.com/mvdan/gofumpt 114 | [golangci-lint]: https://golangci-lint.run 115 | [Prettier]: https://prettier.io/ 116 | [Docusaurus]: https://docusaurus.io 117 | [Discussion]: https://github.com/retr0h/gilt/discussions 118 | [Conventional Commits]: https://www.conventionalcommits.org 119 | [Bats]: https://github.com/bats-core/bats-core 120 | 121 | -------------------------------------------------------------------------------- /docs/versioned_docs/version-2.1.2/installation.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 2 3 | --- 4 | 5 | # Installation 6 | 7 | ## Homebrew Tap 8 | 9 | ```bash 10 | brew install retr0h/tap/gilt 11 | ``` 12 | 13 | ## Go Install 14 | 15 | ```bash 16 | go install github.com/retr0h/gilt/v2@latest 17 | ``` 18 | 19 | ## Python 20 | 21 | ```bash 22 | pip3 install python-gilt 23 | ``` 24 | -------------------------------------------------------------------------------- /docs/versioned_docs/version-2.1.2/intro.md: -------------------------------------------------------------------------------- 1 | --- 2 | slug: / 3 | sidebar_position: 1 4 | title: Home 5 | --- 6 | 7 | # Gilt 8 | 9 | 10 | 11 | Gilt is a tool which aims to make repo management, manageable. Gilt clones 12 | repositories at a particular version, then overlays the repository to the 13 | provided destination. An alternate approach to "vendoring". 14 | 15 | What makes Gilt interesting, is the ability to overlay particular files and/or 16 | directories from the specified repository to given destinations. Originally, 17 | this was quite helpful for those using Ansible, since libraries, plugins, and 18 | playbooks are often shared, but Ansible's [Galaxy][] has no mechanism to handle 19 | this. Currently, this is proving useful for overlaying [Helm charts][]. 20 | 21 |
22 | 23 | ## Alternatives 24 | 25 | - [Repo][] 26 | - [Git submodules][] 27 | - [Git subtree][] 28 | 29 | ## History 30 | 31 | This project is a golang port of [Gilt][py-gilt], and aims to correct poor 32 | decisions made in the python version, primarially around config syntax, 33 | portability, and reproducibility. 34 | 35 | 36 | [Galaxy]: https://docs.ansible.com/ansible/latest/reference_appendices/galaxy.html 37 | [Helm charts]: https://helm.sh/docs/topics/charts/ 38 | [Repo]: https://gerrit.googlesource.com/git-repo/+/refs/heads/master/README.md 39 | [Git submodules]: https://git-scm.com/book/en/v2/Git-Tools-Submodules 40 | [Git subtree]: https://github.com/git/git/blob/master/contrib/subtree/git-subtree.txt 41 | [py-gilt]: http://gilt.readthedocs.io/en/latest/ 42 | 43 | -------------------------------------------------------------------------------- /docs/versioned_docs/version-2.1.2/testing.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 5 3 | --- 4 | 5 | # Testing 6 | 7 | Check installed dependencies: 8 | 9 | ```bash 10 | task deps:check 11 | ``` 12 | 13 | To execute tests: 14 | 15 | ```bash 16 | task test 17 | ``` 18 | 19 | Auto format code: 20 | 21 | ```bash 22 | task fmt 23 | ``` 24 | 25 | List helpful targets: 26 | 27 | ```bash 28 | task 29 | ``` 30 | -------------------------------------------------------------------------------- /docs/versioned_docs/version-2.1.2/usage.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 4 3 | --- 4 | 5 | # Usage 6 | 7 | ## CLI 8 | 9 | ### Init Configuration 10 | 11 | Initializes config file in the shell's current working directory: 12 | 13 | ```bash 14 | gilt init 15 | ``` 16 | 17 | ### Overlay Repository 18 | 19 | Overlay a remote repository into the destination provided. 20 | 21 | ```bash 22 | gilt overlay 23 | ``` 24 | 25 | ### Debug 26 | 27 | Display the git commands being executed. 28 | 29 | ```bash 30 | gilt --debug overlay 31 | ``` 32 | 33 | ## Package 34 | 35 | ### Overlay Repository 36 | 37 | See example client in `examples/go-client/`. 38 | 39 | ```go 40 | func main() { 41 | debug := true 42 | logger := getLogger(debug) 43 | 44 | c := config.Repositories{ 45 | Debug: debug, 46 | GiltDir: "~/.gilt", 47 | Repositories: []config.Repository{ 48 | { 49 | Git: "https://github.com/retr0h/ansible-etcd.git", 50 | Version: "77a95b7", 51 | DstDir: "../tmp/retr0h.ansible-etcd", 52 | }, 53 | }, 54 | } 55 | 56 | var r repositoriesManager = repositories.New(c, logger) 57 | r.Overlay() 58 | } 59 | ``` 60 | -------------------------------------------------------------------------------- /docs/versioned_docs/version-2.2.1/configuration.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 3 3 | --- 4 | 5 | # Configuration 6 | 7 | Gilt uses [Viper][] to load configuation through multiple methods. 8 | 9 | ## Config File 10 | 11 | Create the giltfile (`Giltfile.yaml`). 12 | 13 | Clone the specified `url`@`version` to the configurable path `--gilt-dir`. 14 | Extract the repo the `dstDir` when `dstDir` is provided. Otherwise, copy files 15 | and/or directories to the desired destinations. 16 | 17 | ```yaml 18 | --- 19 | giltDir: ~/.gilt/clone 20 | debug: false 21 | parallel: true 22 | repositories: 23 | - git: https://github.com/retr0h/ansible-etcd.git 24 | version: 77a95b7 25 | dstDir: roles/retr0h.ansible-etcd 26 | - git: https://github.com/retr0h/ansible-etcd.git 27 | version: 1.1 28 | dstDir: roles/retr0h.ansible-etcd-tag 29 | - git: https://github.com/lorin/openstack-ansible-modules.git 30 | version: 2677cc3 31 | sources: 32 | - src: '*_manage' 33 | dstDir: library 34 | - src: nova_quota 35 | dstDir: library 36 | - src: neutron_router 37 | dstFile: library/neutron_router.py 38 | - src: tests 39 | dstDir: tests 40 | commands: 41 | - cmd: ansible-playbook 42 | args: 43 | - -i, 44 | - playbook.yml 45 | - cmd: bash 46 | args: 47 | - -c 48 | - who | grep tty 49 | ``` 50 | 51 | ## Env Vars 52 | 53 | The config file can be overriden/defined through env vars. 54 | 55 | ```bash 56 | GILT_GILTFILE=Giltfile.yaml \ 57 | GILT_GILTDIR=~/.gilt/clone \ 58 | GILT_DEBUG=false \ 59 | GILT_PARALLEL=false \ 60 | gilt overlay 61 | ``` 62 | 63 | ## Command Flags 64 | 65 | The config file and/or env vars can be overriden/defined through cli flags. 66 | 67 | ```bash 68 | gilt \ 69 | --gilt-file=Giltfile.yaml \ 70 | --gilt-dir=~/.gilt/clone \ 71 | --debug \ 72 | --parallel=false \ 73 | overlay 74 | ``` 75 | 76 | 77 | [Viper]: https://github.com/spf13/viper 78 | 79 | -------------------------------------------------------------------------------- /docs/versioned_docs/version-2.2.1/contributing.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 6 3 | --- 4 | 5 | # Contributing 6 | 7 | Contributions to Gilt are very welcome, but we ask that you read this document 8 | before submitting a PR. 9 | 10 | :::note 11 | 12 | This document applies to the [Gilt][] repository. 13 | 14 | ::: 15 | 16 | ## Before you start 17 | 18 | - **Check existing work** - Is there an existing PR? Are there issues discussing 19 | the feature/change you want to make? Please make sure you consider/address 20 | these discussions in your work. 21 | - **Backwards compatibility** - Will your change break existing Giltfiles? It is 22 | much more likely that your change will merged if it backwards compatible. Is 23 | there an approach you can take that maintains this compatibility? If not, 24 | consider opening an issue first so that API changes can be discussed before 25 | you invest your time into a PR. 26 | 27 | ## 1. Setup 28 | 29 | - **Go** - Gilt is written in [Go][]. We always support the latest two major Go 30 | versions, so make sure your version is recent enough. 31 | - **Node.js** - [Node.js][] is used to host Gilt's documentation server and is 32 | required if you want to run this server locally. 33 | 34 | ## 2. Making changes 35 | 36 | - **Code style** - Try to maintain the existing code style where possible. Go 37 | code should be formatted by [`gofumpt`][gofumpt] and linted using 38 | [`golangci-lint`][golangci-lint]. Any Markdown or TypeScript files should be 39 | formatted and linted by [Prettier][]. This style is enforced by our CI to 40 | ensure that we have a consistent style across the project. You can use the 41 | `task fmt:check` command to lint the code locally and the `task fmt` command 42 | to automatically fix any issues that are found. 43 | - **Documentation** - Ensure that you add/update any relevant documentation. See 44 | the [updating documentation](#updating-documentation) section below. 45 | - **Tests** - Ensure that you add/update any relevant tests and that all tests 46 | are passing before submitting the PR. See the [writing tests](#writing-tests) 47 | section below. 48 | 49 | ### Running your changes 50 | 51 | To run Gilt with working changes, you can use `go run main.go overlay`. 52 | 53 | ### Updating documentation 54 | 55 | Gilt uses [Docusaurus][] to host a documentation server. The code for this is 56 | located in the Gilt repository. This can be setup and run locally by using 57 | `task docs:start` (requires `nodejs` & `yarn`). All content is written in 58 | Markdown and is located in the `docs/docs` directory. All Markdown documents 59 | should have an 80 character line wrap limit (enforced by Prettier). 60 | 61 | ### Writing tests 62 | 63 | When making a changes, consider whether new tests are required. These tests 64 | should ensure that the functionality you are adding will continue to work in the 65 | future. Existing tests may also need updating if you have changed Gilt's 66 | behavior. 67 | 68 | You may also consider adding unit tests for any new functions you have added. 69 | The unit tests should follow the Go convention of being location in a file named 70 | `*_test.go` in the same package as the code being tested. 71 | 72 | Integration tests are located in the `tests` directory and executed by [Bats][]. 73 | 74 | ## 3. Committing your code 75 | 76 | Try to write meaningful commit messages and avoid having too many commits on the 77 | PR. Most PRs should likely have a single commit (although for bigger PRs it may 78 | be reasonable to split it in a few). Git squash and rebase is your friend! 79 | 80 | If you're not sure how to format your commit message, check out [Conventional 81 | Commits][]. This style is enforced, and is a good way to make your commit 82 | messages more readable and consistent. 83 | 84 | ## 4. Submitting a PR 85 | 86 | - **Describe your changes** - Ensure that you provide a comprehensive 87 | description of your changes. 88 | - **Issue/PR links** - Link any previous work such as related issues or PRs. 89 | Please describe how your changes differ to/extend this work. 90 | - **Examples** - Add any examples or screenshots that you think are useful to 91 | demonstrate the effect of your changes. 92 | - **Draft PRs** - If your changes are incomplete, but you would like to discuss 93 | them, open the PR as a draft and add a comment to start a discussion. Using 94 | comments rather than the PR description allows the description to be updated 95 | later while preserving any discussions. 96 | 97 | ## FAQ 98 | 99 | > I want to contribute, where do I start? 100 | 101 | All kinds of contributions are welcome, whether its a typo fix or a shiny new 102 | feature. You can also contribute by upvoting/commenting on issues or helping to 103 | answer questions. 104 | 105 | > I'm stuck, where can I get help? 106 | 107 | If you have questions, feel free open a [Discussion][] on GitHub. 108 | 109 | 110 | [Gilt]: https://github.com/retr0h/gilt 111 | [Go]: https://go.dev 112 | [Node.js]: https://nodejs.org/en/ 113 | [gofumpt]: https://github.com/mvdan/gofumpt 114 | [golangci-lint]: https://golangci-lint.run 115 | [Prettier]: https://prettier.io/ 116 | [Docusaurus]: https://docusaurus.io 117 | [Discussion]: https://github.com/retr0h/gilt/discussions 118 | [Conventional Commits]: https://www.conventionalcommits.org 119 | [Bats]: https://github.com/bats-core/bats-core 120 | 121 | -------------------------------------------------------------------------------- /docs/versioned_docs/version-2.2.1/installation.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 2 3 | --- 4 | 5 | # Installation 6 | 7 | ## Homebrew Tap 8 | 9 | ```bash 10 | brew install retr0h/tap/gilt 11 | ``` 12 | 13 | ## Go Install 14 | 15 | ```bash 16 | go install github.com/retr0h/gilt/v2@latest 17 | ``` 18 | 19 | ## Python 20 | 21 | ```bash 22 | pip3 install python-gilt 23 | ``` 24 | -------------------------------------------------------------------------------- /docs/versioned_docs/version-2.2.1/intro.md: -------------------------------------------------------------------------------- 1 | --- 2 | slug: / 3 | sidebar_position: 1 4 | title: Home 5 | --- 6 | 7 | # Gilt 8 | 9 | 10 | 11 | Gilt is a tool which aims to make repo management, manageable. Gilt clones 12 | repositories at a particular version, then overlays the repository to the 13 | provided destination. An alternate approach to "vendoring". 14 | 15 | What makes Gilt interesting, is the ability to overlay particular files and/or 16 | directories from the specified repository to given destinations. Originally, 17 | this was quite helpful for those using Ansible, since libraries, plugins, and 18 | playbooks are often shared, but Ansible's [Galaxy][] has no mechanism to handle 19 | this. Currently, this is proving useful for overlaying [Helm charts][]. 20 | 21 |
22 | 23 | ## Alternatives 24 | 25 | - [Repo][] 26 | - [Git submodules][] 27 | - [Git subtree][] 28 | 29 | ## History 30 | 31 | This project is a golang port of [Gilt][py-gilt], and aims to correct poor 32 | decisions made in the python version, primarially around config syntax, 33 | portability, and reproducibility. 34 | 35 | 36 | [Galaxy]: https://docs.ansible.com/ansible/latest/reference_appendices/galaxy.html 37 | [Helm charts]: https://helm.sh/docs/topics/charts/ 38 | [Repo]: https://gerrit.googlesource.com/git-repo/+/refs/heads/master/README.md 39 | [Git submodules]: https://git-scm.com/book/en/v2/Git-Tools-Submodules 40 | [Git subtree]: https://github.com/git/git/blob/master/contrib/subtree/git-subtree.txt 41 | [py-gilt]: http://gilt.readthedocs.io/en/latest/ 42 | 43 | -------------------------------------------------------------------------------- /docs/versioned_docs/version-2.2.1/testing.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 5 3 | --- 4 | 5 | # Testing 6 | 7 | Check installed dependencies: 8 | 9 | ```bash 10 | task deps:check 11 | ``` 12 | 13 | To execute tests: 14 | 15 | ```bash 16 | task test 17 | ``` 18 | 19 | Auto format code: 20 | 21 | ```bash 22 | task fmt 23 | ``` 24 | 25 | List helpful targets: 26 | 27 | ```bash 28 | task 29 | ``` 30 | -------------------------------------------------------------------------------- /docs/versioned_docs/version-2.2.1/usage.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 4 3 | --- 4 | 5 | # Usage 6 | 7 | ## CLI 8 | 9 | ### Init Configuration 10 | 11 | Initializes config file in the shell's current working directory: 12 | 13 | ```bash 14 | gilt init 15 | ``` 16 | 17 | ### Overlay Repository 18 | 19 | Overlay a remote repository into the destination provided. 20 | 21 | ```bash 22 | gilt overlay 23 | ``` 24 | 25 | ### Debug 26 | 27 | Display the git commands being executed. 28 | 29 | ```bash 30 | gilt --debug overlay 31 | ``` 32 | 33 | ## Package 34 | 35 | ### Overlay Repository 36 | 37 | See example client in `examples/go-client/`. 38 | 39 | ```go 40 | func main() { 41 | debug := true 42 | logger := getLogger(debug) 43 | 44 | c := config.Repositories{ 45 | Debug: debug, 46 | GiltDir: "~/.gilt", 47 | Repositories: []config.Repository{ 48 | { 49 | Git: "https://github.com/retr0h/ansible-etcd.git", 50 | Version: "77a95b7", 51 | DstDir: "../tmp/retr0h.ansible-etcd", 52 | }, 53 | }, 54 | } 55 | 56 | var r repositoriesManager = repositories.New(c, logger) 57 | r.Overlay() 58 | } 59 | ``` 60 | -------------------------------------------------------------------------------- /docs/versioned_docs/version-2.2.2/configuration.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 3 3 | --- 4 | 5 | # Configuration 6 | 7 | Gilt uses [Viper][] to load configuation through multiple methods. 8 | 9 | ## Config File 10 | 11 | Create the giltfile (`Giltfile.yaml`). 12 | 13 | Clone the specified `url`@`version` to the configurable path `--gilt-dir`. 14 | Extract the repo the `dstDir` when `dstDir` is provided. Otherwise, copy files 15 | and/or directories to the desired destinations. 16 | 17 | ```yaml 18 | --- 19 | giltDir: ~/.gilt/clone 20 | debug: false 21 | parallel: true 22 | repositories: 23 | - git: https://github.com/retr0h/ansible-etcd.git 24 | version: 77a95b7 25 | dstDir: roles/retr0h.ansible-etcd 26 | - git: https://github.com/retr0h/ansible-etcd.git 27 | version: 1.1 28 | dstDir: roles/retr0h.ansible-etcd-tag 29 | - git: https://github.com/lorin/openstack-ansible-modules.git 30 | version: 2677cc3 31 | sources: 32 | - src: '*_manage' 33 | dstDir: library 34 | - src: nova_quota 35 | dstDir: library 36 | - src: neutron_router 37 | dstFile: library/neutron_router.py 38 | - src: tests 39 | dstDir: tests 40 | commands: 41 | - cmd: ansible-playbook 42 | args: 43 | - -i, 44 | - playbook.yml 45 | - cmd: bash 46 | args: 47 | - -c 48 | - who | grep tty 49 | ``` 50 | 51 | ## Env Vars 52 | 53 | The config file can be overriden/defined through env vars. 54 | 55 | ```bash 56 | GILT_GILTFILE=Giltfile.yaml \ 57 | GILT_GILTDIR=~/.gilt/clone \ 58 | GILT_DEBUG=false \ 59 | GILT_PARALLEL=false \ 60 | gilt overlay 61 | ``` 62 | 63 | ## Command Flags 64 | 65 | The config file and/or env vars can be overriden/defined through cli flags. 66 | 67 | ```bash 68 | gilt \ 69 | --gilt-file=Giltfile.yaml \ 70 | --gilt-dir=~/.gilt/clone \ 71 | --debug \ 72 | --parallel=false \ 73 | overlay 74 | ``` 75 | 76 | 77 | [Viper]: https://github.com/spf13/viper 78 | 79 | -------------------------------------------------------------------------------- /docs/versioned_docs/version-2.2.2/contributing.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 6 3 | --- 4 | 5 | # Contributing 6 | 7 | Contributions to Gilt are very welcome, but we ask that you read this document 8 | before submitting a PR. 9 | 10 | :::note 11 | 12 | This document applies to the [Gilt][] repository. 13 | 14 | ::: 15 | 16 | ## Before you start 17 | 18 | - **Check existing work** - Is there an existing PR? Are there issues discussing 19 | the feature/change you want to make? Please make sure you consider/address 20 | these discussions in your work. 21 | - **Backwards compatibility** - Will your change break existing Giltfiles? It is 22 | much more likely that your change will merged if it backwards compatible. Is 23 | there an approach you can take that maintains this compatibility? If not, 24 | consider opening an issue first so that API changes can be discussed before 25 | you invest your time into a PR. 26 | 27 | ## 1. Setup 28 | 29 | - **Go** - Gilt is written in [Go][]. We always support the latest two major Go 30 | versions, so make sure your version is recent enough. 31 | - **Node.js** - [Node.js][] is used to host Gilt's documentation server and is 32 | required if you want to run this server locally. 33 | 34 | ## 2. Making changes 35 | 36 | - **Code style** - Try to maintain the existing code style where possible. Go 37 | code should be formatted by [`gofumpt`][gofumpt] and linted using 38 | [`golangci-lint`][golangci-lint]. Any Markdown or TypeScript files should be 39 | formatted and linted by [Prettier][]. This style is enforced by our CI to 40 | ensure that we have a consistent style across the project. You can use the 41 | `task fmt:check` command to lint the code locally and the `task fmt` command 42 | to automatically fix any issues that are found. 43 | - **Documentation** - Ensure that you add/update any relevant documentation. See 44 | the [updating documentation](#updating-documentation) section below. 45 | - **Tests** - Ensure that you add/update any relevant tests and that all tests 46 | are passing before submitting the PR. See the [writing tests](#writing-tests) 47 | section below. 48 | 49 | ### Running your changes 50 | 51 | To run Gilt with working changes, you can use `go run main.go overlay`. 52 | 53 | ### Updating documentation 54 | 55 | Gilt uses [Docusaurus][] to host a documentation server. The code for this is 56 | located in the Gilt repository. This can be setup and run locally by using 57 | `task docs:start` (requires `nodejs` & `yarn`). All content is written in 58 | Markdown and is located in the `docs/docs` directory. All Markdown documents 59 | should have an 80 character line wrap limit (enforced by Prettier). 60 | 61 | ### Writing tests 62 | 63 | When making changes, consider whether new tests are required. These tests should 64 | ensure that the functionality you are adding will continue to work in the 65 | future. Existing tests may also need updating if you have changed Gilt's 66 | behavior. 67 | 68 | You may also consider adding unit tests for any new functions you have added. 69 | The unit tests should follow the Go convention of being location in a file named 70 | `*_test.go` in the same package as the code being tested. 71 | 72 | Integration tests are located in the `tests` directory and executed by [Bats][]. 73 | 74 | ## 3. Committing your code 75 | 76 | Try to write meaningful commit messages and avoid having too many commits on the 77 | PR. Most PRs should likely have a single commit (although for bigger PRs it may 78 | be reasonable to split it in a few). Git squash and rebase is your friend! 79 | 80 | If you're not sure how to format your commit message, check out [Conventional 81 | Commits][]. This style is enforced, and is a good way to make your commit 82 | messages more readable and consistent. 83 | 84 | ## 4. Submitting a PR 85 | 86 | - **Describe your changes** - Ensure that you provide a comprehensive 87 | description of your changes. 88 | - **Issue/PR links** - Link any previous work such as related issues or PRs. 89 | Please describe how your changes differ to/extend this work. 90 | - **Examples** - Add any examples or screenshots that you think are useful to 91 | demonstrate the effect of your changes. 92 | - **Draft PRs** - If your changes are incomplete, but you would like to discuss 93 | them, open the PR as a draft and add a comment to start a discussion. Using 94 | comments rather than the PR description allows the description to be updated 95 | later while preserving any discussions. 96 | 97 | ## FAQ 98 | 99 | > I want to contribute, where do I start? 100 | 101 | All kinds of contributions are welcome, whether its a typo fix or a shiny new 102 | feature. You can also contribute by upvoting/commenting on issues or helping to 103 | answer questions. 104 | 105 | > I'm stuck, where can I get help? 106 | 107 | If you have questions, feel free open a [Discussion][] on GitHub. 108 | 109 | 110 | [Gilt]: https://github.com/retr0h/gilt 111 | [Go]: https://go.dev 112 | [Node.js]: https://nodejs.org/en/ 113 | [gofumpt]: https://github.com/mvdan/gofumpt 114 | [golangci-lint]: https://golangci-lint.run 115 | [Prettier]: https://prettier.io/ 116 | [Docusaurus]: https://docusaurus.io 117 | [Discussion]: https://github.com/retr0h/gilt/discussions 118 | [Conventional Commits]: https://www.conventionalcommits.org 119 | [Bats]: https://github.com/bats-core/bats-core 120 | 121 | -------------------------------------------------------------------------------- /docs/versioned_docs/version-2.2.2/installation.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 2 3 | --- 4 | 5 | # Installation 6 | 7 | ## Homebrew Tap 8 | 9 | ```bash 10 | brew install retr0h/tap/gilt 11 | ``` 12 | 13 | ## Go Install 14 | 15 | ```bash 16 | go install github.com/retr0h/gilt/v2@latest 17 | ``` 18 | 19 | ## Python 20 | 21 | ```bash 22 | pip3 install python-gilt 23 | ``` 24 | -------------------------------------------------------------------------------- /docs/versioned_docs/version-2.2.2/intro.md: -------------------------------------------------------------------------------- 1 | --- 2 | slug: / 3 | sidebar_position: 1 4 | title: Home 5 | --- 6 | 7 | # Gilt 8 | 9 | 10 | 11 | Gilt is a tool which aims to make repo management, manageable. Gilt clones 12 | repositories at a particular version, then overlays the repository to the 13 | provided destination. An alternate approach to "vendoring". 14 | 15 | What makes Gilt interesting, is the ability to overlay particular files and/or 16 | directories from the specified repository to given destinations. Originally, 17 | this was quite helpful for those using Ansible, since libraries, plugins, and 18 | playbooks are often shared, but Ansible's [Galaxy][] has no mechanism to handle 19 | this. Currently, this is proving useful for overlaying [Helm charts][]. 20 | 21 |
22 | 23 | ## Alternatives 24 | 25 | - [Repo][] 26 | - [Git submodules][] 27 | - [Git subtree][] 28 | 29 | ## History 30 | 31 | This project is a golang port of [Gilt][py-gilt], and aims to correct poor 32 | decisions made in the python version, primarially around config syntax, 33 | portability, and reproducibility. 34 | 35 | 36 | [Galaxy]: https://docs.ansible.com/ansible/latest/reference_appendices/galaxy.html 37 | [Helm charts]: https://helm.sh/docs/topics/charts/ 38 | [Repo]: https://gerrit.googlesource.com/git-repo/+/refs/heads/master/README.md 39 | [Git submodules]: https://git-scm.com/book/en/v2/Git-Tools-Submodules 40 | [Git subtree]: https://github.com/git/git/blob/master/contrib/subtree/git-subtree.txt 41 | [py-gilt]: http://gilt.readthedocs.io/en/latest/ 42 | 43 | -------------------------------------------------------------------------------- /docs/versioned_docs/version-2.2.2/testing.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 5 3 | --- 4 | 5 | # Testing 6 | 7 | Check installed dependencies: 8 | 9 | ```bash 10 | task deps:check 11 | ``` 12 | 13 | To execute tests: 14 | 15 | ```bash 16 | task test 17 | ``` 18 | 19 | Auto format code: 20 | 21 | ```bash 22 | task fmt 23 | ``` 24 | 25 | List helpful targets: 26 | 27 | ```bash 28 | task 29 | ``` 30 | -------------------------------------------------------------------------------- /docs/versioned_docs/version-2.2.2/usage.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 4 3 | --- 4 | 5 | # Usage 6 | 7 | ## CLI 8 | 9 | ### Init Configuration 10 | 11 | Initializes config file in the shell's current working directory: 12 | 13 | ```bash 14 | gilt init 15 | ``` 16 | 17 | ### Overlay Repository 18 | 19 | Overlay a remote repository into the destination provided. 20 | 21 | ```bash 22 | gilt overlay 23 | ``` 24 | 25 | ### Debug 26 | 27 | Display the git commands being executed. 28 | 29 | ```bash 30 | gilt --debug overlay 31 | ``` 32 | 33 | ### Skipping post-commands 34 | 35 | Overlay files only, but run no other commands. 36 | 37 | ```bash 38 | gilt overlay --no-commands 39 | ``` 40 | 41 | ## Package 42 | 43 | ### Overlay Repository 44 | 45 | See example client in `examples/go-client/`. 46 | 47 | ```go 48 | func main() { 49 | debug := true 50 | logger := getLogger(debug) 51 | 52 | c := config.Repositories{ 53 | Debug: debug, 54 | GiltDir: "~/.gilt", 55 | Repositories: []config.Repository{ 56 | { 57 | Git: "https://github.com/retr0h/ansible-etcd.git", 58 | Version: "77a95b7", 59 | DstDir: "../tmp/retr0h.ansible-etcd", 60 | }, 61 | }, 62 | } 63 | 64 | var r repositoriesManager = repositories.New(c, logger) 65 | r.Overlay() 66 | } 67 | ``` 68 | -------------------------------------------------------------------------------- /docs/versioned_docs/version-2.2.3/contributing.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 6 3 | --- 4 | 5 | # Contributing 6 | 7 | Contributions to Gilt are very welcome, but we ask that you read this document 8 | before submitting a PR. 9 | 10 | :::note 11 | 12 | This document applies to the [Gilt][] repository. 13 | 14 | ::: 15 | 16 | ## Before you start 17 | 18 | - **Check existing work** - Is there an existing PR? Are there issues discussing 19 | the feature/change you want to make? Please make sure you consider/address 20 | these discussions in your work. 21 | - **Backwards compatibility** - Will your change break existing Giltfiles? It is 22 | much more likely that your change will merged if it backwards compatible. Is 23 | there an approach you can take that maintains this compatibility? If not, 24 | consider opening an issue first so that API changes can be discussed before 25 | you invest your time into a PR. 26 | 27 | ## 1. Setup 28 | 29 | - **Go** - Gilt is written in [Go][]. We always support the latest two major Go 30 | versions, so make sure your version is recent enough. 31 | - **Node.js** - [Node.js][] is used to host Gilt's documentation server and is 32 | required if you want to run this server locally. 33 | 34 | ## 2. Making changes 35 | 36 | - **Code style** - Try to maintain the existing code style where possible. Go 37 | code should be formatted by [`gofumpt`][gofumpt] and linted using 38 | [`golangci-lint`][golangci-lint]. Any Markdown or TypeScript files should be 39 | formatted and linted by [Prettier][]. This style is enforced by our CI to 40 | ensure that we have a consistent style across the project. You can use the 41 | `task fmt:check` command to lint the code locally and the `task fmt` command 42 | to automatically fix any issues that are found. 43 | - **Documentation** - Ensure that you add/update any relevant documentation. See 44 | the [updating documentation](#updating-documentation) section below. 45 | - **Tests** - Ensure that you add/update any relevant tests and that all tests 46 | are passing before submitting the PR. See the [writing tests](#writing-tests) 47 | section below. 48 | 49 | ### Running your changes 50 | 51 | To run Gilt with working changes, you can use `go run main.go overlay`. 52 | 53 | ### Updating documentation 54 | 55 | Gilt uses [Docusaurus][] to host a documentation server. The code for this is 56 | located in the Gilt repository. This can be setup and run locally by using 57 | `task docs:start` (requires `nodejs` & `yarn`). All content is written in 58 | Markdown and is located in the `docs/docs` directory. All Markdown documents 59 | should have an 80 character line wrap limit (enforced by Prettier). 60 | 61 | ### Writing tests 62 | 63 | When making changes, consider whether new tests are required. These tests should 64 | ensure that the functionality you are adding will continue to work in the 65 | future. Existing tests may also need updating if you have changed Gilt's 66 | behavior. 67 | 68 | You may also consider adding unit tests for any new functions you have added. 69 | The unit tests should follow the Go convention of being location in a file named 70 | `*_test.go` in the same package as the code being tested. 71 | 72 | Integration tests are located in the `tests` directory and executed by [Bats][]. 73 | 74 | ## 3. Committing your code 75 | 76 | Try to write meaningful commit messages and avoid having too many commits on the 77 | PR. Most PRs should likely have a single commit (although for bigger PRs it may 78 | be reasonable to split it in a few). Git squash and rebase is your friend! 79 | 80 | If you're not sure how to format your commit message, check out [Conventional 81 | Commits][]. This style is enforced, and is a good way to make your commit 82 | messages more readable and consistent. 83 | 84 | ## 4. Submitting a PR 85 | 86 | - **Describe your changes** - Ensure that you provide a comprehensive 87 | description of your changes. 88 | - **Issue/PR links** - Link any previous work such as related issues or PRs. 89 | Please describe how your changes differ to/extend this work. 90 | - **Examples** - Add any examples or screenshots that you think are useful to 91 | demonstrate the effect of your changes. 92 | - **Draft PRs** - If your changes are incomplete, but you would like to discuss 93 | them, open the PR as a draft and add a comment to start a discussion. Using 94 | comments rather than the PR description allows the description to be updated 95 | later while preserving any discussions. 96 | 97 | ## FAQ 98 | 99 | > I want to contribute, where do I start? 100 | 101 | All kinds of contributions are welcome, whether its a typo fix or a shiny new 102 | feature. You can also contribute by upvoting/commenting on issues or helping to 103 | answer questions. 104 | 105 | > I'm stuck, where can I get help? 106 | 107 | If you have questions, feel free open a [Discussion][] on GitHub. 108 | 109 | 110 | [Gilt]: https://github.com/retr0h/gilt 111 | [Go]: https://go.dev 112 | [Node.js]: https://nodejs.org/en/ 113 | [gofumpt]: https://github.com/mvdan/gofumpt 114 | [golangci-lint]: https://golangci-lint.run 115 | [Prettier]: https://prettier.io/ 116 | [Docusaurus]: https://docusaurus.io 117 | [Discussion]: https://github.com/retr0h/gilt/discussions 118 | [Conventional Commits]: https://www.conventionalcommits.org 119 | [Bats]: https://github.com/bats-core/bats-core 120 | 121 | -------------------------------------------------------------------------------- /docs/versioned_docs/version-2.2.3/installation.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 2 3 | --- 4 | 5 | # Installation 6 | 7 | ## Homebrew Tap 8 | 9 | ```bash 10 | brew install retr0h/tap/gilt 11 | ``` 12 | 13 | ## Go Install 14 | 15 | ```bash 16 | go install github.com/retr0h/gilt/v2@latest 17 | ``` 18 | 19 | ## Python 20 | 21 | ```bash 22 | pip3 install python-gilt 23 | ``` 24 | -------------------------------------------------------------------------------- /docs/versioned_docs/version-2.2.3/intro.md: -------------------------------------------------------------------------------- 1 | --- 2 | slug: / 3 | sidebar_position: 1 4 | title: Home 5 | --- 6 | 7 | # Gilt 8 | 9 | 10 | 11 | Gilt is a tool which aims to make repo management, manageable. Gilt clones 12 | repositories at a particular version, then overlays the repository to the 13 | provided destination. An alternate approach to "vendoring". 14 | 15 | What makes Gilt interesting, is the ability to overlay particular files and/or 16 | directories from the specified repository to given destinations. Originally, 17 | this was quite helpful for those using Ansible, since libraries, plugins, and 18 | playbooks are often shared, but Ansible's [Galaxy][] has no mechanism to handle 19 | this. Currently, this is proving useful for overlaying [Helm charts][]. 20 | 21 |
22 | 23 | ## Alternatives 24 | 25 | - [Repo][] 26 | - [Git submodules][] 27 | - [Git subtree][] 28 | 29 | ## History 30 | 31 | This project is a golang port of [Gilt][py-gilt], and aims to correct poor 32 | decisions made in the python version, primarially around config syntax, 33 | portability, and reproducibility. 34 | 35 | 36 | [Galaxy]: https://docs.ansible.com/ansible/latest/reference_appendices/galaxy.html 37 | [Helm charts]: https://helm.sh/docs/topics/charts/ 38 | [Repo]: https://gerrit.googlesource.com/git-repo/+/refs/heads/master/README.md 39 | [Git submodules]: https://git-scm.com/book/en/v2/Git-Tools-Submodules 40 | [Git subtree]: https://github.com/git/git/blob/master/contrib/subtree/git-subtree.txt 41 | [py-gilt]: http://gilt.readthedocs.io/en/latest/ 42 | 43 | -------------------------------------------------------------------------------- /docs/versioned_docs/version-2.2.3/testing.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 5 3 | --- 4 | 5 | # Testing 6 | 7 | Check installed dependencies: 8 | 9 | ```bash 10 | task deps:check 11 | ``` 12 | 13 | To execute tests: 14 | 15 | ```bash 16 | task test 17 | ``` 18 | 19 | Auto format code: 20 | 21 | ```bash 22 | task fmt 23 | ``` 24 | 25 | List helpful targets: 26 | 27 | ```bash 28 | task 29 | ``` 30 | -------------------------------------------------------------------------------- /docs/versioned_docs/version-2.2.3/usage.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 4 3 | --- 4 | 5 | # Usage 6 | 7 | ## CLI 8 | 9 | ### Init Configuration 10 | 11 | Initializes config file in the shell's current working directory: 12 | 13 | ```bash 14 | gilt init 15 | ``` 16 | 17 | ### Overlay Repository 18 | 19 | Overlay a remote repository into the destination provided. 20 | 21 | ```bash 22 | gilt overlay 23 | ``` 24 | 25 | ### Debug 26 | 27 | Display the git commands being executed. 28 | 29 | ```bash 30 | gilt --debug overlay 31 | ``` 32 | 33 | ### Skipping post-commands 34 | 35 | Overlay files only, but run no other commands. 36 | 37 | ```bash 38 | gilt overlay --no-commands 39 | ``` 40 | 41 | ## Package 42 | 43 | ### Overlay Repository 44 | 45 | See example client in `examples/go-client/`. 46 | 47 | ```go 48 | func main() { 49 | debug := true 50 | logger := getLogger(debug) 51 | 52 | c := config.Repositories{ 53 | Debug: debug, 54 | GiltDir: "~/.gilt", 55 | Repositories: []config.Repository{ 56 | { 57 | Git: "https://github.com/retr0h/ansible-etcd.git", 58 | Version: "77a95b7", 59 | DstDir: "../tmp/retr0h.ansible-etcd", 60 | }, 61 | }, 62 | } 63 | 64 | var r repositoriesManager = repositories.New(c, logger) 65 | r.Overlay() 66 | } 67 | ``` 68 | -------------------------------------------------------------------------------- /docs/versioned_docs/version-2.2/configuration.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 3 3 | --- 4 | 5 | # Configuration 6 | 7 | Gilt uses [Viper][] to load configuation through multiple methods. 8 | 9 | ## Config File 10 | 11 | Create the giltfile (`Giltfile.yaml`). 12 | 13 | Clone the specified `url`@`version` to the configurable path `--gilt-dir`. 14 | Extract the repo the `dstDir` when `dstDir` is provided. Otherwise, copy files 15 | and/or directories to the desired destinations. 16 | 17 | ```yaml 18 | --- 19 | giltDir: ~/.gilt/clone 20 | debug: false 21 | parallel: true 22 | repositories: 23 | - git: https://github.com/retr0h/ansible-etcd.git 24 | version: 77a95b7 25 | dstDir: roles/retr0h.ansible-etcd 26 | - git: https://github.com/retr0h/ansible-etcd.git 27 | version: 1.1 28 | dstDir: roles/retr0h.ansible-etcd-tag 29 | - git: https://github.com/lorin/openstack-ansible-modules.git 30 | version: 2677cc3 31 | sources: 32 | - src: '*_manage' 33 | dstDir: library 34 | - src: nova_quota 35 | dstDir: library 36 | - src: neutron_router 37 | dstFile: library/neutron_router.py 38 | - src: tests 39 | dstDir: tests 40 | commands: 41 | - cmd: ansible-playbook 42 | args: 43 | - -i, 44 | - playbook.yml 45 | - cmd: bash 46 | args: 47 | - -c 48 | - who | grep tty 49 | ``` 50 | 51 | ## Env Vars 52 | 53 | The config file can be overriden/defined through env vars. 54 | 55 | ```bash 56 | GILT_GILTFILE=Giltfile.yaml \ 57 | GILT_GILTDIR=~/.gilt/clone \ 58 | GILT_DEBUG=false \ 59 | GILT_PARALLEL=0 \ 60 | gilt overlay 61 | ``` 62 | 63 | ## Command Flags 64 | 65 | The config file and/or env vars can be overriden/defined through cli flags. 66 | 67 | ```bash 68 | gilt \ 69 | --gilt-file=Giltfile.yaml \ 70 | --gilt-dir=~/.gilt/clone \ 71 | --debug \ 72 | --parallel=false \ 73 | overlay 74 | ``` 75 | 76 | 77 | [Viper]: https://github.com/spf13/viper 78 | 79 | -------------------------------------------------------------------------------- /docs/versioned_docs/version-2.2/installation.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 2 3 | --- 4 | 5 | # Installation 6 | 7 | ## Homebrew Tap 8 | 9 | ```bash 10 | brew install retr0h/tap/gilt 11 | ``` 12 | 13 | ## Go Install 14 | 15 | ```bash 16 | go install github.com/retr0h/gilt/v2@latest 17 | ``` 18 | 19 | ## Python 20 | 21 | ```bash 22 | pip3 install python-gilt 23 | ``` 24 | -------------------------------------------------------------------------------- /docs/versioned_docs/version-2.2/intro.md: -------------------------------------------------------------------------------- 1 | --- 2 | slug: / 3 | sidebar_position: 1 4 | title: Home 5 | --- 6 | 7 | # Gilt 8 | 9 | 10 | 11 | Gilt is a tool which aims to make repo management, manageable. Gilt clones 12 | repositories at a particular version, then overlays the repository to the 13 | provided destination. An alternate approach to "vendoring". 14 | 15 | What makes Gilt interesting, is the ability to overlay particular files and/or 16 | directories from the specified repository to given destinations. Originally, 17 | this was quite helpful for those using Ansible, since libraries, plugins, and 18 | playbooks are often shared, but Ansible's [Galaxy][] has no mechanism to handle 19 | this. Currently, this is proving useful for overlaying [Helm charts][]. 20 | 21 |
22 | 23 | ## Alternatives 24 | 25 | - [Repo][] 26 | - [Git submodules][] 27 | - [Git subtree][] 28 | 29 | ## History 30 | 31 | This project is a golang port of [Gilt][py-gilt], and aims to correct poor 32 | decisions made in the python version, primarially around config syntax, 33 | portability, and reproducibility. 34 | 35 | 36 | [Galaxy]: https://docs.ansible.com/ansible/latest/reference_appendices/galaxy.html 37 | [Helm charts]: https://helm.sh/docs/topics/charts/ 38 | [Repo]: https://gerrit.googlesource.com/git-repo/+/refs/heads/master/README.md 39 | [Git submodules]: https://git-scm.com/book/en/v2/Git-Tools-Submodules 40 | [Git subtree]: https://github.com/git/git/blob/master/contrib/subtree/git-subtree.txt 41 | [py-gilt]: http://gilt.readthedocs.io/en/latest/ 42 | 43 | -------------------------------------------------------------------------------- /docs/versioned_docs/version-2.2/testing.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 5 3 | --- 4 | 5 | # Testing 6 | 7 | Check installed dependencies: 8 | 9 | ```bash 10 | task deps:check 11 | ``` 12 | 13 | To execute tests: 14 | 15 | ```bash 16 | task test 17 | ``` 18 | 19 | Auto format code: 20 | 21 | ```bash 22 | task fmt 23 | ``` 24 | 25 | List helpful targets: 26 | 27 | ```bash 28 | task 29 | ``` 30 | -------------------------------------------------------------------------------- /docs/versioned_docs/version-2.2/usage.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 4 3 | --- 4 | 5 | # Usage 6 | 7 | ## CLI 8 | 9 | ### Init Configuration 10 | 11 | Initializes config file in the shell's current working directory: 12 | 13 | ```bash 14 | gilt init 15 | ``` 16 | 17 | ### Overlay Repository 18 | 19 | Overlay a remote repository into the destination provided. 20 | 21 | ```bash 22 | gilt overlay 23 | ``` 24 | 25 | ### Debug 26 | 27 | Display the git commands being executed. 28 | 29 | ```bash 30 | gilt --debug overlay 31 | ``` 32 | 33 | ## Package 34 | 35 | ### Overlay Repository 36 | 37 | See example client in `examples/go-client/`. 38 | 39 | ```go 40 | func main() { 41 | debug := true 42 | logger := getLogger(debug) 43 | 44 | c := config.Repositories{ 45 | Debug: debug, 46 | GiltDir: "~/.gilt", 47 | Repositories: []config.Repository{ 48 | { 49 | Git: "https://github.com/retr0h/ansible-etcd.git", 50 | Version: "77a95b7", 51 | DstDir: "../tmp/retr0h.ansible-etcd", 52 | }, 53 | }, 54 | } 55 | 56 | var r repositoriesManager = repositories.New(c, logger) 57 | r.Overlay() 58 | } 59 | ``` 60 | -------------------------------------------------------------------------------- /docs/versioned_docs/version-v2.2.4/installation.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 2 3 | --- 4 | 5 | # Installation 6 | 7 | ## Homebrew Tap 8 | 9 | ```bash 10 | brew install retr0h/tap/gilt 11 | ``` 12 | 13 | ## Go Install 14 | 15 | ```bash 16 | go install github.com/retr0h/gilt/v2@latest 17 | ``` 18 | 19 | ## Python 20 | 21 | ```bash 22 | pip3 install python-gilt 23 | ``` 24 | -------------------------------------------------------------------------------- /docs/versioned_docs/version-v2.2.4/intro.md: -------------------------------------------------------------------------------- 1 | --- 2 | slug: / 3 | sidebar_position: 1 4 | title: Home 5 | --- 6 | 7 | # Gilt 8 | 9 | 10 | 11 | Gilt is a tool which aims to make repo management, manageable. Gilt clones 12 | repositories at a particular version, then overlays the repository to the 13 | provided destination. An alternate approach to "vendoring". 14 | 15 | What makes Gilt interesting, is the ability to overlay particular files and/or 16 | directories from the specified repository to given destinations. Originally, 17 | this was quite helpful for those using Ansible, since libraries, plugins, and 18 | playbooks are often shared, but Ansible's [Galaxy][] has no mechanism to handle 19 | this. Currently, this is proving useful for overlaying [Helm charts][]. 20 | 21 |
22 | 23 | ## Alternatives 24 | 25 | - [Repo][] 26 | - [Git submodules][] 27 | - [Git subtree][] 28 | 29 | ## History 30 | 31 | This project is a golang port of [Gilt][py-gilt], and aims to correct poor 32 | decisions made in the python version, primarially around config syntax, 33 | portability, and reproducibility. 34 | 35 | 36 | [Galaxy]: https://docs.ansible.com/ansible/latest/reference_appendices/galaxy.html 37 | [Helm charts]: https://helm.sh/docs/topics/charts/ 38 | [Repo]: https://gerrit.googlesource.com/git-repo/+/refs/heads/master/README.md 39 | [Git submodules]: https://git-scm.com/book/en/v2/Git-Tools-Submodules 40 | [Git subtree]: https://github.com/git/git/blob/master/contrib/subtree/git-subtree.txt 41 | [py-gilt]: http://gilt.readthedocs.io/en/latest/ 42 | 43 | -------------------------------------------------------------------------------- /docs/versioned_docs/version-v2.2.4/testing.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 5 3 | --- 4 | 5 | # Testing 6 | 7 | Check installed dependencies: 8 | 9 | ```bash 10 | task deps:check 11 | ``` 12 | 13 | To execute tests: 14 | 15 | ```bash 16 | task test 17 | ``` 18 | 19 | Auto format code: 20 | 21 | ```bash 22 | task fmt 23 | ``` 24 | 25 | List helpful targets: 26 | 27 | ```bash 28 | task 29 | ``` 30 | -------------------------------------------------------------------------------- /docs/versioned_docs/version-v2.2.4/usage.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 4 3 | --- 4 | 5 | # Usage 6 | 7 | ## CLI 8 | 9 | ### Init Configuration 10 | 11 | Initializes config file in the shell's current working directory: 12 | 13 | ```bash 14 | gilt init 15 | ``` 16 | 17 | ### Overlay Repository 18 | 19 | Overlay a remote repository into the destination provided. 20 | 21 | ```bash 22 | gilt overlay 23 | ``` 24 | 25 | ### Debug 26 | 27 | Display the git commands being executed. 28 | 29 | ```bash 30 | gilt --debug overlay 31 | ``` 32 | 33 | ### Skipping post-commands 34 | 35 | Overlay files only, but run no other commands. 36 | 37 | ```bash 38 | gilt overlay --no-commands 39 | ``` 40 | 41 | ## Package 42 | 43 | ### Overlay Repository 44 | 45 | See example client in `examples/go-client/`. 46 | 47 | ```go 48 | func main() { 49 | debug := true 50 | logger := getLogger(debug) 51 | 52 | c := config.Repositories{ 53 | Debug: debug, 54 | GiltDir: "~/.gilt", 55 | Repositories: []config.Repository{ 56 | { 57 | Git: "https://github.com/retr0h/ansible-etcd.git", 58 | Version: "77a95b7", 59 | DstDir: "../tmp/retr0h.ansible-etcd", 60 | }, 61 | }, 62 | } 63 | 64 | var r repositoriesManager = repositories.New(c, logger) 65 | r.Overlay() 66 | } 67 | ``` 68 | -------------------------------------------------------------------------------- /docs/versioned_sidebars/version-2.0.3-sidebars.json: -------------------------------------------------------------------------------- 1 | { 2 | "docsSidebar": [ 3 | { 4 | "type": "autogenerated", 5 | "dirName": "." 6 | } 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /docs/versioned_sidebars/version-2.1.1-sidebars.json: -------------------------------------------------------------------------------- 1 | { 2 | "docsSidebar": [ 3 | { 4 | "type": "autogenerated", 5 | "dirName": "." 6 | } 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /docs/versioned_sidebars/version-2.1.2-sidebars.json: -------------------------------------------------------------------------------- 1 | { 2 | "docsSidebar": [ 3 | { 4 | "type": "autogenerated", 5 | "dirName": "." 6 | } 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /docs/versioned_sidebars/version-2.2-sidebars.json: -------------------------------------------------------------------------------- 1 | { 2 | "docsSidebar": [ 3 | { 4 | "type": "autogenerated", 5 | "dirName": "." 6 | } 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /docs/versioned_sidebars/version-2.2.1-sidebars.json: -------------------------------------------------------------------------------- 1 | { 2 | "docsSidebar": [ 3 | { 4 | "type": "autogenerated", 5 | "dirName": "." 6 | } 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /docs/versioned_sidebars/version-2.2.2-sidebars.json: -------------------------------------------------------------------------------- 1 | { 2 | "docsSidebar": [ 3 | { 4 | "type": "autogenerated", 5 | "dirName": "." 6 | } 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /docs/versioned_sidebars/version-2.2.3-sidebars.json: -------------------------------------------------------------------------------- 1 | { 2 | "docsSidebar": [ 3 | { 4 | "type": "autogenerated", 5 | "dirName": "." 6 | } 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /docs/versioned_sidebars/version-v2.2.4-sidebars.json: -------------------------------------------------------------------------------- 1 | { 2 | "docsSidebar": [ 3 | { 4 | "type": "autogenerated", 5 | "dirName": "." 6 | } 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /docs/versions.json: -------------------------------------------------------------------------------- 1 | [ 2 | "v2.2.4", 3 | "2.2.3", 4 | "2.2.2", 5 | "2.2.1", 6 | "2.2", 7 | "2.1.2", 8 | "2.1.1", 9 | "2.0.3" 10 | ] 11 | -------------------------------------------------------------------------------- /examples/go-client/go.mod: -------------------------------------------------------------------------------- 1 | module example.com/client 2 | 3 | go 1.23 4 | 5 | toolchain go1.23.3 6 | 7 | replace github.com/retr0h/gilt/v2 => ../../../gilt/ 8 | 9 | require ( 10 | github.com/lmittmann/tint v1.0.5 11 | github.com/retr0h/gilt/v2 v2.2.0 12 | ) 13 | 14 | require ( 15 | github.com/avfs/avfs v0.34.0 // indirect 16 | github.com/danjacques/gofslock v0.0.0-20230728142113-ae8f59f9e88b // indirect 17 | github.com/gabriel-vasile/mimetype v1.4.3 // indirect 18 | github.com/go-playground/locales v0.14.1 // indirect 19 | github.com/go-playground/universal-translator v0.18.1 // indirect 20 | github.com/go-playground/validator/v10 v10.22.1 // indirect 21 | github.com/leodido/go-urn v1.4.0 // indirect 22 | golang.org/x/crypto v0.21.0 // indirect 23 | golang.org/x/net v0.23.0 // indirect 24 | golang.org/x/sys v0.26.0 // indirect 25 | golang.org/x/text v0.14.0 // indirect 26 | ) 27 | -------------------------------------------------------------------------------- /examples/go-client/go.sum: -------------------------------------------------------------------------------- 1 | github.com/avfs/avfs v0.34.0 h1:1smP9udOqkYM0PyTb44vZZwzrrMaNQOxNL18kZ7f5L4= 2 | github.com/avfs/avfs v0.34.0/go.mod h1:LnzrUO5acMU5NCkohHcUN15YrnkxiJ/lRLQOZSp39ow= 3 | github.com/danjacques/gofslock v0.0.0-20230728142113-ae8f59f9e88b h1:BBkZ6LZYtzMQ2Oo5LkovMmUp0gxAD+AnXzfknZlFTBo= 4 | github.com/danjacques/gofslock v0.0.0-20230728142113-ae8f59f9e88b/go.mod h1:9LABMmUSkKzt6FVQNEWdUTM0bz8Bt8MPyEcuZe0Sr8c= 5 | github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= 6 | github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 7 | github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= 8 | github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= 9 | github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= 10 | github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= 11 | github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= 12 | github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= 13 | github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= 14 | github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= 15 | github.com/go-playground/validator/v10 v10.22.1 h1:40JcKH+bBNGFczGuoBYgX4I6m/i27HYW8P9FDk5PbgA= 16 | github.com/go-playground/validator/v10 v10.22.1/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= 17 | github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= 18 | github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= 19 | github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= 20 | github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= 21 | github.com/lmittmann/tint v1.0.5 h1:NQclAutOfYsqs2F1Lenue6OoWCajs5wJcP3DfWVpePw= 22 | github.com/lmittmann/tint v1.0.5/go.mod h1:HIS3gSy7qNwGCj+5oRjAutErFBl4BzdQP6cJZ0NfMwE= 23 | github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= 24 | github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 25 | github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= 26 | github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 27 | golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= 28 | golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= 29 | golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= 30 | golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= 31 | golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 32 | golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= 33 | golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 34 | golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= 35 | golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= 36 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 37 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 38 | -------------------------------------------------------------------------------- /examples/go-client/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "log/slog" 5 | "os" 6 | "time" 7 | 8 | "github.com/lmittmann/tint" 9 | 10 | "github.com/retr0h/gilt/v2/pkg/config" 11 | "github.com/retr0h/gilt/v2/pkg/repositories" 12 | ) 13 | 14 | type repositoriesManager interface { 15 | Overlay() error 16 | } 17 | 18 | func getLogger(debug bool) *slog.Logger { 19 | logLevel := slog.LevelInfo 20 | if debug { 21 | logLevel = slog.LevelDebug 22 | } 23 | 24 | logger := slog.New( 25 | tint.NewHandler(os.Stderr, &tint.Options{ 26 | Level: logLevel, 27 | TimeFormat: time.Kitchen, 28 | }), 29 | ) 30 | 31 | return logger 32 | } 33 | 34 | func main() { 35 | debug := true 36 | logger := getLogger(debug) 37 | 38 | c := config.Repositories{ 39 | Debug: debug, 40 | GiltDir: "~/.gilt", 41 | Repositories: []config.Repository{ 42 | { 43 | Git: "https://github.com/retr0h/ansible-etcd.git", 44 | Version: "77a95b7", 45 | DstDir: "../../test/integration/tmp/retr0h.ansible-etcd", 46 | }, 47 | }, 48 | } 49 | 50 | var r repositoriesManager = repositories.New(c, logger) 51 | r.Overlay() 52 | } 53 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/retr0h/gilt/v2 2 | 3 | go 1.23.0 4 | 5 | toolchain go1.23.8 6 | 7 | require ( 8 | github.com/avfs/avfs v0.35.0 9 | github.com/caarlos0/go-version v0.2.0 10 | github.com/danjacques/gofslock v0.0.0-20230728142113-ae8f59f9e88b 11 | github.com/go-playground/validator/v10 v10.26.0 12 | github.com/golang/mock v1.6.0 13 | github.com/lmittmann/tint v1.1.1 14 | github.com/spf13/cobra v1.9.1 15 | github.com/spf13/viper v1.20.1 16 | github.com/stretchr/testify v1.10.0 17 | golang.org/x/term v0.32.0 18 | gopkg.in/yaml.v3 v3.0.1 19 | ) 20 | 21 | require ( 22 | github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect 23 | github.com/fsnotify/fsnotify v1.8.0 // indirect 24 | github.com/gabriel-vasile/mimetype v1.4.8 // indirect 25 | github.com/go-playground/locales v0.14.1 // indirect 26 | github.com/go-playground/universal-translator v0.18.1 // indirect 27 | github.com/go-viper/mapstructure/v2 v2.2.1 // indirect 28 | github.com/inconshreveable/mousetrap v1.1.0 // indirect 29 | github.com/leodido/go-urn v1.4.0 // indirect 30 | github.com/pelletier/go-toml/v2 v2.2.3 // indirect 31 | github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect 32 | github.com/sagikazarmark/locafero v0.7.0 // indirect 33 | github.com/sourcegraph/conc v0.3.0 // indirect 34 | github.com/spf13/afero v1.12.0 // indirect 35 | github.com/spf13/cast v1.7.1 // indirect 36 | github.com/spf13/pflag v1.0.6 // indirect 37 | github.com/subosito/gotenv v1.6.0 // indirect 38 | go.uber.org/atomic v1.9.0 // indirect 39 | go.uber.org/multierr v1.9.0 // indirect 40 | golang.org/x/crypto v0.33.0 // indirect 41 | golang.org/x/net v0.34.0 // indirect 42 | golang.org/x/sys v0.33.0 // indirect 43 | golang.org/x/text v0.22.0 // indirect 44 | gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect 45 | ) 46 | -------------------------------------------------------------------------------- /internal/exec.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 John Dewey 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 19 | // DEALINGS IN THE SOFTWARE. 20 | 21 | package internal 22 | 23 | // ExecManager manager responsible for exec operations. 24 | type ExecManager interface { 25 | RunCmd(name string, args []string) (string, error) 26 | RunCmdInDir(name string, args []string, cwd string) (string, error) 27 | RunInTempDir(dir, pattern string, fn func(string) error) error 28 | } 29 | -------------------------------------------------------------------------------- /internal/exec/exec.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 John Dewey 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 19 | // DEALINGS IN THE SOFTWARE. 20 | 21 | package exec 22 | 23 | import ( 24 | "log/slog" 25 | "os/exec" 26 | "strings" 27 | 28 | "github.com/avfs/avfs" 29 | ) 30 | 31 | // New factory to create a new Exec instance. 32 | func New( 33 | appFs avfs.VFS, 34 | logger *slog.Logger, 35 | ) *Exec { 36 | return &Exec{ 37 | appFs: appFs, 38 | logger: logger, 39 | } 40 | } 41 | 42 | func (e *Exec) RunCmdImpl( 43 | name string, 44 | args []string, 45 | cwd string, 46 | ) (string, error) { 47 | cmd := exec.Command(name, args...) 48 | if cwd != "" { 49 | cmd.Dir = cwd 50 | } 51 | out, err := cmd.CombinedOutput() 52 | e.logger.Debug( 53 | "exec", 54 | slog.String("command", strings.Join(cmd.Args, " ")), 55 | slog.String("cwd", cwd), 56 | slog.String("output", string(out)), 57 | slog.Any("error", err), 58 | ) 59 | if err != nil { 60 | return string(out), err 61 | } 62 | 63 | return string(out), nil 64 | } 65 | 66 | // RunCmd execute the provided command with args. 67 | // Yeah, yeah, yeah, I know I cheated by using Exec in this package. 68 | func (e *Exec) RunCmd( 69 | name string, 70 | args []string, 71 | ) (string, error) { 72 | return e.RunCmdImpl(name, args, "") 73 | } 74 | 75 | func (e *Exec) RunCmdInDir( 76 | name string, 77 | args []string, 78 | cwd string, 79 | ) (string, error) { 80 | return e.RunCmdImpl(name, args, cwd) 81 | } 82 | 83 | // RunInTempDir creates a temporary directory, and runs the provided function 84 | // with the name of the directory as input. Then it cleans up the temporary 85 | // directory. 86 | func (e *Exec) RunInTempDir(dir, pattern string, fn func(string) error) error { 87 | tmpDir, err := e.appFs.MkdirTemp(dir, pattern) 88 | if err != nil { 89 | return err 90 | } 91 | e.logger.Debug("created tempdir", slog.String("dir", tmpDir)) 92 | 93 | // Ignoring errors as there's not much we can do and this is a cleanup function. 94 | defer func() { 95 | e.logger.Debug("removing tempdir", slog.String("dir", tmpDir)) 96 | _ = e.appFs.RemoveAll(tmpDir) 97 | }() 98 | 99 | // Run the provided function. 100 | return fn(tmpDir) 101 | } 102 | -------------------------------------------------------------------------------- /internal/exec/exec_public_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 John Dewey 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 19 | // DEALINGS IN THE SOFTWARE. 20 | 21 | package exec_test 22 | 23 | import ( 24 | "log/slog" 25 | "os" 26 | "testing" 27 | 28 | "github.com/avfs/avfs/vfs/memfs" 29 | "github.com/stretchr/testify/assert" 30 | "github.com/stretchr/testify/suite" 31 | 32 | "github.com/retr0h/gilt/v2/internal" 33 | "github.com/retr0h/gilt/v2/internal/exec" 34 | ) 35 | 36 | type ExecManagerPublicTestSuite struct { 37 | suite.Suite 38 | } 39 | 40 | func (suite *ExecManagerPublicTestSuite) NewTestExecManager() internal.ExecManager { 41 | return exec.New( 42 | memfs.New(), 43 | slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{ 44 | Level: slog.LevelDebug, 45 | })), 46 | ) 47 | } 48 | 49 | func (suite *ExecManagerPublicTestSuite) TestRunCmdOk() { 50 | em := suite.NewTestExecManager() 51 | 52 | _, err := em.RunCmd("ls", []string{}) 53 | assert.NoError(suite.T(), err) 54 | } 55 | 56 | func (suite *ExecManagerPublicTestSuite) TestRunCmdWithDebug() { 57 | suite.T().Skip("cannot seem to capture Stdout when logging in em") 58 | 59 | em := suite.NewTestExecManager() 60 | 61 | _, err := em.RunCmd("echo", []string{"-n", "foo"}) 62 | assert.NoError(suite.T(), err) 63 | } 64 | 65 | func (suite *ExecManagerPublicTestSuite) TestRunCmdReturnsError() { 66 | em := suite.NewTestExecManager() 67 | 68 | _, err := em.RunCmd("invalid", []string{"foo"}) 69 | assert.Error(suite.T(), err) 70 | assert.Contains(suite.T(), err.Error(), "not found") 71 | } 72 | 73 | func (suite *ExecManagerPublicTestSuite) TestRunCmdInDirOk() { 74 | em := suite.NewTestExecManager() 75 | 76 | _, err := em.RunCmdInDir("ls", []string{}, "/tmp") 77 | assert.NoError(suite.T(), err) 78 | } 79 | 80 | func (suite *ExecManagerPublicTestSuite) TestRunCmdInDirWithDebug() { 81 | suite.T().Skip("cannot seem to capture Stdout when logging in em") 82 | 83 | em := suite.NewTestExecManager() 84 | 85 | _, err := em.RunCmdInDir("echo", []string{"-n", "foo"}, "/tmp") 86 | assert.NoError(suite.T(), err) 87 | } 88 | 89 | func (suite *ExecManagerPublicTestSuite) TestRunCmdInDirReturnsError() { 90 | em := suite.NewTestExecManager() 91 | 92 | _, err := em.RunCmdInDir("invalid", []string{"foo"}, "/tmp") 93 | assert.Error(suite.T(), err) 94 | assert.Contains(suite.T(), err.Error(), "not found") 95 | } 96 | 97 | func (suite *ExecManagerPublicTestSuite) TestRunInTempDirOk() { 98 | em := suite.NewTestExecManager() 99 | 100 | dir := "" 101 | pattern := "test" 102 | fn := func(string) error { return nil } 103 | 104 | err := em.RunInTempDir(dir, pattern, fn) 105 | assert.NoError(suite.T(), err) 106 | } 107 | 108 | func (suite *ExecManagerPublicTestSuite) TestRunInTempDirError() { 109 | em := suite.NewTestExecManager() 110 | 111 | dir := "\x00" // Null character is invalid in a filepath 112 | pattern := "test" 113 | fn := func(string) error { return nil } 114 | 115 | err := em.RunInTempDir(dir, pattern, fn) 116 | assert.Error(suite.T(), err) 117 | } 118 | 119 | // In order for `go test` to run this suite, we need to create 120 | // a normal test function and pass our suite to suite.Run. 121 | func TestExecPublicTestSuite(t *testing.T) { 122 | suite.Run(t, new(ExecManagerPublicTestSuite)) 123 | } 124 | -------------------------------------------------------------------------------- /internal/exec/types.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 John Dewey 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 19 | // DEALINGS IN THE SOFTWARE. 20 | 21 | package exec 22 | 23 | import ( 24 | "log/slog" 25 | 26 | "github.com/avfs/avfs" 27 | ) 28 | 29 | // Exec disk implementation. 30 | type Exec struct { 31 | appFs avfs.VFS 32 | logger *slog.Logger 33 | } 34 | -------------------------------------------------------------------------------- /internal/git.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 John Dewey 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 19 | // DEALINGS IN THE SOFTWARE. 20 | 21 | package internal 22 | 23 | // GitManager manager responsible for Git operations. 24 | type GitManager interface { 25 | Clone(gitURL, origin, cloneDir string) error 26 | Worktree(cloneDir, version, dstDir string) error 27 | Update(origin, cloneDir string) error 28 | Remote(cloneDir string) (string, error) 29 | } 30 | -------------------------------------------------------------------------------- /internal/git/git.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018 John Dewey 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 19 | // DEALINGS IN THE SOFTWARE. 20 | 21 | // Package git package needs reworked into proper Git libraries. However, this 22 | // package will remain using exec as it was easiest to port from gilt's 23 | // python counterpart. 24 | package git 25 | 26 | import ( 27 | "log/slog" 28 | 29 | "github.com/avfs/avfs" 30 | 31 | "github.com/retr0h/gilt/v2/internal" 32 | ) 33 | 34 | // New factory to create a new Git instance. 35 | func New( 36 | appFs avfs.VFS, 37 | execManager internal.ExecManager, 38 | logger *slog.Logger, 39 | ) *Git { 40 | return &Git{ 41 | appFs: appFs, 42 | execManager: execManager, 43 | logger: logger, 44 | } 45 | } 46 | 47 | // Clone the repo. This is a bare repo, with only metadata to start with. 48 | func (g *Git) Clone(gitURL, origin, cloneDir string) error { 49 | _, err := g.execManager.RunCmd( 50 | "git", 51 | []string{ 52 | "-c", "clone.defaultRemoteName=" + origin, 53 | "clone", "--bare", "--filter=blob:none", gitURL, cloneDir, 54 | }, 55 | ) 56 | // NOTE(nic): Workaround truly ancient versions of git that do not support 57 | // `clone.defaultRemoteName`, and explicitly rename the remote to "our" value. 58 | // The `git remote rename` command will report a fatal error here, but will 59 | // actually still rename the remote. On newer versions, the remote name will 60 | // already be set by `git clone`, and the command will fail. So either way, 61 | // we want to throw out the result. 62 | if err == nil { 63 | _, _ = g.execManager.RunCmdInDir( 64 | "git", 65 | []string{"remote", "rename", "origin", origin}, 66 | cloneDir, 67 | ) 68 | } 69 | return err 70 | } 71 | 72 | // Update the repo. Fetch the current HEAD and any new tags that may have 73 | // appeared, and update the cache. 74 | func (g *Git) Update(origin, cloneDir string) error { 75 | _, err := g.execManager.RunCmdInDir( 76 | "git", 77 | []string{"fetch", "--tags", "--force", origin, "+refs/heads/*:refs/heads/*"}, 78 | cloneDir, 79 | ) 80 | return err 81 | } 82 | 83 | // Worktree create a working tree from the repo in `cloneDir` at `version` in `dstDir`. 84 | // Under the covers, this will download any/all required objects from origin 85 | // into the cache 86 | func (g *Git) Worktree( 87 | cloneDir string, 88 | version string, 89 | dstDir string, 90 | ) error { 91 | dst, err := g.appFs.Abs(dstDir) 92 | if err != nil { 93 | return err 94 | } 95 | 96 | g.logger.Info( 97 | "extracting", 98 | slog.String("from", cloneDir), 99 | slog.String("version", version), 100 | slog.String("to", dst), 101 | ) 102 | 103 | _, err = g.execManager.RunCmdInDir( 104 | "git", 105 | []string{"worktree", "add", "--force", dst, version}, 106 | cloneDir, 107 | ) 108 | // `git worktree add` creates a breadcrumb file back to the original repo; 109 | // this is just junk data in our use case, so get rid of it 110 | if err == nil { 111 | _ = g.appFs.Remove(g.appFs.Join(dst, ".git")) 112 | _, _ = g.execManager.RunCmdInDir( 113 | "git", 114 | []string{"worktree", "prune", "--verbose"}, 115 | cloneDir, 116 | ) 117 | } 118 | return err 119 | } 120 | 121 | // Return the name of the repo remote. 122 | func (g *Git) Remote(cloneDir string) (string, error) { 123 | return g.execManager.RunCmdInDir("git", []string{"remote"}, cloneDir) 124 | } 125 | -------------------------------------------------------------------------------- /internal/git/types.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 John Dewey 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 19 | // DEALINGS IN THE SOFTWARE. 20 | 21 | package git 22 | 23 | import ( 24 | "log/slog" 25 | 26 | "github.com/avfs/avfs" 27 | 28 | "github.com/retr0h/gilt/v2/internal" 29 | ) 30 | 31 | // Git implementation responsible for Git operations. 32 | type Git struct { 33 | appFs avfs.VFS 34 | execManager internal.ExecManager 35 | logger *slog.Logger 36 | } 37 | -------------------------------------------------------------------------------- /internal/mocks/exec.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 John Dewey 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 19 | // DEALINGS IN THE SOFTWARE. 20 | 21 | package mocks 22 | 23 | // ExecManager manager responsible for exec operations. 24 | type ExecManager interface { 25 | RunCmd(name string, args []string) error 26 | RunCmdInDir(name string, args []string, cwd string) error 27 | RunInTempDir(dir, pattern string, fn func(string) error) error 28 | } 29 | -------------------------------------------------------------------------------- /internal/mocks/exec/exec_mock.go: -------------------------------------------------------------------------------- 1 | // Code generated by MockGen. DO NOT EDIT. 2 | // Source: internal/exec.go 3 | 4 | // Package exec is a generated GoMock package. 5 | package exec 6 | 7 | import ( 8 | reflect "reflect" 9 | 10 | gomock "github.com/golang/mock/gomock" 11 | ) 12 | 13 | // MockExecManager is a mock of ExecManager interface. 14 | type MockExecManager struct { 15 | ctrl *gomock.Controller 16 | recorder *MockExecManagerMockRecorder 17 | } 18 | 19 | // MockExecManagerMockRecorder is the mock recorder for MockExecManager. 20 | type MockExecManagerMockRecorder struct { 21 | mock *MockExecManager 22 | } 23 | 24 | // NewMockExecManager creates a new mock instance. 25 | func NewMockExecManager(ctrl *gomock.Controller) *MockExecManager { 26 | mock := &MockExecManager{ctrl: ctrl} 27 | mock.recorder = &MockExecManagerMockRecorder{mock} 28 | return mock 29 | } 30 | 31 | // EXPECT returns an object that allows the caller to indicate expected use. 32 | func (m *MockExecManager) EXPECT() *MockExecManagerMockRecorder { 33 | return m.recorder 34 | } 35 | 36 | // RunCmd mocks base method. 37 | func (m *MockExecManager) RunCmd(name string, args []string) (string, error) { 38 | m.ctrl.T.Helper() 39 | ret := m.ctrl.Call(m, "RunCmd", name, args) 40 | ret0, _ := ret[0].(string) 41 | ret1, _ := ret[1].(error) 42 | return ret0, ret1 43 | } 44 | 45 | // RunCmd indicates an expected call of RunCmd. 46 | func (mr *MockExecManagerMockRecorder) RunCmd(name, args interface{}) *gomock.Call { 47 | mr.mock.ctrl.T.Helper() 48 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RunCmd", reflect.TypeOf((*MockExecManager)(nil).RunCmd), name, args) 49 | } 50 | 51 | // RunCmdInDir mocks base method. 52 | func (m *MockExecManager) RunCmdInDir(name string, args []string, cwd string) (string, error) { 53 | m.ctrl.T.Helper() 54 | ret := m.ctrl.Call(m, "RunCmdInDir", name, args, cwd) 55 | ret0, _ := ret[0].(string) 56 | ret1, _ := ret[1].(error) 57 | return ret0, ret1 58 | } 59 | 60 | // RunCmdInDir indicates an expected call of RunCmdInDir. 61 | func (mr *MockExecManagerMockRecorder) RunCmdInDir(name, args, cwd interface{}) *gomock.Call { 62 | mr.mock.ctrl.T.Helper() 63 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RunCmdInDir", reflect.TypeOf((*MockExecManager)(nil).RunCmdInDir), name, args, cwd) 64 | } 65 | 66 | // RunInTempDir mocks base method. 67 | // NOTE(nic): mockgen creates this mock wrong, and I'm not sure what to do 68 | // about it. If you've run `task mockgen`, and it removed this code, and now 69 | // your tests are failing, put this code back. 70 | func (m *MockExecManager) RunInTempDir(dir, pattern string, fn func(string) error) error { 71 | m.ctrl.T.Helper() 72 | ret := m.ctrl.Call(m, "RunInTempDir", dir, pattern, fn) 73 | // BEGIN extra code that mockgen can't be bothered to generate 74 | if fn != nil { 75 | return fn("stub") 76 | } 77 | // END extra code that mockgen can't be bothered to generate 78 | ret0, _ := ret[0].(error) 79 | return ret0 80 | } 81 | 82 | // RunInTempDir indicates an expected call of RunInTempDir. 83 | func (mr *MockExecManagerMockRecorder) RunInTempDir(dir, pattern, fn interface{}) *gomock.Call { 84 | mr.mock.ctrl.T.Helper() 85 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RunInTempDir", reflect.TypeOf((*MockExecManager)(nil).RunInTempDir), dir, pattern, fn) 86 | } 87 | -------------------------------------------------------------------------------- /internal/mocks/git.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 John Dewey 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 19 | // DEALINGS IN THE SOFTWARE. 20 | 21 | package mocks 22 | 23 | // GitManager manager responsible for Git operations. 24 | type GitManager interface { 25 | Clone(gitURL, origin, cloneDir string) error 26 | Worktree(cloneDir, version, dstDir string) error 27 | Update(origin, cloneDir string) error 28 | Remote(cloneDir string) (string, error) 29 | } 30 | -------------------------------------------------------------------------------- /internal/mocks/git/git_mock.go: -------------------------------------------------------------------------------- 1 | // Code generated by MockGen. DO NOT EDIT. 2 | // Source: internal/git.go 3 | 4 | // Package git is a generated GoMock package. 5 | package git 6 | 7 | import ( 8 | reflect "reflect" 9 | 10 | gomock "github.com/golang/mock/gomock" 11 | ) 12 | 13 | // MockGitManager is a mock of GitManager interface. 14 | type MockGitManager struct { 15 | ctrl *gomock.Controller 16 | recorder *MockGitManagerMockRecorder 17 | } 18 | 19 | // MockGitManagerMockRecorder is the mock recorder for MockGitManager. 20 | type MockGitManagerMockRecorder struct { 21 | mock *MockGitManager 22 | } 23 | 24 | // NewMockGitManager creates a new mock instance. 25 | func NewMockGitManager(ctrl *gomock.Controller) *MockGitManager { 26 | mock := &MockGitManager{ctrl: ctrl} 27 | mock.recorder = &MockGitManagerMockRecorder{mock} 28 | return mock 29 | } 30 | 31 | // EXPECT returns an object that allows the caller to indicate expected use. 32 | func (m *MockGitManager) EXPECT() *MockGitManagerMockRecorder { 33 | return m.recorder 34 | } 35 | 36 | // Clone mocks base method. 37 | func (m *MockGitManager) Clone(gitURL, origin, cloneDir string) error { 38 | m.ctrl.T.Helper() 39 | ret := m.ctrl.Call(m, "Clone", gitURL, origin, cloneDir) 40 | ret0, _ := ret[0].(error) 41 | return ret0 42 | } 43 | 44 | // Clone indicates an expected call of Clone. 45 | func (mr *MockGitManagerMockRecorder) Clone(gitURL, origin, cloneDir interface{}) *gomock.Call { 46 | mr.mock.ctrl.T.Helper() 47 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Clone", reflect.TypeOf((*MockGitManager)(nil).Clone), gitURL, origin, cloneDir) 48 | } 49 | 50 | // Remote mocks base method. 51 | func (m *MockGitManager) Remote(cloneDir string) (string, error) { 52 | m.ctrl.T.Helper() 53 | ret := m.ctrl.Call(m, "Remote", cloneDir) 54 | ret0, _ := ret[0].(string) 55 | ret1, _ := ret[1].(error) 56 | return ret0, ret1 57 | } 58 | 59 | // Remote indicates an expected call of Remote. 60 | func (mr *MockGitManagerMockRecorder) Remote(cloneDir interface{}) *gomock.Call { 61 | mr.mock.ctrl.T.Helper() 62 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Remote", reflect.TypeOf((*MockGitManager)(nil).Remote), cloneDir) 63 | } 64 | 65 | // Update mocks base method. 66 | func (m *MockGitManager) Update(origin, cloneDir string) error { 67 | m.ctrl.T.Helper() 68 | ret := m.ctrl.Call(m, "Update", origin, cloneDir) 69 | ret0, _ := ret[0].(error) 70 | return ret0 71 | } 72 | 73 | // Update indicates an expected call of Update. 74 | func (mr *MockGitManagerMockRecorder) Update(origin, cloneDir interface{}) *gomock.Call { 75 | mr.mock.ctrl.T.Helper() 76 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Update", reflect.TypeOf((*MockGitManager)(nil).Update), origin, cloneDir) 77 | } 78 | 79 | // Worktree mocks base method. 80 | func (m *MockGitManager) Worktree(cloneDir, version, dstDir string) error { 81 | m.ctrl.T.Helper() 82 | ret := m.ctrl.Call(m, "Worktree", cloneDir, version, dstDir) 83 | ret0, _ := ret[0].(error) 84 | return ret0 85 | } 86 | 87 | // Worktree indicates an expected call of Worktree. 88 | func (mr *MockGitManagerMockRecorder) Worktree(cloneDir, version, dstDir interface{}) *gomock.Call { 89 | mr.mock.ctrl.T.Helper() 90 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Worktree", reflect.TypeOf((*MockGitManager)(nil).Worktree), cloneDir, version, dstDir) 91 | } 92 | -------------------------------------------------------------------------------- /internal/mocks/repository.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 John Dewey 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 19 | // DEALINGS IN THE SOFTWARE. 20 | 21 | package mocks 22 | 23 | import ( 24 | "github.com/retr0h/gilt/v2/pkg/config" 25 | ) 26 | 27 | // RepositoryManager manager responsible for Repository operations. 28 | type RepositoryManager interface { 29 | Clone(config config.Repository, cloneDir string) (string, error) 30 | Worktree(config config.Repository, cloneDir string, targetDir string) error 31 | CopySources(config config.Repository, cloneDir string) error 32 | } 33 | -------------------------------------------------------------------------------- /internal/mocks/repository/copy_mock.go: -------------------------------------------------------------------------------- 1 | // Code generated by MockGen. DO NOT EDIT. 2 | // Source: internal/repository/types.go 3 | 4 | // Package repository is a generated GoMock package. 5 | package repository 6 | 7 | import ( 8 | reflect "reflect" 9 | 10 | gomock "github.com/golang/mock/gomock" 11 | ) 12 | 13 | // MockCopyManager is a mock of CopyManager interface. 14 | type MockCopyManager struct { 15 | ctrl *gomock.Controller 16 | recorder *MockCopyManagerMockRecorder 17 | } 18 | 19 | // MockCopyManagerMockRecorder is the mock recorder for MockCopyManager. 20 | type MockCopyManagerMockRecorder struct { 21 | mock *MockCopyManager 22 | } 23 | 24 | // NewMockCopyManager creates a new mock instance. 25 | func NewMockCopyManager(ctrl *gomock.Controller) *MockCopyManager { 26 | mock := &MockCopyManager{ctrl: ctrl} 27 | mock.recorder = &MockCopyManagerMockRecorder{mock} 28 | return mock 29 | } 30 | 31 | // EXPECT returns an object that allows the caller to indicate expected use. 32 | func (m *MockCopyManager) EXPECT() *MockCopyManagerMockRecorder { 33 | return m.recorder 34 | } 35 | 36 | // CopyDir mocks base method. 37 | func (m *MockCopyManager) CopyDir(src, dst string) error { 38 | m.ctrl.T.Helper() 39 | ret := m.ctrl.Call(m, "CopyDir", src, dst) 40 | ret0, _ := ret[0].(error) 41 | return ret0 42 | } 43 | 44 | // CopyDir indicates an expected call of CopyDir. 45 | func (mr *MockCopyManagerMockRecorder) CopyDir(src, dst interface{}) *gomock.Call { 46 | mr.mock.ctrl.T.Helper() 47 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CopyDir", reflect.TypeOf((*MockCopyManager)(nil).CopyDir), src, dst) 48 | } 49 | 50 | // CopyFile mocks base method. 51 | func (m *MockCopyManager) CopyFile(src, dst string) error { 52 | m.ctrl.T.Helper() 53 | ret := m.ctrl.Call(m, "CopyFile", src, dst) 54 | ret0, _ := ret[0].(error) 55 | return ret0 56 | } 57 | 58 | // CopyFile indicates an expected call of CopyFile. 59 | func (mr *MockCopyManagerMockRecorder) CopyFile(src, dst interface{}) *gomock.Call { 60 | mr.mock.ctrl.T.Helper() 61 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CopyFile", reflect.TypeOf((*MockCopyManager)(nil).CopyFile), src, dst) 62 | } 63 | -------------------------------------------------------------------------------- /internal/mocks/repository/repository_mock.go: -------------------------------------------------------------------------------- 1 | // Code generated by MockGen. DO NOT EDIT. 2 | // Source: internal/repository.go 3 | 4 | // Package repository is a generated GoMock package. 5 | package repository 6 | 7 | import ( 8 | reflect "reflect" 9 | 10 | gomock "github.com/golang/mock/gomock" 11 | config "github.com/retr0h/gilt/v2/pkg/config" 12 | ) 13 | 14 | // MockRepositoryManager is a mock of RepositoryManager interface. 15 | type MockRepositoryManager struct { 16 | ctrl *gomock.Controller 17 | recorder *MockRepositoryManagerMockRecorder 18 | } 19 | 20 | // MockRepositoryManagerMockRecorder is the mock recorder for MockRepositoryManager. 21 | type MockRepositoryManagerMockRecorder struct { 22 | mock *MockRepositoryManager 23 | } 24 | 25 | // NewMockRepositoryManager creates a new mock instance. 26 | func NewMockRepositoryManager(ctrl *gomock.Controller) *MockRepositoryManager { 27 | mock := &MockRepositoryManager{ctrl: ctrl} 28 | mock.recorder = &MockRepositoryManagerMockRecorder{mock} 29 | return mock 30 | } 31 | 32 | // EXPECT returns an object that allows the caller to indicate expected use. 33 | func (m *MockRepositoryManager) EXPECT() *MockRepositoryManagerMockRecorder { 34 | return m.recorder 35 | } 36 | 37 | // Clone mocks base method. 38 | func (m *MockRepositoryManager) Clone(config config.Repository, cloneDir string) (string, error) { 39 | m.ctrl.T.Helper() 40 | ret := m.ctrl.Call(m, "Clone", config, cloneDir) 41 | ret0, _ := ret[0].(string) 42 | ret1, _ := ret[1].(error) 43 | return ret0, ret1 44 | } 45 | 46 | // Clone indicates an expected call of Clone. 47 | func (mr *MockRepositoryManagerMockRecorder) Clone(config, cloneDir interface{}) *gomock.Call { 48 | mr.mock.ctrl.T.Helper() 49 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Clone", reflect.TypeOf((*MockRepositoryManager)(nil).Clone), config, cloneDir) 50 | } 51 | 52 | // CopySources mocks base method. 53 | func (m *MockRepositoryManager) CopySources(config config.Repository, cloneDir string) error { 54 | m.ctrl.T.Helper() 55 | ret := m.ctrl.Call(m, "CopySources", config, cloneDir) 56 | ret0, _ := ret[0].(error) 57 | return ret0 58 | } 59 | 60 | // CopySources indicates an expected call of CopySources. 61 | func (mr *MockRepositoryManagerMockRecorder) CopySources(config, cloneDir interface{}) *gomock.Call { 62 | mr.mock.ctrl.T.Helper() 63 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CopySources", reflect.TypeOf((*MockRepositoryManager)(nil).CopySources), config, cloneDir) 64 | } 65 | 66 | // Worktree mocks base method. 67 | func (m *MockRepositoryManager) Worktree(config config.Repository, cloneDir, targetDir string) error { 68 | m.ctrl.T.Helper() 69 | ret := m.ctrl.Call(m, "Worktree", config, cloneDir, targetDir) 70 | ret0, _ := ret[0].(error) 71 | return ret0 72 | } 73 | 74 | // Worktree indicates an expected call of Worktree. 75 | func (mr *MockRepositoryManagerMockRecorder) Worktree(config, cloneDir, targetDir interface{}) *gomock.Call { 76 | mr.mock.ctrl.T.Helper() 77 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Worktree", reflect.TypeOf((*MockRepositoryManager)(nil).Worktree), config, cloneDir, targetDir) 78 | } 79 | -------------------------------------------------------------------------------- /internal/path/path.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 John Dewey 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 19 | // DEALINGS IN THE SOFTWARE. 20 | 21 | package path 22 | 23 | import ( 24 | "os/user" 25 | "strings" 26 | ) 27 | 28 | // CurrentUserFn function to switch when testing 29 | var CurrentUserFn = user.Current 30 | 31 | // ExpandUser on Unix and Windows, return the argument with an initial 32 | // component of ~ or ~user replaced by that user’s home directory. 33 | func ExpandUser( 34 | path string, 35 | ) (string, error) { 36 | if !strings.HasPrefix(path, "~") { 37 | return path, nil 38 | } 39 | 40 | usr, err := CurrentUserFn() 41 | if err != nil { 42 | return "", err 43 | } 44 | 45 | return strings.Replace(path, "~", usr.HomeDir, 1), nil 46 | } 47 | -------------------------------------------------------------------------------- /internal/path/path_public_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 John Dewey 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 19 | // DEALINGS IN THE SOFTWARE. 20 | 21 | package path_test 22 | 23 | import ( 24 | "fmt" 25 | "os/user" 26 | "testing" 27 | 28 | "github.com/stretchr/testify/assert" 29 | "github.com/stretchr/testify/suite" 30 | 31 | "github.com/retr0h/gilt/v2/internal/path" 32 | ) 33 | 34 | type PathPublicTestSuite struct { 35 | suite.Suite 36 | } 37 | 38 | func (suite *PathPublicTestSuite) TestexpandUserOk() { 39 | originalCurrentUserFn := path.CurrentUserFn 40 | path.CurrentUserFn = func() (*user.User, error) { 41 | return &user.User{ 42 | HomeDir: "/testUser", 43 | }, nil 44 | } 45 | defer func() { path.CurrentUserFn = originalCurrentUserFn }() 46 | 47 | got, err := path.ExpandUser("~/foo/bar") 48 | assert.NoError(suite.T(), err) 49 | assert.Equal(suite.T(), got, "/testUser/foo/bar") 50 | } 51 | 52 | // Test expandUser when there is no work to do 53 | func (suite *PathPublicTestSuite) TestexpandUserNoop() { 54 | testpath := "/foo/bar" 55 | got, err := path.ExpandUser(testpath) 56 | assert.NoError(suite.T(), err) 57 | assert.Equal(suite.T(), got, testpath) 58 | } 59 | 60 | func (suite *PathPublicTestSuite) TestexpandUserReturnsError() { 61 | originalCurrentUserFn := path.CurrentUserFn 62 | path.CurrentUserFn = func() (*user.User, error) { 63 | return nil, fmt.Errorf("failed to get current user") 64 | } 65 | defer func() { path.CurrentUserFn = originalCurrentUserFn }() 66 | 67 | _, err := path.ExpandUser("~/foo/bar") 68 | assert.Error(suite.T(), err) 69 | } 70 | 71 | // In order for `go test` to run this suite, we need to create 72 | // a normal test function and pass our suite to suite.Run. 73 | func TestPathPublicTestSuite(t *testing.T) { 74 | suite.Run(t, new(PathPublicTestSuite)) 75 | } 76 | -------------------------------------------------------------------------------- /internal/repositories.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 John Dewey 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 19 | // DEALINGS IN THE SOFTWARE. 20 | 21 | package internal 22 | 23 | // RepositoriesManager manager responsible for Repositories operations. 24 | type RepositoriesManager interface { 25 | Overlay() error 26 | } 27 | -------------------------------------------------------------------------------- /internal/repositories/types.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 John Dewey 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 19 | // DEALINGS IN THE SOFTWARE. 20 | 21 | package repositories 22 | 23 | import ( 24 | "log/slog" 25 | 26 | "github.com/avfs/avfs" 27 | 28 | "github.com/retr0h/gilt/v2/internal" 29 | "github.com/retr0h/gilt/v2/pkg/config" 30 | ) 31 | 32 | // Repositories perform repository operations. 33 | type Repositories struct { 34 | appFs avfs.VFS 35 | config config.Repositories 36 | logger *slog.Logger 37 | 38 | repoManager internal.RepositoryManager 39 | execManager internal.ExecManager 40 | 41 | cloneCache map[string]string 42 | } 43 | -------------------------------------------------------------------------------- /internal/repository.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 John Dewey 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 19 | // DEALINGS IN THE SOFTWARE. 20 | 21 | package internal 22 | 23 | import ( 24 | "github.com/retr0h/gilt/v2/pkg/config" 25 | ) 26 | 27 | // RepositoryManager manager responsible for Repository operations. 28 | type RepositoryManager interface { 29 | Clone(config config.Repository, cloneDir string) (string, error) 30 | Worktree(config config.Repository, cloneDir string, targetDir string) error 31 | CopySources(config config.Repository, cloneDir string) error 32 | } 33 | -------------------------------------------------------------------------------- /internal/repository/copy.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018 John Dewey 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 19 | // DEALINGS IN THE SOFTWARE. 20 | 21 | package repository 22 | 23 | import ( 24 | "fmt" 25 | "io" 26 | "log/slog" 27 | 28 | "github.com/avfs/avfs" 29 | ) 30 | 31 | // NewCopy factory to create a new copy instance. 32 | func NewCopy( 33 | appFs avfs.VFS, 34 | logger *slog.Logger, 35 | ) *Copy { 36 | return &Copy{ 37 | appFs: appFs, 38 | logger: logger, 39 | } 40 | } 41 | 42 | // CopyFile copies the contents of the file named src to the file named 43 | // by dst. The file will be created if it does not already exist. If the 44 | // destination file exists, all it's contents will be replaced by the contents 45 | // of the source file. The file mode will be copied from the source and 46 | // the copied data is synced/flushed to stable storage. 47 | func (r *Copy) CopyFile( 48 | src string, 49 | dst string, 50 | ) (err error) { 51 | baseSrc := r.appFs.Base(src) 52 | 53 | r.logger.Info( 54 | "copying file", 55 | slog.String("srcFile", baseSrc), 56 | slog.String("dstFile", dst), 57 | ) 58 | 59 | // Open the source file for reading, and record its metadata 60 | in, err := r.appFs.Open(src) 61 | if err != nil { 62 | return err 63 | } 64 | defer func() { _ = in.Close() }() 65 | 66 | si, err := in.Stat() 67 | if err != nil { 68 | return err 69 | } 70 | 71 | // Ensure target directory exists; it will be created with the same mode as 72 | // the target file, plus x-bits. 73 | dirMode := si.Mode() & 0o777 74 | dirMode |= ((dirMode & 0o444) >> 2) | ((dirMode & 0o222) >> 1) 75 | _ = r.appFs.MkdirAll(r.appFs.Dir(dst), dirMode) 76 | // Open dest file for writing; make it owner-only perms before putting 77 | // anything in it 78 | out, err := r.appFs.Create(dst) 79 | if err != nil { 80 | return err 81 | } 82 | defer func() { _ = out.Close() }() 83 | 84 | err = out.Chmod(0o600) 85 | if err != nil { 86 | return err 87 | } 88 | 89 | _, err = io.Copy(out, in) 90 | if err != nil { 91 | return err 92 | } 93 | 94 | err = out.Sync() 95 | if err != nil { 96 | return err 97 | } 98 | 99 | // All done; make the permissions match 100 | err = out.Chmod(si.Mode()) 101 | if err != nil { 102 | return err 103 | } 104 | 105 | return nil 106 | } 107 | 108 | // CopyDir recursively copies a directory tree, attempting to preserve permissions. 109 | // Source directory must exist, destination directory must *not* exist. 110 | // Symlinks are implicitly dereferenced. 111 | func (r *Copy) CopyDir( 112 | src string, 113 | dst string, 114 | ) (err error) { 115 | src = r.appFs.Clean(src) 116 | dst = r.appFs.Clean(dst) 117 | baseSrc := r.appFs.Base(src) 118 | 119 | r.logger.Info( 120 | "copying dir", 121 | slog.String("srcDir", baseSrc), 122 | slog.String("dstDir", dst), 123 | ) 124 | 125 | si, err := r.appFs.Stat(src) 126 | if err != nil { 127 | return err 128 | } 129 | if !si.IsDir() { 130 | return fmt.Errorf("source is not a directory") 131 | } 132 | 133 | d, err := r.appFs.Open(dst) 134 | _ = d.Close() 135 | if err == nil { 136 | return fmt.Errorf("destination already exists") 137 | } 138 | 139 | err = r.appFs.MkdirAll(dst, si.Mode()) 140 | if err != nil { 141 | return err 142 | } 143 | 144 | entries, err := r.appFs.ReadDir(src) 145 | if err != nil { 146 | return err 147 | } 148 | 149 | for _, entry := range entries { 150 | srcPath := r.appFs.Join(src, entry.Name()) 151 | dstPath := r.appFs.Join(dst, entry.Name()) 152 | 153 | // Dereference any symlinks and copy their contents instead 154 | target, err := r.appFs.Stat(srcPath) 155 | if err != nil { 156 | return err 157 | } 158 | 159 | if target.IsDir() { 160 | err = r.CopyDir(srcPath, dstPath) 161 | if err != nil { 162 | return err 163 | } 164 | } else { 165 | err = r.CopyFile(srcPath, dstPath) 166 | if err != nil { 167 | return err 168 | } 169 | } 170 | } 171 | 172 | return nil 173 | } 174 | -------------------------------------------------------------------------------- /internal/repository/helper_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018 John Dewey 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 19 | // DEALINGS IN THE SOFTWARE. 20 | 21 | package repository_test 22 | 23 | import ( 24 | "github.com/avfs/avfs" 25 | ) 26 | 27 | type FileSpec struct { 28 | appFs avfs.VFS 29 | srcDir string 30 | srcFile string 31 | srcFiles []string 32 | } 33 | 34 | func createFileSpecs(specs []FileSpec) { 35 | for _, s := range specs { 36 | if s.srcDir != "" { 37 | _ = s.appFs.MkdirAll(s.srcDir, 0o755) 38 | } 39 | 40 | if s.srcFile != "" { 41 | _, _ = s.appFs.Create(s.srcFile) 42 | } 43 | 44 | if len(s.srcFiles) > 0 { 45 | for _, f := range s.srcFiles { 46 | _, _ = s.appFs.Create(f) 47 | } 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /internal/repository/repository.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018 John Dewey 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 19 | // DEALINGS IN THE SOFTWARE. 20 | 21 | package repository 22 | 23 | import ( 24 | "errors" 25 | "fmt" 26 | "log/slog" 27 | "strings" 28 | 29 | "github.com/avfs/avfs" 30 | 31 | "github.com/retr0h/gilt/v2/internal" 32 | "github.com/retr0h/gilt/v2/pkg/config" 33 | ) 34 | 35 | const ORIGIN = "gilt" 36 | 37 | // We'll use this to normalize Git URLs as "safe" filenames 38 | var replacer = strings.NewReplacer("/", "-", ":", "-") 39 | 40 | // New factory to create a new Repository instance. 41 | func New( 42 | appFs avfs.VFS, 43 | copyManager CopyManager, 44 | gitManager internal.GitManager, 45 | logger *slog.Logger, 46 | ) *Repository { 47 | return &Repository{ 48 | appFs: appFs, 49 | copyManager: copyManager, 50 | gitManager: gitManager, 51 | logger: logger, 52 | } 53 | } 54 | 55 | // Clone Repository.Git under Repository.getCloneDir 56 | func (r *Repository) Clone( 57 | c config.Repository, 58 | cloneDir string, 59 | ) (string, error) { 60 | targetDir := r.appFs.Join(cloneDir, replacer.Replace(c.Git)) 61 | remote, err := r.gitManager.Remote(targetDir) 62 | if err == nil && !strings.Contains(remote, ORIGIN) { 63 | r.logger.Info( 64 | "remote does not exist in clone, invalidating cache", 65 | slog.Any("remote", ORIGIN), 66 | slog.String("dstDir", targetDir), 67 | ) 68 | _ = r.appFs.RemoveAll(targetDir) 69 | err = errors.New("cache does not exist") 70 | } 71 | if err != nil { 72 | r.logger.Info("cloning", slog.String("repository", c.Git), slog.String("dstDir", targetDir)) 73 | if err := r.gitManager.Clone(c.Git, ORIGIN, targetDir); err != nil { 74 | return targetDir, err 75 | } 76 | } else { 77 | r.logger.Info("clone already exists", slog.String("dstDir", targetDir)) 78 | if err := r.gitManager.Update(ORIGIN, targetDir); err != nil { 79 | return targetDir, err 80 | } 81 | } 82 | return targetDir, nil 83 | } 84 | 85 | // Worktree create a git workingtree at the given version in Repository.DstDir. 86 | func (r *Repository) Worktree( 87 | c config.Repository, 88 | cloneDir string, 89 | targetDir string, 90 | ) error { 91 | return r.gitManager.Worktree(cloneDir, c.Version, targetDir) 92 | } 93 | 94 | // CopySources copy Repository.Src to Repository.DstFile or Repository.DstDir. 95 | func (r *Repository) CopySources( 96 | c config.Repository, 97 | cloneDir string, 98 | ) error { 99 | r.logger.Debug("copy", slog.String("origin", cloneDir)) 100 | for _, source := range c.Sources { 101 | cloneDirWithSrcPath := r.appFs.Join(cloneDir, source.Src) // join clone dir with head 102 | globbedSrc, err := r.appFs.Glob(cloneDirWithSrcPath) 103 | if err != nil { 104 | return err 105 | } 106 | 107 | for _, src := range globbedSrc { 108 | // The source is a directory 109 | if info, err := r.appFs.Stat(src); err == nil && info.IsDir() { 110 | // ... and dst dir exists 111 | if info, err := r.appFs.Stat(source.DstDir); err == nil && info.IsDir() { 112 | if err := r.appFs.RemoveAll(source.DstDir); err != nil { 113 | return err 114 | } 115 | } 116 | if err := r.copyManager.CopyDir(src, source.DstDir); err != nil { 117 | return err 118 | } 119 | } else { 120 | if source.DstFile != "" { 121 | if err := r.copyManager.CopyFile(src, source.DstFile); err != nil { 122 | return err 123 | } 124 | } else if source.DstDir != "" { 125 | if err := r.appFs.MkdirAll(source.DstDir, 0o755); err != nil { 126 | return fmt.Errorf("unable to create dest dir: %s", err) 127 | } 128 | srcBaseFile := r.appFs.Base(src) 129 | newDst := r.appFs.Join(source.DstDir, srcBaseFile) 130 | if err := r.copyManager.CopyFile(src, newDst); err != nil { 131 | return err 132 | } 133 | } 134 | } 135 | } 136 | } 137 | 138 | return nil 139 | } 140 | -------------------------------------------------------------------------------- /internal/repository/types.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 John Dewey 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 19 | // DEALINGS IN THE SOFTWARE. 20 | 21 | package repository 22 | 23 | import ( 24 | "log/slog" 25 | 26 | "github.com/avfs/avfs" 27 | 28 | "github.com/retr0h/gilt/v2/internal" 29 | ) 30 | 31 | // Repository contains the repository's details for cloning. 32 | type Repository struct { 33 | appFs avfs.VFS 34 | copyManager CopyManager 35 | gitManager internal.GitManager 36 | logger *slog.Logger 37 | } 38 | 39 | // CopyManager manager responsible for Copy operations. 40 | type CopyManager interface { 41 | CopyDir(src string, dst string) error 42 | CopyFile(src string, dst string) error 43 | } 44 | 45 | // Copy copy implementation. 46 | type Copy struct { 47 | appFs avfs.VFS 48 | logger *slog.Logger 49 | } 50 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018 John Dewey 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 19 | // DEALINGS IN THE SOFTWARE. 20 | 21 | package main 22 | 23 | import ( 24 | "github.com/retr0h/gilt/v2/cmd" 25 | ) 26 | 27 | func main() { 28 | cmd.Execute() 29 | } 30 | -------------------------------------------------------------------------------- /pkg/config/schema.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 John Dewey 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 19 | // DEALINGS IN THE SOFTWARE. 20 | 21 | package config 22 | 23 | import ( 24 | "github.com/go-playground/validator/v10" 25 | ) 26 | 27 | // regsiterValidatorsFn function to switch when testing 28 | var registerValidatorsFn = registerValidators 29 | 30 | // registerValidators register customer validators. 31 | func registerValidators(v *validator.Validate) error { 32 | // noop - hook for future validators 33 | return nil 34 | } 35 | 36 | // Validate validates a structs exposed fields. 37 | func Validate( 38 | c *Repositories, 39 | ) error { 40 | validate := validator.New() 41 | 42 | err := registerValidatorsFn(validate) 43 | if err != nil { 44 | return err 45 | } 46 | 47 | return validate.Struct(c) 48 | } 49 | -------------------------------------------------------------------------------- /pkg/config/types.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 John Dewey 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 19 | // DEALINGS IN THE SOFTWARE. 20 | 21 | package config 22 | 23 | // Repositories perform repository operations. 24 | type Repositories struct { 25 | // Debug enable or disable debug option set from CLI. 26 | Debug bool `mapstruture:"debug"` 27 | // Parallel enable or disable concurrent clone fetches. 28 | Parallel bool ` mapstructure:"parallel"` 29 | // SkipCommands run post-commands as part of the overlay process 30 | SkipCommands bool 31 | // GiltFile path to Gilt's config file option set from CLI. 32 | GiltFile string ` mapstructure:"giltFile" validate:"required"` 33 | // GiltDir path to Gilt's clone dir option set from CLI. 34 | GiltDir string ` mapstructure:"giltDir" validate:"required"` 35 | // Repositories a slice of repository configurations to overlay. 36 | Repositories []Repository `mapstruture:"repositories" validate:"required,dive"` 37 | } 38 | 39 | // Source mapping of files and/or directories needing copied. 40 | type Source struct { 41 | // Src source file or directory to copy. 42 | Src string `mapstructure:"src" validate:"required"` 43 | // DstFile destination of file copy. 44 | DstFile string `mapstructure:"dstFile" validate:"required_without=DstDir,excluded_with=DstDir"` 45 | // DstDir destination of directory copy. 46 | DstDir string `mapstructure:"dstDir" validate:"required_without=DstFile,excluded_with=DstFile,ne=.,ne=.."` 47 | } 48 | 49 | // Water string `validate:"required_without=Fire,excluded_with=Fire"` 50 | 51 | // Command command to execute. 52 | type Command struct { 53 | Cmd string `mapstructure:"cmd" validate:"required"` 54 | Args []string `mapstructure:"args"` 55 | } 56 | 57 | // Repository contains the repository's details for cloning. 58 | type Repository struct { 59 | // Git url of Git repository to clone. 60 | Git string `mapstructure:"git" validate:"required"` 61 | // Version the commit SHA or tag to use. 62 | Version string `mapstructure:"version" validate:"required"` 63 | // DstDir destination directory to copy clone to. 64 | DstDir string `mapstructure:"dstDir" validate:"required_without=Sources,excluded_with=Sources,ne=.,ne=.."` 65 | // Sources containing files and/or directories to copy. 66 | Sources []Source `mapstructure:"sources" validate:"dive,required_without=DstDir,excluded_with=DstDir"` 67 | // Commands commands to execute on Repository. 68 | Commands []Command `mapstructure:"commands"` 69 | } 70 | -------------------------------------------------------------------------------- /pkg/repositories.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 John Dewey 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 19 | // DEALINGS IN THE SOFTWARE. 20 | 21 | package pkg 22 | 23 | // RepositoriesManager manager responsible for public Repositories operations. 24 | type RepositoriesManager interface { 25 | Overlay() error 26 | } 27 | -------------------------------------------------------------------------------- /pkg/repositories/types.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 John Dewey 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 19 | // DEALINGS IN THE SOFTWARE. 20 | 21 | package repositories 22 | 23 | import ( 24 | "log/slog" 25 | 26 | "github.com/avfs/avfs" 27 | 28 | "github.com/retr0h/gilt/v2/internal" 29 | "github.com/retr0h/gilt/v2/pkg/config" 30 | ) 31 | 32 | // Repositories perform repository operations. 33 | type Repositories struct { 34 | appFs avfs.VFS 35 | c config.Repositories 36 | reposManager internal.RepositoriesManager 37 | logger *slog.Logger 38 | } 39 | -------------------------------------------------------------------------------- /test/Giltfile.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | debug: false 3 | repositories: 4 | - git: https://github.com/retr0h/ansible-etcd.git 5 | version: 77a95b7 6 | dstDir: retr0h.ansible-etcd 7 | commands: 8 | - cmd: touch 9 | args: ansible-etcd-repo-post-command-1 10 | - git: https://github.com/retr0h/ansible-etcd.git 11 | version: 1.1 12 | dstDir: retr0h.ansible-etcd-tag 13 | - git: https://github.com/lorin/openstack-ansible-modules.git 14 | version: 2677cc3 15 | sources: 16 | - src: "*_manage" 17 | dstDir: library 18 | - src: nova_quota 19 | dstDir: library 20 | - src: neutron_router 21 | dstFile: library/neutron_router.py 22 | - src: tests 23 | dstDir: tests 24 | commands: 25 | - cmd: touch 26 | args: openstack-ansible-modules-repo-post-command-1 27 | - cmd: touch 28 | args: openstack-ansible-modules-repo-post-command-2 29 | --------------------------------------------------------------------------------