{"id":13505892,"url":"https://github.com/ivanilves/travelgrunt","last_synced_at":"2026-07-19T00:01:45.498Z","repository":{"id":61195551,"uuid":"547257973","full_name":"ivanilves/travelgrunt","owner":"ivanilves","description":"navigate inside [mono]repos effortlessly!","archived":false,"fork":false,"pushed_at":"2024-10-27T18:18:11.000Z","size":140,"stargazers_count":69,"open_issues_count":6,"forks_count":3,"subscribers_count":6,"default_branch":"main","last_synced_at":"2025-04-09T20:05:33.326Z","etag":null,"topics":["devops","fatigue","git","monorepo","platform","shell","sre","system-administration","systems","terraform","terragrunt"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ivanilves.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-10-07T11:42:35.000Z","updated_at":"2025-01-22T21:14:50.000Z","dependencies_parsed_at":"2024-01-03T02:29:35.448Z","dependency_job_id":"99737ebe-ef33-4983-843c-2d45d4b76a44","html_url":"https://github.com/ivanilves/travelgrunt","commit_stats":null,"previous_names":["ivanilves/ttg"],"tags_count":26,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ivanilves%2Ftravelgrunt","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ivanilves%2Ftravelgrunt/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ivanilves%2Ftravelgrunt/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ivanilves%2Ftravelgrunt/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ivanilves","download_url":"https://codeload.github.com/ivanilves/travelgrunt/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248103872,"owners_count":21048245,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["devops","fatigue","git","monorepo","platform","shell","sre","system-administration","systems","terraform","terragrunt"],"created_at":"2024-08-01T00:01:16.401Z","updated_at":"2026-07-19T00:01:45.434Z","avatar_url":"https://github.com/ivanilves.png","language":"Go","funding_links":[],"categories":["Tools","\u003ca name=\"git\"\u003e\u003c/a\u003eGit and accessories"],"sub_categories":["Community providers"],"readme":"[![codeclimate](https://api.codeclimate.com/v1/badges/857b9074dbf627e4f594/maintainability)](https://codeclimate.com/github/ivanilves/travelgrunt/maintainability)\n[![codecov](https://codecov.io/github/ivanilves/travelgrunt/branch/main/graph/badge.svg?token=SW21884ADR)](https://codecov.io/github/ivanilves/travelgrunt)\n\n\n# travelgrunt\n\nTravel **[Terragrunt](https://terragrunt.gruntwork.io/)**, **[Terraform](https://www.terraform.io/)** and ... ANY [Git] repository tree with CLI as a first class passenger! :airplane:\n\n`travelgrunt` alleviates the pain of hitting endless `cd`/`\u003cTAB\u003e` combos while navigating inside the repo.\n\n## How to use?\n\n### Inside a Git repository\n* `cd` to the directory of your [locally cloned] Git repository;\n* run **tg** [alias](#shell-aliases) there :rocket: ([optional] arguments are \"path filter\" matches);\n* use arrow keys to navigate the list and `/` key to search for specific items;\n\n### As a global bookmarks navigator\n* create `~/.travelgrunt.yml` with your favorite [links](#bookmarks) in your home directory;\n* run **tg** from anywhere to navigate your bookmarked paths;\n* works outside of Git repositories - perfect for jumping between projects!\n\n## Configuration\n:bulb: If no configuration file found `travelgrunt` will assume repository having only Terragrunt projects inside.\n\nCreate `.travelgrunt.yml` file in the root path of your repository. Example config for a random monorepo:\n\n```\nrules:\n  - prefix: vendor/\n    negate: true\n  - prefix: terragrunt/\n    mode: terragrunt\n  - prefix: code/\n    name: '.*\\.(go|js|css|html)$'\n  - prefix: config/\n    name: '*.yaml'\n```\n\n:arrow_up: Config is essentially a list of sequentially applied path matching rules. Each rule can have these fields:\n\n* `prefix` - literal prefix to be matched against relative directory path;\n* `name` - a free form regular expression or a simple glob (`name: '*.go'`) match applied to the file name;\n* `mode` - any matching behavior backed by a [custom logic] function from the [`mode`](https://github.com/ivanilves/travelgrunt/tree/main/pkg/config/mode) package;\n* `negate` - boolean directive that reverses the meaning of the match, excluding the paths matched;\n\n:bulb: Even while developing `travelgrunt` itself we use it to navigate [package directories](https://github.com/ivanilves/travelgrunt/blob/main/.travelgrunt.yml) of the application :tophat:\n\n## Links\nUse links feature to be able to travel outside of the repo in a convenient manner.\n\nAdd `links` [string list] section to `.travelgrunt.yml` in-repository config file:\n```yaml\nrules:\n  - mode: terragrunt\nlinks:\n  - /tmp\n  - submodule-path\n  - ~/projects/other-repo\n```\nInvoke links usage by passing `-l` flag to the CLI app:\n```bash\n$ tg -l\n```\nTypical filter rules do apply for the link selection:\n```bash\n$ tg -l other-repo\n```\n\n## Bookmarks\nUse `travelgrunt` as a **global filesystem navigator** with bookmarks!\n\nCreate `~/.travelgrunt.yml` in your home directory with your frequently accessed paths:\n```yaml\nlinks:\n  - ~/projects/work/backend\n  - ~/projects/work/frontend\n  - ~/projects/personal/blog\n  - ~/documents/notes\n  - /var/log\n  - /opt/services\n```\n\nWhen you run **tg** outside of any Git repository, it will automatically use this global config:\n```bash\n$ tg                # Shows all your bookmarks\n$ tg backend        # Filters bookmarks matching \"backend\"\n```\n\n:bulb: This is perfect for jumping between different projects or frequently accessed directories **anywhere** on your filesystem!\n\n**Notes:**\n* Global bookmarks work **only outside** Git repositories\n* Inside a repo, `travelgrunt` uses the local `.travelgrunt.yml` config (if present)\n* The `-top` flag requires being inside a Git repository\n* Both absolute paths (`/opt/services`) and tilde-expanded paths (`~/projects`) are supported\n\n## Override configured rules with arbitrary expression\n\nYou can search by the arbitrary expression instead of configured rules:\n\n```\ntg -x \u003cEXPRESSION\u003e [\u003cmatch\u003e \u003cmatch2\u003e ... \u003cmatchN\u003e]\n```\n\n## Shell aliases and functions\n\nIt is **absolutely required** to use `zsh` aliases or `bash` functions. Start from something like this:\n#### ZSH\n```\nalias tg='_tg(){ travelgrunt -out-file ~/.tg-path ${@} \u0026\u0026 cd \"$(cat ~/.tg-path)\" }; _tg'\nalias te='_te(){ travelgrunt -out-file ~/.tg-path -e ${@} \u0026\u0026 ${EDITOR} \"$(cat ~/.tg-path)\" }; _te'\nalias tt='_tt(){ travelgrunt -top -out-file ~/.tg-path \u0026\u0026 cd \"$(cat ~/.tg-path)\" }; _tt'\n```\n#### BASH\n```\nfunction tg() {\n\ttravelgrunt -out-file ~/.tg-path ${@} \u0026\u0026 cd \"$(cat ~/.tg-path)\"\n}\n\nfunction te() {\n\ttravelgrunt -out-file ~/.tg-path -e ${@} \u0026\u0026 ${EDITOR} \"$(cat ~/.tg-path)\"\n}\n\nfunction tt() {\n\ttravelgrunt -top -out-file ~/.tg-path \u0026\u0026 cd \"$(cat ~/.tg-path)\"\n}\n```\nThese lines are usually added to `~/.bashrc` or `~/.zshrc` file, depending on your system and shell of choice.\n\n:bulb: **tt** is a \"convenience alias\" that brings you to the top level path of your repository.\n\n### Why aliases?\nCore feature of this program is the ability to change working directory while staying **inside the current shell**.\nThis **can not** be done by the program itself, because of `POSIX` security limitations. Without instrumenting\nthe shell with aliases `travelgrunt` will not work!\n\n### `CTRL+C` / `CTRL+D` behaviour\nWhen key combinations `CTRL+C` or `CTRL+D` get pressed during the execution, following occures:\n* `CTRL+C` - program terminates with exit code `1`, under the starting directory path;\n* `CTRL+D` - program terminates with exit code `0`, under the directory path currently selected;\n\n## How to install? :neckbeard:\n\n### Install with `homebrew`:\n\n```\nbrew tap ivanilves/tap\nbrew install ivanilves/tap/travelgrunt\n```\n\n### Install latest binary with `cURL` + `sh`:\nInstall latest release binary into `/usr/local/bin` (default):\n\n```\ncurl -s -f \\\n  https://raw.githubusercontent.com/ivanilves/travelgrunt/main/scripts/install-latest.sh | sh\n```\n\nInstall latest release binary into `/somewhere/else/bin`:\n```\ncurl -s -f \\\n  https://raw.githubusercontent.com/ivanilves/travelgrunt/main/scripts/install-latest.sh \\\n  | PREFIX=/somewhere/else sh\n```\n\n## How to build? :construction:\n\n* `make dep` - install/ensure dependencies;\n* `make build` - build the `travelgrunt` binary in `cmd/travelgrunt` path;\n* `make install` - [optional] install built `travelgrunt` binary under the `${PREFIX}/bin` location;\n\n## How to release a new version? :package:\n\n:bulb: Make sure you have push permissions for this repository!\n\nRun `make release` recipe, which will:\n* check, if you are on a `main` branch;\n* pull the latest `main` branch from remote;\n* calculate the next release version (update `MAJOR`.`MINOR` [here](https://github.com/ivanilves/travelgrunt/blob/main/Makefile#L2) if needed);\n* tag the branch tip with the version calculated and push tag to remote then;\n* [GoReleaser](https://github.com/ivanilves/travelgrunt/blob/main/.goreleaser.yml) will take care of everything else :sunglasses:\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fivanilves%2Ftravelgrunt","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fivanilves%2Ftravelgrunt","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fivanilves%2Ftravelgrunt/lists"}