patchy-cli 0.0.2-pr.115.296bb27
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +152 -0
- package/bin/patchy.cjs +84 -0
- package/package.json +72 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Richard Gill
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
# patchy
|
|
2
|
+
|
|
3
|
+
An opinionated command-line tool for managing Git patch workflows.
|
|
4
|
+
|
|
5
|
+
**patchy** helps you maintain a curated set of patches—both added files and diffs—against an upstream Git repository.
|
|
6
|
+
|
|
7
|
+
## Quick Start
|
|
8
|
+
|
|
9
|
+
Run this command to initialize a new patch project:
|
|
10
|
+
|
|
11
|
+
```sh
|
|
12
|
+
patchy init
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
This will set up the necessary directory structure and configuration file for your patch workflow.
|
|
16
|
+
|
|
17
|
+
## Directory Structure
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
my-patch-repo/
|
|
21
|
+
├── patches/
|
|
22
|
+
│ ├── path/in/repo/newFile.ts # new file
|
|
23
|
+
│ ├── path/in/repo/oldFile.ts.diff # diff file
|
|
24
|
+
├── patchy.json # optional config
|
|
25
|
+
|
|
26
|
+
repo-dir/
|
|
27
|
+
├── path/in/repo/newFile.ts # will be copied from patches/
|
|
28
|
+
├── path/in/repo/oldFile.ts # original file, to be patched
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
File layout must mirror the structure of `repo_dir`.
|
|
32
|
+
|
|
33
|
+
## Installation
|
|
34
|
+
|
|
35
|
+
**Install script (recommended):**
|
|
36
|
+
|
|
37
|
+
```sh
|
|
38
|
+
curl -fsSL https://raw.githubusercontent.com/richardgill/patchy/main/install | bash
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
**Via npm:**
|
|
42
|
+
|
|
43
|
+
```sh
|
|
44
|
+
npm install -g patchy-cli
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Or use directly without installing:
|
|
48
|
+
|
|
49
|
+
```sh
|
|
50
|
+
npx patchy-cli --version
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Shared Flags
|
|
54
|
+
|
|
55
|
+
These flags are accepted by **all commands**:
|
|
56
|
+
|
|
57
|
+
| CLI Flag | Env Variable | Description |
|
|
58
|
+
| ----------------- | ---------------------- | ------------------------------------------------ |
|
|
59
|
+
| `--repo-dir` | `PATCHY_REPO_DIR` | Path to the Git repo you're patching |
|
|
60
|
+
| `--repo-base-dir` | `PATCHY_REPO_BASE_DIR` | Parent directory where upstream repos are cloned |
|
|
61
|
+
| `--patches-dir` | `PATCHY_PATCHES_DIR` | Path to your patch files (default: `./patches/`) |
|
|
62
|
+
| `--config` | `PATCHY_CONFIG` | JSON config file (default: `patchy.json`) |
|
|
63
|
+
| `--verbose` | `PATCHY_VERBOSE` | Enable verbose log output |
|
|
64
|
+
| `--dry-run` | `PATCHY_DRY_RUN` | Simulate the command without writing files |
|
|
65
|
+
|
|
66
|
+
> CLI flags override all values in `patchy.json`.
|
|
67
|
+
|
|
68
|
+
## Commands
|
|
69
|
+
|
|
70
|
+
### `patchy apply`
|
|
71
|
+
|
|
72
|
+
Apply patch files from `patches/` into `repo_dir`.
|
|
73
|
+
|
|
74
|
+
```sh
|
|
75
|
+
patchy apply [--repo-dir] [--patches-dir] [--dry-run]
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### `patchy generate`
|
|
79
|
+
|
|
80
|
+
Generate `.diff` files and new full files into `./patches/` based on current `git diff` in `repo_dir`.
|
|
81
|
+
|
|
82
|
+
```sh
|
|
83
|
+
patchy generate [--repo-dir] [--patches-dir] [--dry-run]
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### `patchy repo reset`
|
|
87
|
+
|
|
88
|
+
Hard reset the Git working tree of `repo_dir`. Discards local changes.
|
|
89
|
+
|
|
90
|
+
```sh
|
|
91
|
+
patchy repo reset [--repo-dir]
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### `patchy repo checkout --ref <git-ref>`
|
|
95
|
+
|
|
96
|
+
Check out a specific Git ref (branch, tag, or SHA) in `repo_dir`.
|
|
97
|
+
|
|
98
|
+
```sh
|
|
99
|
+
patchy repo checkout --ref main [--repo-dir]
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### `patchy repo clone --url <git-url>`
|
|
103
|
+
|
|
104
|
+
Clone a repository into a subdirectory of `repo_base_dir`. The target directory is derived from the repo name.
|
|
105
|
+
|
|
106
|
+
```sh
|
|
107
|
+
patchy repo clone [--repo-base-dir] [--ref] [--repo-url]
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## Configuration (`patchy.json`)
|
|
111
|
+
|
|
112
|
+
Optional file to set default values:
|
|
113
|
+
|
|
114
|
+
```json
|
|
115
|
+
{
|
|
116
|
+
"repo_url": "https://github.com/richardgill/upstream.git",
|
|
117
|
+
"repo_dir": "upstream-repo",
|
|
118
|
+
"repo_base_dir": "../clones",
|
|
119
|
+
"patches_dir": "patches/",
|
|
120
|
+
"ref": "main"
|
|
121
|
+
}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
All options may be set with environment variables as well e.g. `PATCHY_REPO_URL`.
|
|
125
|
+
|
|
126
|
+
### Precedence Order
|
|
127
|
+
|
|
128
|
+
1. CLI flags
|
|
129
|
+
2. Environment variables
|
|
130
|
+
3. `--config` (defaults to `./patchy.json`)
|
|
131
|
+
|
|
132
|
+
## Example Workflow
|
|
133
|
+
|
|
134
|
+
```sh
|
|
135
|
+
# Clone the upstream repo
|
|
136
|
+
patchy repo clone --repo-url https://github.com/richardgill/upstream.git --repo-base-dir ../clones
|
|
137
|
+
|
|
138
|
+
# Check out upstream repo at a specific version
|
|
139
|
+
patchy repo checkout --ref v1.2.3 --repo-dir ../clones/upstream
|
|
140
|
+
|
|
141
|
+
# Generate patches from current state of repo_dir
|
|
142
|
+
patchy generate --repo-dir ../clones/upstream
|
|
143
|
+
|
|
144
|
+
# Later, apply patches cleanly to fresh repo
|
|
145
|
+
patchy repo reset --repo-dir ../clones/upstream
|
|
146
|
+
patchy repo checkout --ref main --repo-dir upstream
|
|
147
|
+
patchy apply --repo-dir ../clones/upstream
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
## License
|
|
151
|
+
|
|
152
|
+
MIT
|
package/bin/patchy.cjs
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const childProcess = require("child_process");
|
|
4
|
+
const fs = require("fs");
|
|
5
|
+
const path = require("path");
|
|
6
|
+
const os = require("os");
|
|
7
|
+
|
|
8
|
+
const run = (target) => {
|
|
9
|
+
const result = childProcess.spawnSync(target, process.argv.slice(2), {
|
|
10
|
+
stdio: "inherit",
|
|
11
|
+
});
|
|
12
|
+
if (result.error) {
|
|
13
|
+
console.error(result.error.message);
|
|
14
|
+
process.exit(1);
|
|
15
|
+
}
|
|
16
|
+
const code = typeof result.status === "number" ? result.status : 0;
|
|
17
|
+
process.exit(code);
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
const envPath = process.env.PATCHY_BIN_PATH;
|
|
21
|
+
if (envPath) {
|
|
22
|
+
run(envPath);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const scriptPath = fs.realpathSync(__filename);
|
|
26
|
+
const scriptDir = path.dirname(scriptPath);
|
|
27
|
+
|
|
28
|
+
const platformMap = {
|
|
29
|
+
darwin: "darwin",
|
|
30
|
+
linux: "linux",
|
|
31
|
+
win32: "windows",
|
|
32
|
+
};
|
|
33
|
+
const archMap = {
|
|
34
|
+
x64: "x64",
|
|
35
|
+
arm64: "arm64",
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
let platform = platformMap[os.platform()];
|
|
39
|
+
if (!platform) {
|
|
40
|
+
platform = os.platform();
|
|
41
|
+
}
|
|
42
|
+
let arch = archMap[os.arch()];
|
|
43
|
+
if (!arch) {
|
|
44
|
+
arch = os.arch();
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const base = "patchy-cli-" + platform + "-" + arch;
|
|
48
|
+
const binary = platform === "windows" ? "patchy.exe" : "patchy";
|
|
49
|
+
|
|
50
|
+
const findBinary = (startDir) => {
|
|
51
|
+
let current = startDir;
|
|
52
|
+
for (;;) {
|
|
53
|
+
const modules = path.join(current, "node_modules");
|
|
54
|
+
if (fs.existsSync(modules)) {
|
|
55
|
+
const entries = fs.readdirSync(modules);
|
|
56
|
+
for (const entry of entries) {
|
|
57
|
+
if (!entry.startsWith(base)) {
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
const candidate = path.join(modules, entry, "bin", binary);
|
|
61
|
+
if (fs.existsSync(candidate)) {
|
|
62
|
+
return candidate;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
const parent = path.dirname(current);
|
|
67
|
+
if (parent === current) {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
current = parent;
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
const resolved = findBinary(scriptDir);
|
|
75
|
+
if (!resolved) {
|
|
76
|
+
console.error(
|
|
77
|
+
'Could not find the patchy binary for your platform. Try manually installing "' +
|
|
78
|
+
base +
|
|
79
|
+
'"',
|
|
80
|
+
);
|
|
81
|
+
process.exit(1);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
run(resolved);
|
package/package.json
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "patchy-cli",
|
|
3
|
+
"version": "0.0.2-pr.115.296bb27",
|
|
4
|
+
"description": "A CLI tool for managing Git patch workflows.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"patchy": "./bin/patchy.cjs"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"bin"
|
|
11
|
+
],
|
|
12
|
+
"scripts": {
|
|
13
|
+
"build": "bun run ./scripts/build.ts",
|
|
14
|
+
"build-single": "bun run ./scripts/build.ts --single",
|
|
15
|
+
"check": "biome check --error-on-warnings --diagnostic-level=warn",
|
|
16
|
+
"check-fix": "biome check --write --error-on-warnings --diagnostic-level=warn",
|
|
17
|
+
"changeset": "changeset",
|
|
18
|
+
"changeset-version": "changeset version",
|
|
19
|
+
"dev": "bun run src/cli.ts",
|
|
20
|
+
"local-ci": "concurrently --group -p none -n 'check,typecheck,test' 'bun run check-fix' 'bun run typecheck' 'bun run test'",
|
|
21
|
+
"prepare": "[ -n \"$CI\" ] || lefthook install",
|
|
22
|
+
"typecheck": "tsgo --noEmit",
|
|
23
|
+
"test": "bun run scripts/test.ts",
|
|
24
|
+
"test-watch": "bun test --watch",
|
|
25
|
+
"test-coverage": "bun test --coverage"
|
|
26
|
+
},
|
|
27
|
+
"devDependencies": {
|
|
28
|
+
"@biomejs/biome": "2.1.1",
|
|
29
|
+
"@changesets/changelog-github": "^0.5.1",
|
|
30
|
+
"@changesets/cli": "^2.29.5",
|
|
31
|
+
"@types/node": "^24.0.13",
|
|
32
|
+
"@typescript/native-preview": "7.0.0-dev.20250712.1",
|
|
33
|
+
"bun-types": "^1.3.4",
|
|
34
|
+
"concurrently": "^9.2.0",
|
|
35
|
+
"lefthook": "^1.12.2",
|
|
36
|
+
"typescript": "^5.9.2"
|
|
37
|
+
},
|
|
38
|
+
"dependencies": {
|
|
39
|
+
"@clack/prompts": "^0.11.0",
|
|
40
|
+
"@stricli/core": "^1.2.0",
|
|
41
|
+
"chalk": "^5.4.1",
|
|
42
|
+
"diff": "^8.0.2",
|
|
43
|
+
"es-toolkit": "^1.39.8",
|
|
44
|
+
"jsonc-parser": "^3.3.1",
|
|
45
|
+
"simple-git": "^3.30.0",
|
|
46
|
+
"ts-essentials": "^10.1.1",
|
|
47
|
+
"zod": "^4.0.13"
|
|
48
|
+
},
|
|
49
|
+
"peerDependencies": {
|
|
50
|
+
"typescript": ">=5.0.4"
|
|
51
|
+
},
|
|
52
|
+
"peerDependenciesMeta": {
|
|
53
|
+
"typescript": {
|
|
54
|
+
"optional": true
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
"license": "MIT",
|
|
58
|
+
"repository": {
|
|
59
|
+
"url": "https://github.com/richardgill/patchy"
|
|
60
|
+
},
|
|
61
|
+
"optionalDependencies": {
|
|
62
|
+
"patchy-cli-linux-x64": "0.0.2-pr.115.296bb27",
|
|
63
|
+
"patchy-cli-linux-arm64": "0.0.2-pr.115.296bb27",
|
|
64
|
+
"patchy-cli-darwin-x64": "0.0.2-pr.115.296bb27",
|
|
65
|
+
"patchy-cli-darwin-arm64": "0.0.2-pr.115.296bb27",
|
|
66
|
+
"patchy-cli-windows-x64": "0.0.2-pr.115.296bb27"
|
|
67
|
+
},
|
|
68
|
+
"publishConfig": {
|
|
69
|
+
"access": "public"
|
|
70
|
+
},
|
|
71
|
+
"packageManager": "bun@1.3.4"
|
|
72
|
+
}
|