@osdlc/repo-cleaner 0.17.2 → 0.19.0
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/CHANGELOG.md +31 -0
- package/README.md +691 -305
- package/dist/branches.d.ts +37 -36
- package/dist/branches.js +199 -196
- package/dist/clean.d.ts +179 -0
- package/dist/clean.js +824 -0
- package/dist/cli.d.ts +12 -16
- package/dist/cli.js +367 -478
- package/dist/hooks.d.ts +8 -12
- package/dist/hooks.js +2 -2
- package/dist/index.d.ts +18 -25
- package/dist/index.js +16 -23
- package/dist/landing.d.ts +3 -3
- package/dist/landing.js +7 -7
- package/dist/plan.d.ts +76 -70
- package/dist/plan.js +82 -77
- package/dist/providers/github.d.ts +2 -1
- package/dist/providers/github.js +2 -1
- package/dist/providers/gitlab.d.ts +3 -2
- package/dist/providers/gitlab.js +14 -8
- package/dist/providers/index.d.ts +5 -4
- package/dist/providers/index.js +8 -5
- package/dist/providers/types.d.ts +8 -2
- package/dist/prs.d.ts +35 -7
- package/dist/prs.js +45 -12
- package/dist/receipt.d.ts +46 -57
- package/dist/receipt.js +52 -28
- package/dist/reference.d.ts +12 -0
- package/dist/reference.js +152 -0
- package/dist/remote-mirror.d.ts +9 -1
- package/dist/remote-mirror.js +19 -1
- package/dist/render.d.ts +66 -61
- package/dist/render.js +206 -255
- package/dist/resolve.d.ts +3 -3
- package/dist/resolve.js +4 -12
- package/dist/status-line.d.ts +1 -1
- package/dist/status-line.js +5 -5
- package/dist/step-board.d.ts +1 -1
- package/dist/step-board.js +2 -5
- package/dist/submodules.d.ts +120 -0
- package/dist/submodules.js +292 -0
- package/dist/sweep.d.ts +107 -64
- package/dist/sweep.js +333 -119
- package/dist/types.d.ts +294 -105
- package/dist/types.js +106 -54
- package/dist/util.d.ts +13 -0
- package/dist/util.js +36 -0
- package/dist/version.generated.d.ts +1 -1
- package/dist/version.generated.js +1 -1
- package/dist/worktrees.d.ts +21 -37
- package/dist/worktrees.js +198 -165
- package/package.json +5 -5
- package/dist/apply.d.ts +0 -131
- package/dist/apply.js +0 -541
package/dist/clean.d.ts
ADDED
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cleaning up: `check` a plan against an approval, then `run` what it shows.
|
|
3
|
+
*
|
|
4
|
+
* `check` resolves the approval (the rows picked, the rows spared, the risks
|
|
5
|
+
* allowed), refuses one that contradicts itself, sweeps every plan repository
|
|
6
|
+
* again and drops each selected row that is gone, cannot be deleted, moved
|
|
7
|
+
* since the plan, or carries a risk not allowed. It returns the steps a run
|
|
8
|
+
* would take. `run` sweeps once more and takes those steps in a fixed order,
|
|
9
|
+
* stopping at the first failure:
|
|
10
|
+
*
|
|
11
|
+
* 1. spared remote branches, each tip checked with `ls-remote`;
|
|
12
|
+
* 2. worktrees, each unlocked first when its lock's owner is dead, and each
|
|
13
|
+
* checked again for live processes just before it is unlocked or removed;
|
|
14
|
+
* one with submodules is removed with `--force` after its files and every
|
|
15
|
+
* submodule are checked again;
|
|
16
|
+
* 3. local branches;
|
|
17
|
+
* 4. remote branches.
|
|
18
|
+
*
|
|
19
|
+
* A worktree whose directory is gone goes by its own record. One left without
|
|
20
|
+
* its `.git` takes the repository-wide prune, last, and only while that prune
|
|
21
|
+
* would drop nothing the run does not select.
|
|
22
|
+
*
|
|
23
|
+
* Branch deletes are compare-and-swap on the planned sha. Every step is
|
|
24
|
+
* verified, and the receipt is rewritten after each.
|
|
25
|
+
*/
|
|
26
|
+
import type { Annotate } from './hooks.ts';
|
|
27
|
+
import { type Plan } from './plan.ts';
|
|
28
|
+
import { type Dropped, type Receipt, type Step } from './receipt.ts';
|
|
29
|
+
import { type Runners } from './sweep.ts';
|
|
30
|
+
import { type Kind, type Risk, type RowId, type Sweep, type SweepProgress, type SweptWith, type RepoNote } from './types.ts';
|
|
31
|
+
/** A risk allowed for every row (`row` absent), or for one row. */
|
|
32
|
+
export interface Allow {
|
|
33
|
+
risk: Risk;
|
|
34
|
+
/** A row id or bare name, resolved as a pick is. */
|
|
35
|
+
row?: string | undefined;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* What a person approved. Rows are named by id (`branch:feat/x`), or by a
|
|
39
|
+
* bare name or path when only one plan row has it.
|
|
40
|
+
*
|
|
41
|
+
* `pick` work on exactly these rows; a `review` row, or a `keep` row with
|
|
42
|
+
* an action, runs only when picked. Default: every `delete` row.
|
|
43
|
+
* `spare` leave these rows alone; a spared remote branch is still checked,
|
|
44
|
+
* and the run stops if it moved or is gone since the plan.
|
|
45
|
+
* `allow` the risks a row's action may carry.
|
|
46
|
+
*/
|
|
47
|
+
export interface Approval {
|
|
48
|
+
pick?: readonly string[] | undefined;
|
|
49
|
+
spare?: readonly string[] | undefined;
|
|
50
|
+
allow?: readonly (Risk | Allow)[] | undefined;
|
|
51
|
+
}
|
|
52
|
+
/** A row reference resolved to one plan row. */
|
|
53
|
+
export interface Resolved {
|
|
54
|
+
repo: string;
|
|
55
|
+
id: RowId;
|
|
56
|
+
}
|
|
57
|
+
/** An approval with every row resolved to its plan row. */
|
|
58
|
+
export interface ResolvedApproval {
|
|
59
|
+
pick: Resolved[];
|
|
60
|
+
spare: Resolved[];
|
|
61
|
+
allow: {
|
|
62
|
+
risk: Risk;
|
|
63
|
+
row: Resolved | null;
|
|
64
|
+
}[];
|
|
65
|
+
}
|
|
66
|
+
interface Shared extends Runners {
|
|
67
|
+
/** Where the caller stands: the base for relative worktree paths, and a worktree never removed. Defaults to the process's cwd. */
|
|
68
|
+
cwd?: string | undefined;
|
|
69
|
+
/** A host's re-ranking, applied to every re-sweep as the sweep applied it. */
|
|
70
|
+
annotate?: Annotate | undefined;
|
|
71
|
+
/** Told what the re-sweep is doing, for a status line. */
|
|
72
|
+
onProgress?: ((progress: SweepProgress) => void) | undefined;
|
|
73
|
+
}
|
|
74
|
+
export interface CheckOptions extends Shared {
|
|
75
|
+
/**
|
|
76
|
+
* A sweep made just now, used as the re-check instead of sweeping again: for
|
|
77
|
+
* a preview straight after a sweep. A repository whose remote rows it read
|
|
78
|
+
* from disk (offline) is swept again, asking the remote. `run` always sweeps
|
|
79
|
+
* again.
|
|
80
|
+
*/
|
|
81
|
+
sweep?: Sweep | undefined;
|
|
82
|
+
/** Where remote URL clones are kept; a plan repository there must still push only where it fetches from. */
|
|
83
|
+
cacheDir?: string | undefined;
|
|
84
|
+
}
|
|
85
|
+
export interface RunOptions extends Shared {
|
|
86
|
+
/** Where the receipt is rewritten after each step; none when absent. */
|
|
87
|
+
receiptPath?: string | undefined;
|
|
88
|
+
/** Where the plan came from, recorded in the receipt. Default `(memory)`. */
|
|
89
|
+
source?: string | undefined;
|
|
90
|
+
now?: (() => Date) | undefined;
|
|
91
|
+
/** Told once the steps are known, before the first runs; each step's `result` is updated in place. */
|
|
92
|
+
onStart?: ((steps: readonly Step[]) => void) | undefined;
|
|
93
|
+
/** Told before each step: its index, the step count and the step. */
|
|
94
|
+
onStep?: ((index: number, total: number, step: Step) => void) | undefined;
|
|
95
|
+
/** Told after each step, with its `result` set, before the receipt is saved. */
|
|
96
|
+
onStepDone?: ((index: number, total: number, step: Step) => void) | undefined;
|
|
97
|
+
/**
|
|
98
|
+
* Told the run's own re-check's notes, before the first step: what it judged
|
|
99
|
+
* without. The re-check may differ from the preview's, for example when a
|
|
100
|
+
* listing fails only at the run.
|
|
101
|
+
*/
|
|
102
|
+
onNotes?: ((notes: RepoNote[]) => void) | undefined;
|
|
103
|
+
}
|
|
104
|
+
/** What a run would do, for a person to approve: the steps, and the rows dropped and why. */
|
|
105
|
+
export interface Preview {
|
|
106
|
+
plan: Plan;
|
|
107
|
+
approval: ResolvedApproval;
|
|
108
|
+
/** Each with `result: 'would-run'`. */
|
|
109
|
+
steps: Step[];
|
|
110
|
+
dropped: Dropped[];
|
|
111
|
+
/** Allowed risks no row that runs carries. Not an error: what a row carries can change between runs. */
|
|
112
|
+
unusedAllows: {
|
|
113
|
+
risk: Risk;
|
|
114
|
+
row: RowId | null;
|
|
115
|
+
}[];
|
|
116
|
+
/**
|
|
117
|
+
* `RepoSweep.notes`, with each repository's root: what the re-check judged
|
|
118
|
+
* without. With a sweep passed in (`CheckOptions.sweep`), every repository
|
|
119
|
+
* of that sweep; otherwise each plan repository the re-check swept again.
|
|
120
|
+
*/
|
|
121
|
+
notes: RepoNote[];
|
|
122
|
+
}
|
|
123
|
+
/** A row reference as typed: a kind and a name, or a bare name (`kind: null`). */
|
|
124
|
+
export interface RowRef {
|
|
125
|
+
kind: Kind | null;
|
|
126
|
+
name: string;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* `kind:name`, or a bare name. A word before a colon that is not a kind is an
|
|
130
|
+
* error (a typo such as `wt:x`), but a path is a bare name whatever colons it
|
|
131
|
+
* holds: a prefix with a path separator in it is never a kind.
|
|
132
|
+
*/
|
|
133
|
+
export declare function parseRowRef(text: string): RowRef;
|
|
134
|
+
/** `<risk>` for every row, or `<risk>=<row>` for one. */
|
|
135
|
+
export declare function parseAllow(text: string): Allow;
|
|
136
|
+
/**
|
|
137
|
+
* What can be refused of `approval` before anything is swept: a malformed
|
|
138
|
+
* row or risk, a row a sweep with `options` could never hold, and a row
|
|
139
|
+
* picked and spared as written. A row named two ways, and an `allow` for a
|
|
140
|
+
* spared or unpicked row, are found when the approval is resolved against
|
|
141
|
+
* the plan.
|
|
142
|
+
*/
|
|
143
|
+
export declare function checkApproval(options: Pick<SweptWith, 'only' | 'branch'>, approval: Approval): void;
|
|
144
|
+
/**
|
|
145
|
+
* `approval` resolved against `plan`, or a {@link RepoCleanerError} for one
|
|
146
|
+
* that contradicts itself or names rows the plan does not have.
|
|
147
|
+
*/
|
|
148
|
+
export declare function resolveApproval(plan: Plan, approval: Approval, cwd: string): ResolvedApproval;
|
|
149
|
+
/**
|
|
150
|
+
* A network URL as `host[:port]/path`, the same for `git@host:o/r.git`,
|
|
151
|
+
* `ssh://git@host/o/r` and `https://host/o/r/`; the whole path is kept, so
|
|
152
|
+
* nested groups stay apart. Null for a path on this machine, including
|
|
153
|
+
* `file://` and a Windows drive path.
|
|
154
|
+
*/
|
|
155
|
+
export declare function networkRemoteKey(url: string): string | null;
|
|
156
|
+
/**
|
|
157
|
+
* What running `plan` under `approval` would do now: sweeps every repository
|
|
158
|
+
* the selection is in again (or reads `opts.sweep`), and returns the steps
|
|
159
|
+
* and the rows dropped, with why. Deletes nothing.
|
|
160
|
+
*
|
|
161
|
+
* @throws RepoCleanerError for an approval that contradicts itself, names a
|
|
162
|
+
* row the plan does not have or names one ambiguously, or spares a remote
|
|
163
|
+
* branch that moved. A plain `Error`, naming the repository, when the
|
|
164
|
+
* re-check cannot read one: a failed fetch, or a remote `ls-remote` cannot
|
|
165
|
+
* reach. Nothing has been touched.
|
|
166
|
+
*/
|
|
167
|
+
export declare function check(plan: Plan, approval: Approval, opts?: CheckOptions): Preview;
|
|
168
|
+
/**
|
|
169
|
+
* Take the steps `preview` showed: sweeps again, drops a row that moved since
|
|
170
|
+
* the preview, and runs the rest in order, compare-and-swap, verifying each
|
|
171
|
+
* step and stopping at the first failure. Only what the preview showed runs; a
|
|
172
|
+
* row it dropped stays dropped.
|
|
173
|
+
*
|
|
174
|
+
* @throws RepoCleanerError (`spared-changed`) when a spared remote branch moved
|
|
175
|
+
* since the preview, and a plain `Error` when the re-check cannot read a
|
|
176
|
+
* repository, as {@link check} does. Nothing has been touched.
|
|
177
|
+
*/
|
|
178
|
+
export declare function run(preview: Preview, opts?: RunOptions): Receipt;
|
|
179
|
+
export {};
|