{"id":30679464,"url":"https://github.com/aocoronel/neostow-sh","last_synced_at":"2025-10-19T05:41:03.981Z","repository":{"id":291440847,"uuid":"977632669","full_name":"aocoronel/neostow-sh","owner":"aocoronel","description":"✨ The declarative GNU Stow","archived":false,"fork":false,"pushed_at":"2025-08-28T18:23:28.000Z","size":21,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-08-29T00:44:50.895Z","etag":null,"topics":["declarative","shell","stow","symlink"],"latest_commit_sha":null,"homepage":"","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/aocoronel.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,"zenodo":null}},"created_at":"2025-05-04T16:39:49.000Z","updated_at":"2025-08-28T18:23:31.000Z","dependencies_parsed_at":null,"dependency_job_id":"5f6c8646-ef0d-4e2c-9c28-36acceaa34f3","html_url":"https://github.com/aocoronel/neostow-sh","commit_stats":null,"previous_names":["janpstrunn/neostow","anstrinn/neostow","aocoronel/neostow"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/aocoronel/neostow-sh","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aocoronel%2Fneostow-sh","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aocoronel%2Fneostow-sh/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aocoronel%2Fneostow-sh/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aocoronel%2Fneostow-sh/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aocoronel","download_url":"https://codeload.github.com/aocoronel/neostow-sh/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aocoronel%2Fneostow-sh/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":273137397,"owners_count":25052003,"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","status":"online","status_checked_at":"2025-09-01T02:00:09.058Z","response_time":120,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["declarative","shell","stow","symlink"],"created_at":"2025-09-01T14:11:41.513Z","updated_at":"2025-10-19T05:41:03.974Z","avatar_url":"https://github.com/aocoronel.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# The declarative GNU stow\n\n\u003e [!WARNING]\n\u003e `neostow-sh` does not have robust shell injection protections! Do never run this without reviewing the neostow file! Do use sudo with caution!\n\n`neostow-sh` is a POSIX compliant shell script, that does only depends on common Linux utils to operate.\n\n`neostow` is a tool that streamline the process to manage symlinks like GNU `stow`, but using a `neostow` file, instead. It allows more flexible symlink management, enabling the creation of symlinks from a relative source to anywhere on your computer.\n\nThis declarative nature allows to easily make reproducible and granular symlinking, unlike `stow`. However, this project does not aims to fully replace it, but to give a declarative feature missing from it.\n\nThis tool is useful to keep files and directories organized in a single centralized place, while also having them across the system. Differently, than `stow`, which allows you to place some files into a different target, other than the parent directory, `neostow` aims to further improve this functionality.\n\nWith `neostow` each file or directory can be symlinked to a specific part of the system, and not the project as a whole. There is not ignore file, and no need to adjust the folder layout to achieve your goals. If your `neostow` does not explicitly specify an operation, it won't touch a single file.\n\nOther versions of Neostow:\n\n- [aocoronel/neostow-c](https://github.com/aocoronel/neostow-c)\n- [aocoronel/neostow-nim](https://github.com/aocoronel/neostow-nim): No longer maintained.\n- [aocoronel/neostow-rs](https://github.com/aocoronel/neostow-rs)\n\n## Shell Edition\n\nThe shell version is written in POSIX to allow maximum compatibility across all shells, and does not depend on extra utilities other than the common Linux utilities such as the `coreutils`.\n\n### Bugs\n\nCurrently, there is no known bugs.\n\n### Vulnerabilities\n\nFrom all the rewrites of `neostow`, the shell version is the most vulnerable to shell injections, since the parsed data from the `.neostow` file can contain malicious data such as `sudo rm -rf --no-preserve-root /`, and many variations with `||`, `\u0026\u0026` or `;`.\n\nCurrently the shell version is able to block these tricks, but maybe not all possible attempts.\n\n## Features\n\n- **Flexible symlink creation**: Create symlinks from any relative source to any destination.\n- **Per-project file**: Maintain a `.neostow` file per project.\n- **Overwrite symlinks**: Optionally overwrite existing symlinks.\n- **Remove symlinks**: Easily remove all created symlinks.\n- **Preview operations**: Preview what operations would run.\n\n## Installation\n\nCopy the source:\n\n```bash\ngit clone https://github.com/aocoronel/neostow-sh.git\ncd neostow-sh\n```\n\nTo install `neostow`:\n\n```bash\nchmod +x src/neostow\nsudo cp src/neostow /usr/local/bin/\n```\n\nTo install manpages:\n\n```bash\nsudo cp docs/neostow.1 /usr/share/man/man1/\n```\n\nTo install completions:\n\n```bash\n# Bash\nsudo cp completions/_neostow.bash /usr/share/bash-completion/completions/\n# Zsh\nsudo cp completions/_neostow.zsh /usr/share/zsh/site-functions\n```\n\n## Usage\n\n`neostow` reads from a `.neostow` file in the current directory to determine which symlinks to create.\n\nThe `.neostow` file should contain lines in the following format: `source=destination`.\n\nSee the manpage(1) at `FILES` for more details. Or give at look at the [example file](https://github.com/aocoronel/neostow-c/blob/main/test/.neostow) and [Examples](#examples).\n\n```console\nneostow | the declarative GNU stow\n\nUsage:  neostow [OPTIONS] \u003cCOMMAND\u003e\n\nCommands:\n  delete\n          Delete symlinks\n  edit\n          Edit the neostow file\n\nOptions:\n  -D, --debug\n          Enables debug verbosity\n  -F, --force\n          Skip prompt dialogs\n  -V, --verbose\n          Enable verbosity\n  -f, --file \u003cFILE\u003e\n          Load an alternative neostow file\n  -d, --dry\n          Describe potential operations\n  -h, --help\n          Displays this message and exits\n  -o, --overwrite\n          Overwrite existing symlinks\n  -v, --version\n          Displays program version\n```\n\n### Configuration File\n\nThe `.neostow` file should be placed in the root of your project directory.\n\n#### Examples\n\nExample `.neostow` file:\n\n```text\nconfig/myconfig.txt=/home/username/.config/myconfig/ # links myconfig.txt to ~/.config/myconfig/\nscripts/myscript.sh=/home/username/bin/myscript/ # links myscript.sh to ~/bin/myscrypt/\nmyfile=$HOME/Downloads # links myfile to ~/Downloads\n```\n\nThe left side paths are relative to the current directory where the `.neostow` file is found.\n\n## Integrations\n\n### [Just](https://github.com/casey/just)\n\n`just` is a handy way to save and run `neostow` commands from any directory within the project.\n\nBecause, `neostow` has the limitation to only find `.neostow` files in the current directory, `just` gives an extra functionality. Integrating both, allows you to run `neostow` from the root of the project, thus finding the `.neostow` file.\n\nIn or `justfile`, you may create a recipe like this:\n\n```just\n# Neostow: Overwrite\nneostow:\n  neostow -o\n```\n\nThen, from any child directory where this `justfile` was placed, you can just run `just neostow`, and it will run the configured recipe.\n\n## Notes\n\nThis program was only tested in a Linux machine.\n\n## License\n\nThis repository is licensed under the MIT License, a very permissive license that allows you to use, modify, copy, distribute and more.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faocoronel%2Fneostow-sh","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faocoronel%2Fneostow-sh","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faocoronel%2Fneostow-sh/lists"}