{"id":48960356,"url":"https://github.com/lucaaaaum/supalink","last_synced_at":"2026-04-18T01:32:41.410Z","repository":{"id":323376012,"uuid":"1092883270","full_name":"lucaaaaum/supalink","owner":"lucaaaaum","description":"supalink is a simple tool made to help with symlink operations made in batch","archived":false,"fork":false,"pushed_at":"2025-11-09T19:48:59.000Z","size":135,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-11-09T20:34:11.671Z","etag":null,"topics":["cli","flake","go","linux","nix","symlink","tool"],"latest_commit_sha":null,"homepage":"","language":"Go","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/lucaaaaum.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,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-11-09T13:56:24.000Z","updated_at":"2025-11-09T19:50:54.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/lucaaaaum/supalink","commit_stats":null,"previous_names":["lucaaaaum/supalink"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/lucaaaaum/supalink","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lucaaaaum%2Fsupalink","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lucaaaaum%2Fsupalink/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lucaaaaum%2Fsupalink/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lucaaaaum%2Fsupalink/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lucaaaaum","download_url":"https://codeload.github.com/lucaaaaum/supalink/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lucaaaaum%2Fsupalink/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31953513,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-18T00:39:45.007Z","status":"ssl_error","status_checked_at":"2026-04-18T00:39:20.671Z","response_time":62,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["cli","flake","go","linux","nix","symlink","tool"],"created_at":"2026-04-18T01:32:40.728Z","updated_at":"2026-04-18T01:32:41.367Z","avatar_url":"https://github.com/lucaaaaum.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# supalink\n\nEver wanted to symlink multiple files using RegEx patterns? I sure do, all the time!\n\nWell, guess what, now you can! *supalink* makes it easy and straightforward to do multiple symlinks in one go, providing some interesting flags to allow flexibility. It also goes fine with existing scripts, if you want to integrate it into a larger workflow.\n\n## Usage\n\nSay we have this file structure:\n\n```\n.\n├── [TorrentMaintainer] Video - Episode 1.mkv\n├── [TorrentMaintainer] Video - Episode 2.mkv\n├── [TorrentMaintainer] Video - Episode 3.mkv\n└── [TorrentMaintainer] Video - Episode 4.mkv\n```\n\nBut you actually want this:\n\n```\n.\n├── Season 1\n│   ├── Video S01E01.mkv\n│   └── Video S01E02.mkv\n└── Season 2\n    ├── Video S02E01.mkv\n    └── Video S02E02.mkv\n```\n\nYou can do this with *supalink* like so:\n\n```bash\nsupalink \"/path/to/downloads/\\[TorrentMaintainer\\] Video/.*\\.mkv\" \"/path/to/library/Video/Season \\$STEP/Video S\\$STEPE\\$STEP_COUNT.mkv\" --step 2 --step 2\n```\n\n\u003e But this looks ridiculous! What on Earth is going on?\n\n### Explanation\n\nYeah so RegEx is a funny thing. You can write it, but it's really, really hard to read it. What we're doing there basically tells *supalink* to:\n\n1. Go to the directory `/path/to/downloads/[TorrentMaintainer] Video`\n2. Search for all files that match the RegEx `.*\\.mkv` (all MKV files, basically)\n3. For each file found, create a symlink in `/path/to/library/Video/Season $STEP/Video S$STEPE$STEP_COUNT.mkv`, where:\n   - `$STEP` is the current season number (starts counting from 1)\n   - `$STEP_COUNT` is the total number of episodes processed so far\n\nYou'll understand more the more you use it. So, for testing purposes, you can always use\n\n```bash\nsupalink --dry-run\n```\n\nwhich runs supalink but does not actually make any symlinks.\n\nAnd, if you're unsure on how the links will actually end-up like, you can also just run\n\n```bash\nsupalink --confirm\n```\n\nwhich will ask for confirmation before creating any symlinks.\n\n### I still need more explanation\n\nYou can always check the available flags and their descriptions with\n\n```bash\nsupalink --help\n```\n\n## Installation\n\nBecause I'm a [nix](https://nixos.org/) nerd, you can install *supalink* using the [nix flake](./flake.nix), just like below:\n\n```nix\n{\n  inputs.supalink.url = \"github:lucaaaaum/supalink\";\n\n  yourPackageSource* = [\n    inputs.supalink.packages.${yourPackageSource.system}.supalink\n  ];\n}\n```\n\n*\\* this being your **system.Packages** or **home.Packages** or whatever*\n\n## Roadmap\n\n- [ ] Use [Charm's](https://github.com/charmbracelet) toolset to make *supalink* prettier;\n- [X] Actually implement Step functionality (it's on the example but it's not working lol);\n- [ ] Improve user experience:\n    - [ ] Make it so the user doesn't have to add quote marks on input;\n    - [ ] Make it so the user doesn't have to escape RegEx characters that shouldn't be treated as RegEx (brackets on torrent maintainers names, dots, dashes, etc.);\n- [ ] Release it on nixpkgs and other package managers;\n- [ ] Create a snippet using Charm's [VHS](https://github.com/charmbracelet/vhs).\n\n## Quick Q/A\n\n***Q: why?***\n\n**A:** torrent mantainers don't all follow the same naming conventions, making it hard to utilize tools such as [Jellyfin](https://jellyfin.org/), which do in fact rely on naming conventions. What I'm currently doing is separating my the torrenting downloads from my media library. So all files are actually on the downloads directory, while the media library simply points to those files.\n\n***Q: couldn't you just write a bash script?***\n\n**A:** yeah but I don't like writing bash. Sorry. Better than whatever powershell has going on though.\n\n***Q: is this cross-platform?***\n\n**A:** if you manage to install this on windows or mac, it should work. I only made the binary available for nix though.\n\n***Q: are all the features implemented?***\n**A:** nope, this is still WIP. Feel free to open issues or PRs if you want to contribute!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flucaaaaum%2Fsupalink","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flucaaaaum%2Fsupalink","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flucaaaaum%2Fsupalink/lists"}