{"id":44666036,"url":"https://github.com/xonixx/fhtagn","last_synced_at":"2026-02-15T00:33:28.304Z","repository":{"id":167681658,"uuid":"643306795","full_name":"xonixx/fhtagn","owner":"xonixx","description":"Literate testing for command-line programs","archived":false,"fork":false,"pushed_at":"2026-01-30T23:19:48.000Z","size":99,"stargazers_count":39,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-01-31T14:58:03.483Z","etag":null,"topics":["awk","shell","testing-tools"],"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/xonixx.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":"2023-05-20T18:38:45.000Z","updated_at":"2026-01-30T23:19:20.000Z","dependencies_parsed_at":null,"dependency_job_id":"92b7afda-e277-4759-bd97-d43eccc0fe48","html_url":"https://github.com/xonixx/fhtagn","commit_stats":null,"previous_names":["xonixx/fhtagn"],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/xonixx/fhtagn","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xonixx%2Ffhtagn","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xonixx%2Ffhtagn/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xonixx%2Ffhtagn/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xonixx%2Ffhtagn/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/xonixx","download_url":"https://codeload.github.com/xonixx/fhtagn/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xonixx%2Ffhtagn/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29461911,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-14T22:42:09.113Z","status":"ssl_error","status_checked_at":"2026-02-14T22:42:05.053Z","response_time":53,"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":["awk","shell","testing-tools"],"created_at":"2026-02-15T00:33:27.165Z","updated_at":"2026-02-15T00:33:28.299Z","avatar_url":"https://github.com/xonixx.png","language":"Shell","readme":"[![Stand With Ukraine](https://raw.githubusercontent.com/vshymanskyy/StandWithUkraine/main/banner-direct-single.svg)](https://stand-with-ukraine.pp.ua)\n\n# fhtagn\n\n[![Run tests](https://github.com/xonixx/fhtagn/actions/workflows/run-tests.yml/badge.svg)](https://github.com/xonixx/fhtagn/actions/workflows/run-tests.yml)\n![coverage](coverage.svg)\n                    \n`fhtagn.awk` is a tiny CLI tool for literate testing for command-line programs.  \n                   \nFile `tests.fhtagn`:\n```\n$ command --that --should --execute correctly\n| expected stdout output\n\n$ command --that --will --cause error\n@ expected stderr output\n? expected-exit-code\n```\n\nRun the tests:\n```sh\n./fhtagn.awk tests.fhtagn\n```\n\nIn fact, this is a re-implementation of [darius/tush](https://github.com/darius/tush), [adolfopa/tush](https://github.com/adolfopa/tush).\nBut simpler (single tiny AWK script) and faster, because:\n                      \n- it uses `/dev/shm` where available instead of `/tmp`\n- it compares the expected result with the actual in the code and only calls `diff` to show the difference if they don't match\n- it doesn't create a sandbox folder for each test\n- it doesn't use `mktemp` but rather generates random name in the code\n\n## Usage\n\n```sh\n./fhtagn.awk f1.fhtagn [ f2.fhtagn [ f3.fhtagn [...] ] ]\n```\nThis will stop on the first error found.\n\nExample:\n```\n$ ./fhtagn.awk tests/1.fhtagn tests/2.fhtagn tests/3.fhtagn \ntests/2.fhtagn:12: $ echo \"hello world\"; echo \"error msg\" \u003e\u00262; exit 7\n--- expected\n+++ actual\n@@ -1,4 +1,4 @@\n | hello world\n-@ error msg 444\n-? 8\n+@ error msg\n+? 7\n \n```\n\n### Fail at the end\n      \nSet `ALL=1` environment variable.\n\nThis runs all tests, collects all errors, and shows the stats at the end.\n```sh\nALL=1 ./fhtagn.awk f1.fhtagn [ f2.fhtagn [ f3.fhtagn [...] ] ]\n```\n\nUseful for running in CI.\n\nExample:\n```\n$ ALL=1 ./fhtagn.awk tests/1.fhtagn tests/2.fhtagn tests/3.fhtagn \ntests/2.fhtagn:12: $ echo \"hello world\"; echo \"error msg\" \u003e\u00262; exit 7\n--- expected\n+++ actual\n@@ -1,4 +1,4 @@\n | hello world\n-@ error msg 444\n-? 8\n+@ error msg\n+? 7\n \ntests/3.fhtagn:7: $ echo bbb\n--- expected\n+++ actual\n@@ -1,2 +1,2 @@\n-| BBB\n+| bbb\n \nresult=FAIL, failure=2, success=4, total=6, files=3\n```\n\n### Parameterized tests\n\nYou can use variable substitution to parametrize tests. This works like so:\n\n```\n# in your .fhtagn file you have\n\n$ command {{VAR1}} '{{VAR2}}'\n| expected output\n```\n\nAnd you run it like so:\n\n```sh\n./fhtagn.awk tests.fhtagn VAR1=value VAR2='other value'\n```\n\nThe example use case here is to check the correctness of the same command when ran by different versions of a programming language. This is what we do to test fhtagn itself with different AWKs: [link1](https://github.com/xonixx/fhtagn/blob/c3986e11757a05b8b3932b4eec204cbfdb31874b/tests/fhtagn.tush#L2), [link2](https://github.com/xonixx/fhtagn/blob/c3986e11757a05b8b3932b4eec204cbfdb31874b/Makesurefile#L74), [link3](https://github.com/xonixx/fhtagn/blob/c3986e11757a05b8b3932b4eec204cbfdb31874b/Makesurefile#L53).\n\nNote that in case of test failure, you will see an expanded command line, which is helpful for debugging.\n\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxonixx%2Ffhtagn","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fxonixx%2Ffhtagn","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxonixx%2Ffhtagn/lists"}