@united-robotics/cli 0.4.6 → 0.4.7
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/dist/index.js +42 -3
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -26,6 +26,17 @@ function save(config, opts = {}) {
|
|
|
26
26
|
mkdirSync(dirname(path), { recursive: true });
|
|
27
27
|
writeFileSync(path, JSON.stringify(config, null, 2));
|
|
28
28
|
}
|
|
29
|
+
function rememberDefaultProject(projectId, cwd) {
|
|
30
|
+
const currentCwd = process.cwd();
|
|
31
|
+
try {
|
|
32
|
+
process.chdir(cwd);
|
|
33
|
+
const cfg = load();
|
|
34
|
+
save({ ...cfg, defaultProjectId: projectId });
|
|
35
|
+
ignoreWorkspaceConfigInGit(cwd);
|
|
36
|
+
} finally {
|
|
37
|
+
process.chdir(currentCwd);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
29
40
|
async function api(path, init = {}) {
|
|
30
41
|
const cfg = load();
|
|
31
42
|
const res = await fetch(`${cfg.apiUrl}${path}`, { ...init, headers: { authorization: `Bearer ${cfg.token ?? ""}`, "content-type": "application/json", ...init.headers ?? {} } });
|
|
@@ -70,8 +81,10 @@ project.command("clone").argument("<projectId>").option("--dest <path>").option(
|
|
|
70
81
|
preservedConfig?.restore();
|
|
71
82
|
}
|
|
72
83
|
const worktree = dest ?? repoDirName(primary.url);
|
|
84
|
+
rememberDefaultProject(projectId, worktree);
|
|
73
85
|
configureGitIdentity(worktree, opts.name, opts.email, credentials.env);
|
|
74
|
-
if (opts.submodules) initProjectWorktree(worktree, opts.name, opts.email, credentials.env);
|
|
86
|
+
if (opts.submodules) initProjectWorktree(worktree, projectId, opts.name, opts.email, credentials.env);
|
|
87
|
+
else configureGitCredentialHelper(worktree, projectId, credentials.env);
|
|
75
88
|
printCloneSuccess(projectId, worktree, token);
|
|
76
89
|
} finally {
|
|
77
90
|
credentials.cleanup();
|
|
@@ -81,7 +94,8 @@ project.command("init").argument("<projectId>").option("--cwd <path>", "workspac
|
|
|
81
94
|
const token = await projectGithubToken(projectId);
|
|
82
95
|
const credentials = createGitAskpass(token.token);
|
|
83
96
|
try {
|
|
84
|
-
|
|
97
|
+
rememberDefaultProject(projectId, opts.cwd);
|
|
98
|
+
initProjectWorktree(opts.cwd, projectId, opts.name, opts.email, credentials.env);
|
|
85
99
|
console.log(`Initialized ${projectId} workspace at ${opts.cwd}`);
|
|
86
100
|
printDetachedHeadNotice();
|
|
87
101
|
} finally {
|
|
@@ -103,6 +117,16 @@ git.command("identity").option("--name <name>", "Git user.name", "exis[ai]").opt
|
|
|
103
117
|
}
|
|
104
118
|
console.log(`Configured git committer identity: ${opts.name} <${opts.email}>`);
|
|
105
119
|
});
|
|
120
|
+
git.command("credential-helper").description("Git credential helper used by United Robotics workspaces").argument("[operation]", "git credential helper operation").option("--project <projectId>", "project id; defaults to local config defaultProjectId").action(async (operation, opts) => {
|
|
121
|
+
if (operation && operation !== "get") return;
|
|
122
|
+
const projectId = opts.project ?? load().defaultProjectId;
|
|
123
|
+
if (!projectId) throw new Error("Missing project id for UR git credential helper. Run `ur project init <projectId>` from the workspace root.");
|
|
124
|
+
const result = await projectGithubToken(projectId);
|
|
125
|
+
process.stdout.write(`username=x-access-token
|
|
126
|
+
password=${result.token}
|
|
127
|
+
|
|
128
|
+
`);
|
|
129
|
+
});
|
|
106
130
|
var github = program.command("github");
|
|
107
131
|
github.command("token").option("--project <projectId>", "project id", "skinspirit-main").option("--repo <repo>", "repo id, name, full name, or URL within the project").option("--json", "emit full JSON").option("--redact", "redact token in JSON output").action(async (opts) => {
|
|
108
132
|
const result = await api(`/api/projects/${opts.project}/github-token`, {
|
|
@@ -158,21 +182,36 @@ esac
|
|
|
158
182
|
cleanup: () => rmSync(dir, { recursive: true, force: true })
|
|
159
183
|
};
|
|
160
184
|
}
|
|
161
|
-
function initProjectWorktree(worktree, name, email, env = process.env) {
|
|
185
|
+
function initProjectWorktree(worktree, projectId, name, email, env = process.env) {
|
|
162
186
|
configureGitIdentity(worktree, name, email, env);
|
|
163
187
|
runGit(["submodule", "sync", "--recursive"], { cwd: worktree, env, authHint: true, allowFailure: true });
|
|
164
188
|
runGit(["submodule", "update", "--init", "--recursive"], { cwd: worktree, env, authHint: true });
|
|
189
|
+
configureGitCredentialHelper(worktree, projectId, env);
|
|
165
190
|
configureSubmoduleIdentities(worktree, name, email, env);
|
|
191
|
+
configureSubmoduleCredentialHelpers(worktree, projectId, env);
|
|
166
192
|
printDetachedHeadNotice();
|
|
167
193
|
}
|
|
168
194
|
function configureGitIdentity(cwd, name, email, env = process.env) {
|
|
169
195
|
runGit(["config", "--local", "user.name", name], { cwd, env });
|
|
170
196
|
runGit(["config", "--local", "user.email", email], { cwd, env });
|
|
171
197
|
}
|
|
198
|
+
function configureGitCredentialHelper(cwd, projectId, env = process.env) {
|
|
199
|
+
const helper = `!ur git credential-helper --project ${shellSingleQuoteSafe(projectId)}`;
|
|
200
|
+
runGit(["config", "--local", "--unset-all", "credential.helper"], { cwd, env, allowFailure: true });
|
|
201
|
+
runGit(["config", "--local", "--add", "credential.helper", ""], { cwd, env });
|
|
202
|
+
runGit(["config", "--local", "--add", "credential.helper", helper], { cwd, env });
|
|
203
|
+
runGit(["config", "--local", "credential.useHttpPath", "true"], { cwd, env });
|
|
204
|
+
runGit(["config", "--local", "credential.interactive", "false"], { cwd, env, allowFailure: true });
|
|
205
|
+
}
|
|
172
206
|
function configureSubmoduleIdentities(worktree, name, email, env = process.env) {
|
|
173
207
|
const result = runGit(["submodule", "foreach", "--recursive", `git config --local user.name '${shellSingleQuoteSafe(name)}' && git config --local user.email '${shellSingleQuoteSafe(email)}'`], { cwd: worktree, env, allowFailure: true });
|
|
174
208
|
if (result.status !== 0) console.warn("Warning: could not apply git identity to all submodules. Run `ur git identity --recursive` after submodules are initialized.");
|
|
175
209
|
}
|
|
210
|
+
function configureSubmoduleCredentialHelpers(worktree, projectId, env = process.env) {
|
|
211
|
+
const helper = `!ur git credential-helper --project ${shellSingleQuoteSafe(projectId)}`;
|
|
212
|
+
const result = runGit(["submodule", "foreach", "--recursive", `git config --local --unset-all credential.helper || true; git config --local --add credential.helper ''; git config --local --add credential.helper '${shellSingleQuoteSafe(helper)}'; git config --local credential.useHttpPath true; git config --local credential.interactive false || true`], { cwd: worktree, env, allowFailure: true });
|
|
213
|
+
if (result.status !== 0) console.warn("Warning: could not apply UR git credential helper to all submodules. Run `ur project init <projectId>` after submodules are initialized.");
|
|
214
|
+
}
|
|
176
215
|
function runGit(args, options = { cwd: process.cwd() }) {
|
|
177
216
|
const gitArgs = options.authHint ? ["-c", "credential.helper=", "-c", "credential.useHttpPath=true", ...args] : args;
|
|
178
217
|
const result = spawnSync(gitBin(), gitArgs, { cwd: options.cwd, env: options.env ?? process.env, encoding: "utf8" });
|