create-egregore 0.15.0 → 0.15.1
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/lib/local.js +45 -11
- package/package.json +1 -1
package/lib/local.js
CHANGED
|
@@ -168,6 +168,43 @@ function cloneRepo(url, dir, token, ui, label) {
|
|
|
168
168
|
ui.success(`Cloned ${label}`);
|
|
169
169
|
}
|
|
170
170
|
|
|
171
|
+
/**
|
|
172
|
+
* Convert HTTPS GitHub URL to SSH format.
|
|
173
|
+
* https://github.com/org/repo.git → git@github.com:org/repo.git
|
|
174
|
+
*/
|
|
175
|
+
function toSSH(url) {
|
|
176
|
+
const m = url.match(/https:\/\/github\.com\/(.+?)(?:\.git)?$/);
|
|
177
|
+
return m ? `git@github.com:${m[1]}.git` : null;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Clone a repo, trying SSH first then HTTPS.
|
|
182
|
+
* GIT_TERMINAL_PROMPT=0 prevents the hanging username/password prompt.
|
|
183
|
+
*/
|
|
184
|
+
function cloneWithFallback(httpsUrl, dir, timeout = 60000) {
|
|
185
|
+
const env = { ...process.env, GIT_TERMINAL_PROMPT: "0" };
|
|
186
|
+
const sshUrl = toSSH(httpsUrl);
|
|
187
|
+
|
|
188
|
+
// Try SSH first (most devs have SSH keys; GitHub no longer supports HTTPS password auth)
|
|
189
|
+
if (sshUrl) {
|
|
190
|
+
try {
|
|
191
|
+
execFileSync("git", ["clone", sshUrl, dir], { stdio: "pipe", encoding: "utf-8", timeout, env });
|
|
192
|
+
return true;
|
|
193
|
+
} catch {
|
|
194
|
+
// Clean up partial clone so HTTPS fallback can use the same dir
|
|
195
|
+
try { fs.rmSync(dir, { recursive: true, force: true }); } catch {}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// Fall back to HTTPS (works if user has gh CLI or a credential helper configured)
|
|
200
|
+
try {
|
|
201
|
+
execFileSync("git", ["clone", httpsUrl, dir], { stdio: "pipe", encoding: "utf-8", timeout, env });
|
|
202
|
+
return true;
|
|
203
|
+
} catch {}
|
|
204
|
+
|
|
205
|
+
return false;
|
|
206
|
+
}
|
|
207
|
+
|
|
171
208
|
function setGitIdentity(dir, user) {
|
|
172
209
|
try {
|
|
173
210
|
run(`git config user.name "${user.name}"`, { cwd: dir });
|
|
@@ -602,10 +639,9 @@ async function localJoinFlow(orgArg, ui) {
|
|
|
602
639
|
|
|
603
640
|
console.log("");
|
|
604
641
|
const s2 = ui.spinner(`Cloning ${orgLogin}/${repoName}...`);
|
|
605
|
-
|
|
606
|
-
execFileSync("git", ["clone", `https://github.com/${orgLogin}/${repoName}.git`, egregoreDir], { stdio: "pipe", encoding: "utf-8", timeout: 60000 });
|
|
642
|
+
if (cloneWithFallback(`https://github.com/${orgLogin}/${repoName}.git`, egregoreDir)) {
|
|
607
643
|
s2.stop(`Cloned ${repoName}`);
|
|
608
|
-
}
|
|
644
|
+
} else {
|
|
609
645
|
s2.fail(`Could not clone ${orgLogin}/${repoName}`);
|
|
610
646
|
ui.error("Make sure you have git credentials set up (SSH keys or gh auth login).");
|
|
611
647
|
ui.error("Also verify the org admin has set up Egregore and invited you.");
|
|
@@ -642,12 +678,11 @@ async function localJoinFlow(orgArg, ui) {
|
|
|
642
678
|
// Store the invite token for later use (invitation acceptance, not cloning)
|
|
643
679
|
const inviteToken = githubToken;
|
|
644
680
|
|
|
645
|
-
// Clone memory using
|
|
681
|
+
// Clone memory using SSH-first fallback (same as main repo)
|
|
646
682
|
ui.step(1, totalSteps, "Cloning shared memory...");
|
|
647
|
-
|
|
648
|
-
execFileSync("git", ["clone", memoryUrl, memoryDir], { stdio: "pipe", encoding: "utf-8", timeout: 60000 });
|
|
683
|
+
if (cloneWithFallback(memoryUrl, memoryDir)) {
|
|
649
684
|
ui.success("Cloned memory");
|
|
650
|
-
}
|
|
685
|
+
} else {
|
|
651
686
|
ui.warn("Could not clone memory repo — you may not have access yet.");
|
|
652
687
|
}
|
|
653
688
|
setGitIdentity(memoryDir, user);
|
|
@@ -683,16 +718,15 @@ async function localJoinFlow(orgArg, ui) {
|
|
|
683
718
|
registerInstance(repoName, orgName, egregoreDir);
|
|
684
719
|
const alias = await installShellAlias(egregoreDir, ui);
|
|
685
720
|
|
|
686
|
-
// Clone managed repos using
|
|
721
|
+
// Clone managed repos using SSH-first fallback
|
|
687
722
|
for (let i = 0; i < managedRepos.length; i++) {
|
|
688
723
|
const mr = managedRepos[i];
|
|
689
724
|
ui.step(5 + i, totalSteps, `Cloning ${mr}...`);
|
|
690
725
|
const repoDir = path.join(base, mr);
|
|
691
|
-
|
|
692
|
-
execFileSync("git", ["clone", `https://github.com/${orgLogin}/${mr}.git`, repoDir], { stdio: "pipe", encoding: "utf-8", timeout: 60000 });
|
|
726
|
+
if (cloneWithFallback(`https://github.com/${orgLogin}/${mr}.git`, repoDir)) {
|
|
693
727
|
setGitIdentity(repoDir, user);
|
|
694
728
|
ui.success(`Cloned ${mr}`);
|
|
695
|
-
}
|
|
729
|
+
} else {
|
|
696
730
|
ui.warn(`Could not clone ${mr} — you may not have access yet.`);
|
|
697
731
|
}
|
|
698
732
|
}
|