{"id":16755024,"url":"https://github.com/twof/downstream","last_synced_at":"2025-06-28T17:07:52.476Z","repository":{"id":45250944,"uuid":"306563781","full_name":"twof/Downstream","owner":"twof","description":"A tool that reports files with associated docs","archived":false,"fork":false,"pushed_at":"2021-12-28T05:42:43.000Z","size":82,"stargazers_count":3,"open_issues_count":1,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-06-24T22:35:45.225Z","etag":null,"topics":["docs","documentation","git","github","github-actions","hook","pre-commit","pre-commit-hook","script","swift"],"latest_commit_sha":null,"homepage":"","language":"Swift","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/twof.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}},"created_at":"2020-10-23T07:41:22.000Z","updated_at":"2022-07-23T00:24:27.000Z","dependencies_parsed_at":"2022-09-15T18:50:25.358Z","dependency_job_id":null,"html_url":"https://github.com/twof/Downstream","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"purl":"pkg:github/twof/Downstream","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/twof%2FDownstream","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/twof%2FDownstream/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/twof%2FDownstream/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/twof%2FDownstream/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/twof","download_url":"https://codeload.github.com/twof/Downstream/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/twof%2FDownstream/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":262465779,"owners_count":23315641,"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":["docs","documentation","git","github","github-actions","hook","pre-commit","pre-commit-hook","script","swift"],"created_at":"2024-10-13T03:06:36.642Z","updated_at":"2025-06-28T17:07:52.459Z","avatar_url":"https://github.com/twof.png","language":"Swift","readme":"# Downstream\n\nA tool to alert users when files they're changing may cause docs to be out of date. Downstream is more or less a \nreverse dependency manager in that it's used to describe what relies on your code rather than what your code relies on.\n\n## Why?\n\nThere's a pretty consistent problem accross orgs I've been in where people are hesitent to write docs, guides, etc \nbecause they're concerned that what they write will rapidly become out of date. This fear is legitimate, and out of \ndate docs are a common problem. Letting people know what docs need to be updated upon file changes is a step towards \nsolving this problem.\n\n## Installation\n\n### `pre-commit` Installation\n\nIn your `.pre-commit-config.yaml` add the following\n\n```yaml\nrepos:\n-   repo: https://github.com/twof/Downstream\n    rev: 0.3.0\n    hooks:\n    -   id: downstream\n```\n\nAlternatively, if you would like to use Downstream on a system without Swift installed, you may use \n`-   id: downstream-docker`. You will need to have Docker installed on that system.\n\n### Github Actions Installation\n\nYou can also have Github comment on PRs when file changes may necessitate other changes. Here is an example setup.\n\n```yaml\nname: pre-commit\n\non:\n  workflow_dispatch:\n  pull_request:\n  push:\n    branches: [master]\n\njobs:\n  pre-commit:\n    runs-on: ubuntu-latest\n    steps:\n    - uses: actions/checkout@v2\n    - uses: actions/setup-python@v2\n    - id: file_changes\n      uses: trilom/file-changes-action@v1.2.3\n      with:\n        output: ' '\n    - id: get_changes\n      run: |\n        content=\"$(swift run downstream -o human ${{ steps.file_changes.outputs.files }})\"\n        content=\"${content//'%'/'%25'}\"\n        content=\"${content//$'\\n'/'%0A'}\"\n        content=\"${content//$'\\r'/'%0D'}\"\n        echo \"::set-output name=content::$content\"\n    - uses: daohoangson/comment-on-github@v2\n      env:\n        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n      with:\n        body: ${{ steps.get_changes.outputs.content }}\n```\n\nFor some background, `file_changes` records a list of files that have been changed in this PR to \n`steps.file_changes.outputs.files`. It's basically the equivalent of `git diff --name-only`. \n\nThese lines\n```\ncontent=\"${content//'%'/'%25'}\"\ncontent=\"${content//$'\\n'/'%0A'}\"\ncontent=\"${content//$'\\r'/'%0D'}\"\n```\nare necessary due to [a bug in Github Actions](https://github.community/t/set-output-truncates-multiline-strings/16852) \nthat prevents multiple lines from being passed to `set-output`.\n\n### Project Structure\n\nYou will need to put a file called `downstream.yml` in the directory with the file you'd like to attach documentation \nto.\n```\nSources/Downstream/\n├── Associations.swift\n├── downstream.yml\n└── main.swift\n```\n\n`downstream.yml` will need to contain a `[String: [String]]` dictionary where the keys are file names in that directory\nand values are links/paths/wherever users can find documentation that relies on that file. Anything under a \"\\*\" will \nwork as an asociation for the entire directory.\n\n```yaml\nassociations:\n  main.swift:\n    - https://github.com/JohnSundell/Files/blob/master/Sources/Files.swift\n    - https://github.com/twof/Downstream/edit/main/README.md\n  Associations.swift:\n    - https://github.com/twof/Downstream/edit/main/README.md\n  *:\n    - https://docs.downstream.io/usage\n```\n\nThe hook is only capable of failing if a `downstream.yml` is invalid. Otherwise it only exists to provide information. \nGiven the above example, if `Associations.swift` was changed, output would look like this\n\n```\n$ git commit -am \"bumped pre-commit hook\"\nDownstream...............................................................Passed\n- hook id: downstream\n- duration: 1.19s\n\nDue to changes made to Sources/downstream/main.swift, you may need to make updates to the following:\nhttps://github.com/twof/Downstream/blob/main/README.md\n\n[main b5db130] bumped pre-commit hook\n 2 files changed, 1 insertion(+), 2 deletions(-)\n```\n\n### Usage\n\nBeyond its usage as a pre-commit hook, Downstream can also be executed manually for integration with CI and whatnot like \ncan be seen above with Github Actions. It can currently produce output based on the format requested by the user with \nthe `-o` flag. Possible options are `human` for human friendly output like seen in the example above, `yaml`, `json`, \nand `list` which simply lists out all of the docs that may need updates in a format that's convenient for intake in a \nbash script.\n\n```\n$ downstream -h\nUSAGE: downstream-argument [--output-format \u003coutput-format\u003e] [\u003cfiles\u003e ...]\n\nARGUMENTS:\n\u003cfiles\u003e                 Input files\n\nOPTIONS:\n-o, --output-format \u003coutput-format\u003e\nThe format of the output\n-h, --help              Show help information.\n```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftwof%2Fdownstream","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftwof%2Fdownstream","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftwof%2Fdownstream/lists"}