History

Add remote repository publish and discovery support (#2482)

Julius Marminge committed 6 months ago

Commit d7969261 parent f7748a033 files · +2502 −157Browse files

Showing the changes to apps/server/src/sourceControl/SourceControlDiscovery.ts (1 of 33 files). Show all

Unified · Split

apps/server/src/sourceControl/SourceControlDiscovery.ts+44−50
@@ -13,20 +13,22 @@ import * as VcsProcess from "../vcs/VcsProcess.ts"; · 12 unmodified lines
1313
1414 interface DiscoveryProbe {
1515 readonly label: string;
16− readonly executable: string;
17− readonly versionArgs: ReadonlyArray<string>;
16+ readonly executable?: string;
17+ readonly versionArgs?: ReadonlyArray<string>;
1818 readonly implemented: boolean;
1919 readonly installHint: string;
2020 }
2121
2222 type VcsProbe = DiscoveryProbe & {
2323 readonly kind: VcsDriverKind;
24+ readonly executable: string;
25+ readonly versionArgs: ReadonlyArray<string>;
2426 };
2527
2628 type ProviderProbe = DiscoveryProbe & {
2729 readonly kind: SourceControlProviderKind;
28− readonly authArgs: ReadonlyArray<string>;
29− readonly parseAuth: (input: AuthProbeInput) => SourceControlProviderAuth;
30+ readonly authArgs?: ReadonlyArray<string>;
31+ readonly parseAuth?: (input: AuthProbeInput) => SourceControlProviderAuth;
3032 };
3133
3234 interface AuthProbeInput {
@@ -38,7 +40,7 @@ interface AuthProbeInput { · 5 unmodified lines
3840 interface DiscoveryProbeResult<Kind extends string> {
3941 readonly kind: Kind;
4042 readonly label: string;
41− readonly executable: string;
43+ readonly executable?: string;
4244 readonly implemented: boolean;
4345 readonly status: "available" | "missing";
4446 readonly version: Option.Option<string>;
@@ -101,12 +103,8 @@ const SOURCE_CONTROL_PROVIDER_PROBES: ReadonlyArray<ProviderProbe> = [ · 56 unmodified lines
101103 {
102104 kind: "bitbucket",
103105 label: "Bitbucket",
104− executable: "bb",
105− versionArgs: ["--version"],
106− authArgs: ["auth", "status"],
107− parseAuth: parseBitbucketAuth,
108106 implemented: false,
109− installHint: "Install a Bitbucket CLI (`bb`) and authenticate it for your Bitbucket workspace.",
107+ installHint: "Bitbucket provider support is not available yet.",
110108 },
111109 ];
112110
@@ -266,37 +264,6 @@ function parseAzureAuth(input: AuthProbeInput): SourceControlProviderAuth { · 153 unmodified lines
266264 });
267265 }
268266
269−function parseBitbucketAuth(input: AuthProbeInput): SourceControlProviderAuth {
270− const output = combinedAuthOutput(input);
271− const account = matchFirst(output, [
272− /Logged in to .* as\s+([^\s(]+)/iu,
273− /Logged in as\s+([^\s(]+)/iu,
274− /account:\s*([^\s(]+)/iu,
275− /user:\s*([^\s(]+)/iu,
276− /username:\s*([^\s(]+)/iu,
277− ]);
278− const host = parseCliHost(output) ?? "bitbucket.org";
279−
280− if (input.exitCode !== 0) {
281− return providerAuth({
282− status: "unauthenticated",
283− host,
284− detail:
285− firstSafeAuthLine(output) ?? "Authenticate the Bitbucket CLI before enabling Bitbucket.",
286− });
287− }
288−
289− if (account) {
290− return providerAuth({ status: "authenticated", account, host });
291− }
292−
293− return providerAuth({
294− status: "unknown",
295− host,
296− detail: firstSafeAuthLine(output) ?? "Bitbucket CLI auth status could not be parsed.",
297− });
298−}
299−
300267 export interface SourceControlDiscoveryShape {
301268 readonly discover: Effect.Effect<SourceControlDiscoveryResult>;
302269 }
@@ -314,12 +281,27 @@ export const layer = Layer.effect( · 11 unmodified lines
314281
315282 const probe = <Kind extends VcsDriverKind | SourceControlProviderKind>(
316283 input: DiscoveryProbe & { readonly kind: Kind },
317− ): Effect.Effect<DiscoveryProbeResult<Kind>> =>
318− process
284+ ): Effect.Effect<DiscoveryProbeResult<Kind>> => {
285+ const executable = input.executable;
286+ const versionArgs = input.versionArgs;
287+
288+ if (!executable || !versionArgs) {
289+ return Effect.succeed({
290+ kind: input.kind,
291+ label: input.label,
292+ implemented: input.implemented,
293+ status: "missing" as const,
294+ version: Option.none<string>(),
295+ installHint: input.installHint,
296+ detail: Option.some(input.installHint),
297+ } satisfies DiscoveryProbeResult<Kind>);
298+ }
299+
300+ return process
319301 .run({
320302 operation: "source-control.discovery.probe",
321− command: input.executable,
322− args: input.versionArgs,
303+ command: executable,
304+ args: versionArgs,
323305 cwd: config.cwd,
324306 timeoutMs: 5_000,
325307 maxOutputBytes: 8_000,
@@ -331,7 +313,7 @@ export const layer = Layer.effect( · 5 unmodified lines
331313 ({
332314 kind: input.kind,
333315 label: input.label,
334− executable: input.executable,
316+ executable,
335317 implemented: input.implemented,
336318 status: "available" as const,
337319 version: Option.orElse(firstNonEmptyLine(result.stdout), () =>
@@ -345,7 +327,7 @@ export const layer = Layer.effect( · 7 unmodified lines
345327 Effect.succeed({
346328 kind: input.kind,
347329 label: input.label,
348− executable: input.executable,
330+ executable,
349331 implemented: input.implemented,
350332 status: "missing" as const,
351333 version: Option.none<string>(),
@@ -354,10 +336,22 @@ export const layer = Layer.effect( · 2 unmodified lines
354336 } satisfies DiscoveryProbeResult<Kind>),
355337 ),
356338 );
339+ };
357340
358341 const probeProvider = (input: ProviderProbe) =>
359342 probe(input).pipe(
360343 Effect.flatMap((item) => {
344+ const executable = input.executable;
345+ const authArgs = input.authArgs;
346+ const parseAuth = input.parseAuth;
347+
348+ if (!executable || !authArgs || !parseAuth) {
349+ return Effect.succeed({
350+ ...item,
351+ auth: unknownAuth(input.installHint),
352+ } satisfies SourceControlProviderDiscoveryItem);
353+ }
354+
361355 if (item.status !== "available") {
362356 return Effect.succeed({
363357 ...item,
@@ -368,8 +362,8 @@ export const layer = Layer.effect( · 4 unmodified lines
368362 return process
369363 .run({
370364 operation: "source-control.discovery.auth",
371− command: input.executable,
372− args: input.authArgs,
365+ command: executable,
366+ args: authArgs,
373367 cwd: config.cwd,
374368 allowNonZeroExit: true,
375369 timeoutMs: 5_000,
@@ -381,7 +375,7 @@ export const layer = Layer.effect( · 5 unmodified lines
381375 (result) =>
382376 ({
383377 ...item,
384− auth: input.parseAuth(result),
378+ auth: parseAuth(result),
385379 }) satisfies SourceControlProviderDiscoveryItem,
386380 ),
387381 Effect.catch((cause) =>