{"id":13998163,"url":"https://github.com/queer/that-goes-there","last_synced_at":"2025-07-23T05:32:40.958Z","repository":{"id":94882392,"uuid":"557492118","full_name":"queer/that-goes-there","owner":"queer","description":"put things over there from over here","archived":true,"fork":false,"pushed_at":"2023-12-19T12:10:14.000Z","size":809,"stargazers_count":16,"open_issues_count":10,"forks_count":1,"subscribers_count":2,"default_branch":"mistress","last_synced_at":"2024-08-10T19:16:25.453Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/queer.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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}},"created_at":"2022-10-25T19:37:57.000Z","updated_at":"2024-07-23T12:53:09.000Z","dependencies_parsed_at":null,"dependency_job_id":"f3ab1df7-fa05-4cd2-8dd7-2902f55bb179","html_url":"https://github.com/queer/that-goes-there","commit_stats":{"total_commits":206,"total_committers":2,"mean_commits":103.0,"dds":0.470873786407767,"last_synced_commit":"0ce9e301268146b4f7564f5ac5e1eb063ee1d2e8"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/queer%2Fthat-goes-there","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/queer%2Fthat-goes-there/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/queer%2Fthat-goes-there/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/queer%2Fthat-goes-there/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/queer","download_url":"https://codeload.github.com/queer/that-goes-there/tar.gz/refs/heads/mistress","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":227245132,"owners_count":17753239,"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":[],"created_at":"2024-08-09T19:01:26.343Z","updated_at":"2024-11-30T00:31:13.229Z","avatar_url":"https://github.com/queer.png","language":"Rust","funding_links":[],"categories":["Rust"],"sub_categories":[],"readme":"# that goes there\n\n*that goes there* (hereafter \"there\" or `there`) is:\n\n- A library for general planning and execution of tasks on local and remote\n  hosts.\n  - [crates.io](https://crates.io/crates/there)\n  - Tasks are compiled down to `sh(1)`-compatible commands for execution.\n  - Non-raw-command tasks attempt to validate prerequists before execution.\n- A CLI for applying plans via:\n  - Local execution\n  - Remote SSH\n  - Agent-controller SSH\n- An agent-controller pair for remote SSH execution.\n\nMinimum supported Rust version: `1.66`\n\n## features\n\n### Library:\n\n- Tokio-based, fully-async\n- Pluggable execution backends\n  - [x] Local\n  - [x] SSH\n  - [ ] Implement `Executor` yourself!\n- Async log streaming\n- Pluggable log streaming backends\n  - [x] In-memory\n  - [ ] Implement `LogSource`/`LogSink` yourself!\n- Agent-controller shared IPC structs\n- Plan validation\n  - Compile tasks down to `sh(1)`-compatible commands\n- Host files + host groups\n- Fully instrumented with `tracing::instrument`\n  - `tracing`-based logging that can be consumed with `tracing-subscriber`\n  - `color_eyre`-based error reporting\n    - Used to share error implementation between CLI/agent/controller\n\n### CLI:\n\n- Log streaming by default\n  - [x] Local execution\n  - [x] SSH execution\n  - [x] Agent-controller execution\n- Plan validation\n\n## setup\n\nInstall [pre-commit](https://pre-commit.com/).\n\n```bash\npre-commit install\npre-commit autoupdate\ncargo install cargo-audit\n```\n\n## usage\n\nkinda undocumented for now. refer to `test/*.yaml` for some plan/hostfile\nexamples.\n\n## todo\n\n- [ ] Pretty tui with [makeup](https://crates.io/crates/makeup) for log streaming\n- [ ] Concurrency guards to ensure that certain tasks have to run across all\n      hosts at the same time.\n\n## show me something pretty\n\n```\ngit:(mistress) | ▶  cargo run -p there-cli -- plan apply --dry -f ./test/ssh-plan.yaml --hosts ./test/ssh-hosts.yaml # ...\n*** plan: test plan ***\n\n* metadata\n** hosts:\n*** group: ssh-group\n**** broken-ssh: localhost:2222 (ssh)\n**** ssh-localhost: localhost:22 (ssh)\n** test command: echo hello world!\n*** ExeExists { exe: \"echo\" }\n** test command 2: echo hello world!! :D\n*** ExeExists { exe: \"echo\" }\n** test command 2: echo wow!!!!!\n*** ExeExists { exe: \"echo\" }\n** create some file: touch /tmp/some-file\n*** ExeExists { exe: \"touch\" }\n*** DirectoryExists { path: \"/tmp\" }\ngit:(mistress) 1 | ▶  cargo run -p there-cli -- plan apply -f ./test/ssh-plan.yaml --hosts ./test/ssh-hosts.yaml # ...\n*** applying plan to group: ssh-group ***\n*** prepared plan for host: broken-ssh\n*** prepared plan for host: ssh-localhost\nbroken-ssh: * steps: 4\nssh-localhost: * steps: 4\nbroken-ssh: ssh authentication failed!\n*** failed plan: test plan for host: broken-ssh: 0/4 ***\n*** error: ssh executor failed to apply plan test plan to host broken-ssh: 0/4 tasks finished: ssh authentication failed!\nssh-localhost: ** executing task: test command\nssh-localhost: ensuring ExeExists { exe: \"echo\" }\nssh-localhost: /bin/echo\nssh-localhost:\nssh-localhost: hello world!\nssh-localhost:\nssh-localhost:\nssh-localhost: ** executing task: test command 2\nssh-localhost: ensuring ExeExists { exe: \"echo\" }\nssh-localhost: /bin/echo\nssh-localhost:\nssh-localhost: hello world!! :D\nssh-localhost:\nssh-localhost:\nssh-localhost: ** executing task: test command 2\nssh-localhost: ensuring ExeExists { exe: \"echo\" }\nssh-localhost: /bin/echo\nssh-localhost:\nssh-localhost: wow!!!!!\nssh-localhost:\nssh-localhost:\nssh-localhost: ** executing task: create some file\nssh-localhost: ensuring ExeExists { exe: \"touch\" }\nssh-localhost: /bin/touch\nssh-localhost:\nssh-localhost: ensuring DirectoryExists { path: \"/tmp\" }\nssh-localhost:\nssh-localhost: *** finished applying plan: test plan -\u003e ssh-localhost (4/4)\n*** completed plan: test plan for host: ssh-localhost: 4/4 ***\ngit:(mistress) 1 | ▶\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fqueer%2Fthat-goes-there","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fqueer%2Fthat-goes-there","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fqueer%2Fthat-goes-there/lists"}