@newlandnpt/pep-cli 0.9.0-rc.3 → 0.9.0-rc.4
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/README.md +14 -0
- package/dist/pep.cjs +108 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -77,6 +77,20 @@ pep setup --skip-skills # only sign in and configure Maven
|
|
|
77
77
|
pep setup group/sub -p # a different group, into THIS project
|
|
78
78
|
```
|
|
79
79
|
|
|
80
|
+
### Seeing what a run would do
|
|
81
|
+
|
|
82
|
+
```powershell
|
|
83
|
+
pep setup --json
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Prints the plan and **installs nothing**: which repositories the group holds right now, which of them
|
|
87
|
+
are new, where each would land, and which entries on your list are no longer in the group — together
|
|
88
|
+
with the skill names those occupy, which is what makes one block another. Useful before a first run,
|
|
89
|
+
and when an install fails for a reason you would rather understand than guess at.
|
|
90
|
+
|
|
91
|
+
It never opens a browser: with no valid sign-in it reports `"login": "required"` and exits non-zero.
|
|
92
|
+
It does read the group, so it may refresh your token, exactly as `pep auth status` does.
|
|
93
|
+
|
|
80
94
|
`--issuer`, `--client-id` and `--resource` work here exactly as on `pep auth login`, for pointing a
|
|
81
95
|
run at another deployment:
|
|
82
96
|
|
package/dist/pep.cjs
CHANGED
|
@@ -1176,6 +1176,13 @@ never deleted. \`pep skills remove <repo>\` drops one for good.
|
|
|
1176
1176
|
The group is baked into this build and is not remembered between runs: pass one
|
|
1177
1177
|
to install from a different group, just for this run.
|
|
1178
1178
|
|
|
1179
|
+
--json prints what this run would do \u2014 which repositories the group holds, which
|
|
1180
|
+
of them are new, where each would land, and which entries on your list are no
|
|
1181
|
+
longer in the group (with the skill names they occupy, which is what makes one
|
|
1182
|
+
block another). It installs nothing, writes nothing and never opens a browser.
|
|
1183
|
+
It does need a valid sign-in to read the group, so it may refresh your token,
|
|
1184
|
+
exactly as \`pep auth status\` does.
|
|
1185
|
+
|
|
1179
1186
|
--issuer, --client-id and --resource are passed to step 1, exactly as on
|
|
1180
1187
|
\`pep auth login\`, and are not remembered either. If you are already signed in to
|
|
1181
1188
|
a different deployment, setup signs in again rather than silently using the one
|
|
@@ -1188,13 +1195,15 @@ replaces it \u2014 run \`pep auth login\` to go back.`,
|
|
|
1188
1195
|
"--dir <path> Install skills into this directory instead",
|
|
1189
1196
|
`--issuer <url> PEP server for this run (default: ${DEFAULT_ISSUER})`,
|
|
1190
1197
|
"--client-id <id> Registered OAuth client for this run",
|
|
1198
|
+
"--json Print what this run would do, install nothing",
|
|
1191
1199
|
"--resource <uri> Token audience; repeat for multiple resources"
|
|
1192
1200
|
],
|
|
1193
1201
|
examples: [
|
|
1194
1202
|
"pep setup",
|
|
1195
1203
|
"pep setup --skip-nexus",
|
|
1196
1204
|
`pep setup ${DEFAULT_SKILLS_GROUP} -p`,
|
|
1197
|
-
"pep setup --issuer https://pep-dev.example --client-id <that deployment's id>"
|
|
1205
|
+
"pep setup --issuer https://pep-dev.example --client-id <that deployment's id>",
|
|
1206
|
+
"pep setup --json"
|
|
1198
1207
|
]
|
|
1199
1208
|
}
|
|
1200
1209
|
};
|
|
@@ -1834,7 +1843,11 @@ async function installGroup(dependencies, remote) {
|
|
|
1834
1843
|
if (repos.length === 0) {
|
|
1835
1844
|
dependencies.onProgress(` ${group} lists no repositories \u2014 nothing to install.`);
|
|
1836
1845
|
}
|
|
1837
|
-
const drifted = driftedFromGroup(
|
|
1846
|
+
const drifted = driftedFromGroup(
|
|
1847
|
+
dependencies.installed.map((one) => one.source),
|
|
1848
|
+
repos,
|
|
1849
|
+
group
|
|
1850
|
+
);
|
|
1838
1851
|
if (drifted.length > 0) {
|
|
1839
1852
|
dependencies.onProgress(` \u26A0 On your list but no longer in ${group}:`);
|
|
1840
1853
|
for (const source of drifted) dependencies.onProgress(` ${source}`);
|
|
@@ -1923,9 +1936,74 @@ function setupFailureSummary(report) {
|
|
|
1923
1936
|
if (failed.length === 0) return void 0;
|
|
1924
1937
|
return `Setup finished with problems: ${failed.join(", ")} did not complete.`;
|
|
1925
1938
|
}
|
|
1939
|
+
async function planSetup(dependencies) {
|
|
1940
|
+
const group = dependencies.group;
|
|
1941
|
+
const nexus = dependencies.skipNexus ? "skipped" : "planned";
|
|
1942
|
+
const bySource = new Map(dependencies.installed.map((one) => [one.source, one]));
|
|
1943
|
+
let current;
|
|
1944
|
+
try {
|
|
1945
|
+
current = await dependencies.auth.status();
|
|
1946
|
+
} catch {
|
|
1947
|
+
}
|
|
1948
|
+
if (current === void 0) {
|
|
1949
|
+
return {
|
|
1950
|
+
group,
|
|
1951
|
+
issuer: null,
|
|
1952
|
+
account: null,
|
|
1953
|
+
login: "required",
|
|
1954
|
+
skills: { status: "unavailable", reason: "not signed in \u2014 run `pep auth login` first" },
|
|
1955
|
+
nexus
|
|
1956
|
+
};
|
|
1957
|
+
}
|
|
1958
|
+
const issuer = current.authorization.issuer;
|
|
1959
|
+
if (dependencies.requestedIssuer !== void 0 && !sameIssuer(issuer, dependencies.requestedIssuer)) {
|
|
1960
|
+
return {
|
|
1961
|
+
group,
|
|
1962
|
+
issuer,
|
|
1963
|
+
account: accountOf(current.user),
|
|
1964
|
+
login: "different-deployment",
|
|
1965
|
+
skills: {
|
|
1966
|
+
status: "unavailable",
|
|
1967
|
+
reason: `signed in to ${issuer}, but --issuer names ${dependencies.requestedIssuer}; a real run would sign in again first`
|
|
1968
|
+
},
|
|
1969
|
+
nexus
|
|
1970
|
+
};
|
|
1971
|
+
}
|
|
1972
|
+
const plan = {
|
|
1973
|
+
group,
|
|
1974
|
+
issuer,
|
|
1975
|
+
account: accountOf(current.user),
|
|
1976
|
+
login: "reuse",
|
|
1977
|
+
nexus
|
|
1978
|
+
};
|
|
1979
|
+
if (dependencies.skipSkills) {
|
|
1980
|
+
return { ...plan, skills: { status: "skipped", reason: "--skip-skills" } };
|
|
1981
|
+
}
|
|
1982
|
+
let repos;
|
|
1983
|
+
try {
|
|
1984
|
+
repos = await dependencies.listGroupRepos({
|
|
1985
|
+
issuer,
|
|
1986
|
+
accessToken: current.authorization.accessToken
|
|
1987
|
+
});
|
|
1988
|
+
} catch (error) {
|
|
1989
|
+
return { ...plan, skills: { status: "unavailable", reason: messageOf(error) } };
|
|
1990
|
+
}
|
|
1991
|
+
const repositories = repos.map((path) => {
|
|
1992
|
+
const known = bySource.get(path);
|
|
1993
|
+
return known === void 0 ? { path, state: "new", directory: dependencies.directoryFor(path) } : {
|
|
1994
|
+
path,
|
|
1995
|
+
state: "installed",
|
|
1996
|
+
directory: known.directory,
|
|
1997
|
+
...known.commit !== void 0 ? { commit: known.commit } : {}
|
|
1998
|
+
};
|
|
1999
|
+
});
|
|
2000
|
+
const gone = new Set(driftedFromGroup(dependencies.installed.map((one) => one.source), repos, group));
|
|
2001
|
+
const drifted = dependencies.installed.filter((one) => gone.has(one.source));
|
|
2002
|
+
return { ...plan, skills: { status: "planned", repositories, drifted } };
|
|
2003
|
+
}
|
|
1926
2004
|
|
|
1927
2005
|
// src/cli.ts
|
|
1928
|
-
var VERSION = false ? "0.0.0-dev" : "0.9.0-rc.
|
|
2006
|
+
var VERSION = false ? "0.0.0-dev" : "0.9.0-rc.4";
|
|
1929
2007
|
var SKILLS_ADD_DEPRECATION = "\u26A0 `pep skills add` will be removed in a future release.";
|
|
1930
2008
|
function reportUpdate(result) {
|
|
1931
2009
|
const conflicts = () => {
|
|
@@ -2144,11 +2222,37 @@ async function main() {
|
|
|
2144
2222
|
const skipNexus = flag(args, "--skip-nexus");
|
|
2145
2223
|
const skipSkills = flag(args, "--skip-skills");
|
|
2146
2224
|
const loginOptions = takeLoginOptions(args);
|
|
2225
|
+
const wantsJson = flag(args, "--json");
|
|
2147
2226
|
const { requested, chosenTarget } = parseSkillsArgs("setup", args);
|
|
2148
2227
|
const skillsGroup = requested ?? DEFAULT_SKILLS_GROUP;
|
|
2149
2228
|
const { configStore: configStore2, auth: auth2 } = createCliServices();
|
|
2150
2229
|
const stateStore = fileSkillsStateStore();
|
|
2151
2230
|
const state = await stateStore.read();
|
|
2231
|
+
const installed = Object.entries(state?.packages ?? {}).map(([source, pkg]) => ({
|
|
2232
|
+
source,
|
|
2233
|
+
directory: pkg.directory,
|
|
2234
|
+
skills: Object.keys(pkg.skills).sort(),
|
|
2235
|
+
...pkg.commit !== void 0 ? { commit: pkg.commit } : {}
|
|
2236
|
+
}));
|
|
2237
|
+
if (wantsJson) {
|
|
2238
|
+
const plan = await planSetup({
|
|
2239
|
+
auth: auth2,
|
|
2240
|
+
...issuerOf(loginOptions) !== void 0 ? { requestedIssuer: issuerOf(loginOptions) } : {},
|
|
2241
|
+
group: skillsGroup,
|
|
2242
|
+
skipSkills,
|
|
2243
|
+
skipNexus,
|
|
2244
|
+
listGroupRepos: (remote) => listGroupRepos({ ...remote, group: skillsGroup }),
|
|
2245
|
+
installed,
|
|
2246
|
+
// ⚠ 与真跑**同一条推导**(`targetForSource`):干跑报的落点要是和真跑落的地方
|
|
2247
|
+
// 不一样,那它比没有还坏。
|
|
2248
|
+
directoryFor: (source) => targetForSource(chosenTarget, state?.packages[source]).directory
|
|
2249
|
+
});
|
|
2250
|
+
console.log(JSON.stringify(plan, null, 2));
|
|
2251
|
+
if (plan.skills.status === "unavailable") {
|
|
2252
|
+
throw new Error(`--json could not plan the skills step: ${plan.skills.reason}`);
|
|
2253
|
+
}
|
|
2254
|
+
return;
|
|
2255
|
+
}
|
|
2152
2256
|
const report = await runSetup({
|
|
2153
2257
|
auth: auth2,
|
|
2154
2258
|
// ⚠ 传 `loginOptions` 而不是 `args`:后者到这里**恒为空**(`parseSkillsArgs` 要么抛、
|
|
@@ -2174,7 +2278,7 @@ async function main() {
|
|
|
2174
2278
|
},
|
|
2175
2279
|
// 漂移比对的另一半。取**这一趟开始前**的账 —— 装完再读的话,本轮刚装上的那些也在
|
|
2176
2280
|
// 里头,而它们当然都还在群里,比出来一样,只是白读一遍。
|
|
2177
|
-
|
|
2281
|
+
installed,
|
|
2178
2282
|
skipNexus,
|
|
2179
2283
|
setupNexus: (remote) => setupNexusCredential(remote),
|
|
2180
2284
|
onProgress: (line) => console.error(line),
|