{"id":15525280,"url":"https://github.com/donatj/ttouch","last_synced_at":"2026-05-10T21:47:42.177Z","repository":{"id":57602309,"uuid":"138644223","full_name":"donatj/ttouch","owner":"donatj","description":"Unix `touch` with JavaScript programmable templates. (I'm aware it's insane)","archived":false,"fork":false,"pushed_at":"2024-05-13T22:57:50.000Z","size":66,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-01-11T16:49:09.096Z","etag":null,"topics":["template","touch","unix"],"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/donatj.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","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}},"created_at":"2018-06-25T20:06:24.000Z","updated_at":"2024-05-13T22:57:54.000Z","dependencies_parsed_at":"2024-05-13T23:32:02.026Z","dependency_job_id":"511ca708-b863-47be-8ff9-a56b1a90c6a9","html_url":"https://github.com/donatj/ttouch","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/donatj%2Fttouch","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/donatj%2Fttouch/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/donatj%2Fttouch/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/donatj%2Fttouch/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/donatj","download_url":"https://codeload.github.com/donatj/ttouch/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241299514,"owners_count":19940483,"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":["template","touch","unix"],"created_at":"2024-10-02T10:56:16.792Z","updated_at":"2026-05-10T21:47:42.169Z","avatar_url":"https://github.com/donatj.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ttouch\n\n[![Go Report Card](https://goreportcard.com/badge/github.com/donatj/ttouch)](https://goreportcard.com/report/github.com/donatj/ttouch)\n[![GoDoc](https://godoc.org/github.com/donatj/ttouch?status.svg)](https://godoc.org/github.com/donatj/ttouch)\n[![CI](https://github.com/donatj/ttouch/actions/workflows/ci.yml/badge.svg)](https://github.com/donatj/ttouch/actions/workflows/ci.yml)\n\nUnix `touch` with JavaScript templates. Creates files with context-aware boilerplate instead of empty content.\n\n## Features\n\n- Generates content based on file extension, name, and project context\n- JavaScript templates (ES2023) with file system access\n- Per-project or global template customization\n- Built-in templates for common file types\n- Fast, lightweight Go binary\n\n## Installation\n\n```bash\ngo install github.com/donatj/ttouch/cmd/ttouch@latest\n```\n\n## Quick Start\n\nCreate a shell script:\n\n```bash\nttouch script.sh\n```\n\nGenerates:\n```sh\n#!/bin/sh\n\nset -e\n\n```\n\nCreate a Go file (detects package from existing files):\n\n```bash\nttouch helper.go\n```\n\nResult with existing `package myapp`:\n```go\npackage myapp\n\n```\n\nCreate executable:\n\n```bash\nttouch -e deploy.sh\n```\n\n## Usage\n\n```\nttouch [flags] \u003cfile\u003e...\n```\n\nFlags:\n- `-f` - Overwrite if file exists\n- `-e` - Make executable\n\nExamples:\n\n```bash\n# Create new file\nttouch README.md\n\n# Create multiple files\nttouch script.sh helper.go utils.js\n\n# Create executable\nttouch -e deploy.py\n\n# Overwrite existing file\nttouch -f existing-script.sh\n```\n\n## Templates\n\nUses [modernc.org/quickjs](https://pkg.go.dev/modernc.org/quickjs) JavaScript runtime (ES2023).\n\n### Template Discovery\n\nTemplates live in `.ttouch` directories. Search starts in current directory and walks up to root (like `.git`).\n\nNaming:\n- `{ext}.js` - Matches extension (e.g., `py.js` for `*.py`)\n- `{filename}.js` - Matches filename (e.g., `readme.md.js` for `README.md`)\n\nFilename matches take precedence over extension matches.\n\nSearch order:\n1. `.ttouch/{filename}.js` in current directory\n2. `.ttouch/{filename}.js` in parent directories\n3. `.ttouch/{ext}.js` in current directory\n4. `.ttouch/{ext}.js` in parent directories\n5. Built-in templates\n\n### Writing Templates\n\nMinimal template:\n\n```js\n\"#!/bin/sh\\n\";\n```\n\nWith IIFE:\n\n```js\n(function () {\n\treturn \"#!/bin/sh\\n\";\n})();\n```\n\nArrow function:\n\n```js\n(() =\u003e {\n\treturn \"#!/usr/bin/env python3\\n\\ndef main():\\n    pass\\n\";\n})();\n```\n\nTemplate value is the last expression in the file.\n\n### VM Object\n\nTemplates access file information via `VM`:\n\n```js\n{\n  \"Filename\": \"script.sh\",           // Relative path\n  \"AbsFilename\": \"/home/user/...\",   // Absolute path\n  \"Flags\": {                         // CLI flags\n    \"Executable\": false,\n    \"Overwrite\": true,\n    \"Files\": [\"script.sh\"]\n  }\n}\n```\n\nExample:\n\n```js\n(() =\u003e {\n    if (VM.Flags.Executable) {\n        return \"#!/usr/bin/env python3\\n\\n# Executable script\\n\";\n    }\n    return \"# Python module\\n\";\n})();\n```\n\n### Helper Functions\n\n#### `ReadFile(path)`\nRead file contents.\n\n```js\nconst content = ReadFile(\"package.json\");\nconst pkg = JSON.parse(content);\n```\n\n#### `Glob(pattern)`\nMatch files by pattern.\n\n```js\nconst goFiles = Glob(\"*.go\");\n```\n\n#### `ScanUp(filename)`\nFind file in current or parent directories.\n\n```js\nconst configs = ScanUp(\"package.json\");\n```\n\n#### `SplitPath(path)`\nSplit path into `[directory, filename]`.\n\n```js\nconst [dir, file] = SplitPath(VM.AbsFilename);\n```\n\n#### `Log(...args)`\nDebug output.\n\n```js\nLog(\"Creating file:\", VM.Filename);\n```\n\n### Built-in Templates\n\n- [dot.js](https://github.com/donatj/ttouch/blob/master/templates/dot.js) - Dotfiles\n- [go.js](https://github.com/donatj/ttouch/blob/master/templates/go.js) - Go files with package detection\n- [md.js](https://github.com/donatj/ttouch/blob/master/templates/md.js) - Markdown with directory heading\n- [php.js](https://github.com/donatj/ttouch/blob/master/templates/php.js) - PHP with PSR-4 namespaces\n- [sh.js](https://github.com/donatj/ttouch/blob/master/templates/sh.js) - Shell scripts\n\n## Custom Templates\n\nCreate `.ttouch/py.js`:\n\n```js\n(() =\u003e {\n    let content = \"#!/usr/bin/env python3\\n\";\n    content += '\"\"\"Module docstring.\"\"\"\\n\\n';\n    \n    if (VM.Filename.includes(\"test_\")) {\n        content += \"import unittest\\n\\n\";\n        content += \"class TestCase(unittest.TestCase):\\n\";\n        content += \"    def test_example(self):\\n\";\n        content += \"        pass\\n\\n\";\n        content += 'if __name__ == \"__main__\":\\n';\n        content += \"    unittest.main()\\n\";\n    } else {\n        content += \"def main():\\n\";\n        content += \"    pass\\n\\n\";\n        content += 'if __name__ == \"__main__\":\\n';\n        content += \"    main()\\n\";\n    }\n    \n    return content;\n})();\n```\n\nRun `ttouch test_utils.py` for unittest template, `ttouch utils.py` for standard module.\n\n## Use Cases\n\n- Scaffold files with correct headers and imports\n- Maintain consistent file structure across teams\n- Generate boilerplate that adapts to existing code\n- Learn language file conventions\n- Automate multi-file generation\n\n## Tips\n\n- Use `Log()` for debugging\n- Start with static templates, add logic later\n- Review [built-in templates](https://github.com/donatj/ttouch/tree/master/templates) for examples\n- Commit `.ttouch` directory for team sharing\n- Place common templates in parent directories for project-wide use\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdonatj%2Fttouch","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdonatj%2Fttouch","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdonatj%2Fttouch/lists"}