Skip to content

Commit

Permalink
Docs
Browse files Browse the repository at this point in the history
  • Loading branch information
Razz4780 committed Feb 2, 2025
1 parent 2d66a9d commit 39c177e
Show file tree
Hide file tree
Showing 2 changed files with 114 additions and 4 deletions.
35 changes: 34 additions & 1 deletion src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,18 +111,48 @@ function handleIdeMessage(message: IdeMessage) {
}
}

/**
* A mirrord target found in the cluster.
*/
export type FoundTarget = {
/**
* The path of this target, as in the mirrord config.
*/
path: string;
/**
* Whether this target is available.
*/
available: boolean;
};

/**
* The new format of `mirrord ls`, including target availability and namespaces info.
*/
export type MirrordLsOutput = {
/**
* The targets found in the current namespace.
*/
targets: FoundTarget[];
/**
* The namespace where the lookup was done.
*
* If the CLI does not support listing namespaces, this is undefined.
*/
// eslint-disable-next-line @typescript-eslint/naming-convention
current_namespace?: string;
/**
* All namespaces visible to the user.
*
* If the CLI does not support listing namespaces, this is undefined.
*/
namespaces?: string[];
};

/**
* Checks whether the JSON value is in the @see MirrordLsOutput format.
*
* @param output JSON parsed from `mirrord ls` stdout
*/
function isRichMirrordLsOutput(output: any): output is MirrordLsOutput {
return "targets" in output && "current_namespace" in output && "namespaces" in output;
}
Expand Down Expand Up @@ -287,7 +317,10 @@ export class MirrordAPI {

/**
* Uses `mirrord ls` to get lists of targets and namespaces.
* Targets come sorted.
*
* Note that old CLI versions return only targets.
*
* @see MirrordLsOutput
*/
async listTargets(configPath: string | null | undefined, configEnv: EnvVars, namespace?: string): Promise<MirrordLsOutput> {
const args = ['ls'];
Expand Down
83 changes: 80 additions & 3 deletions src/targetQuickPick.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,25 @@ import { NotificationBuilder } from './notification';
/// Key used to store the last selected target in the persistent state.
const LAST_TARGET_KEY = "mirrord-last-target";

/**
* A page in the @see TargetQuickPick.
*/
type TargetQuickPickPage = {
/**
* Label to display in the widget.
*/
label: string,
/**
* Prefix of targets visible on this page, mirrord config format.
*
* undefined for namespace selection page.
*/
targetType?: string,
};

/**
* All pages in the @see TargetQuickPick.
*/
const ALL_QUICK_PICK_PAGES: TargetQuickPickPage[] = [
{
label: 'Show Deployments',
Expand All @@ -29,28 +43,72 @@ const ALL_QUICK_PICK_PAGES: TargetQuickPickPage[] = [
},
];

/**
* An item in the @see TargetQuickPick.
*/
type TargetQuickPickItem = vscode.QuickPickItem & (
{ type: 'target', value?: string } |
{ type: 'namespace', value: string } |
{ type: 'page', value: TargetQuickPickPage }
{ type: 'target', value?: string } | // select target
{ type: 'namespace', value: string } | // switch to another namespace
{ type: 'page', value: TargetQuickPickPage } // switch to another page (e.g select pod -> select deployment)
);

/**
* The item in the @see TargetQuickPick that represents the targetless mode.
*/
const TARGETLESS_ITEM: TargetQuickPickItem = {
type: 'target',
label: 'No Target (\"targetless\")',
};

/**
* A function used by @see TargetQuickPick to invoke `mirrord ls` in the given namespace.
*/
export type TargetFetcher = (namespace?: string) => Thenable<MirrordLsOutput>;

/**
* Describes what the user has selected with the @see TargetQuickPick.
*/
export type UserSelection = {
/**
* Selected target.
*
* undefined if targetless.
*/
path?: string,
/**
* Selected namespace.
*
* undefined if the CLI does not support listing namespaces.
*/
namespace?: string,
};

/**
* A quick pick allowing the user to select the target and, if the CLI supports listing namepaces, switch the namespace.
*/
export class TargetQuickPick {
/**
* Output of the last `mirrord ls` invocation.
*
* Should contain only targets that are available and supported by this widget (deployments, rollouts and pods).
*/
private lsOutput: MirrordLsOutput;
/**
* The page we are currently displaying.
*/
private activePage?: TargetQuickPickPage;
/**
* Last target that was ever selected by the user.
*
* This target, if present in @see lsOutput, is put first on its page.
* Also, determines initial page.
*/
private readonly lastTarget?: string;
/**
* Function used to invoke `mirrord ls` and get its output.
*
* Should return only targets that are available and supported by this widget (deployments, rollouts and pods).
*/
private readonly getTargets: TargetFetcher;

private constructor(getTargets: TargetFetcher, lsOutput: MirrordLsOutput) {
Expand All @@ -59,6 +117,11 @@ export class TargetQuickPick {
this.getTargets = getTargets;
}

/**
* Creates a new instance of this quick pick.
*
* This quick pick can be executed using @see showAndGet.
*/
static async new(getTargets: (namespace?: string) => Thenable<MirrordLsOutput>): Promise<TargetQuickPick> {
const getFilteredTargets = async (namespace?: string) => {
const output = await getTargets(namespace);
Expand All @@ -77,10 +140,16 @@ export class TargetQuickPick {
return new TargetQuickPick(getFilteredTargets, lsOutput);
}

/**
* Returns whether @see lsOutput has at least one target of this type.
*/
private hasTargetOfType(targetType: string): boolean {
return this.lsOutput.targets.find(t => t.path.startsWith(`${targetType}/`)) !== undefined;
}

/**
* Returns a default page to display. undefined if @see lsOutput contains no targets.
*/
private getDefaultPage(): TargetQuickPickPage | undefined {
let page: TargetQuickPickPage | undefined;

Expand All @@ -103,6 +172,9 @@ export class TargetQuickPick {
return page;
}

/**
* Prepares a placeholder and items for the quick pick.
*/
private prepareQuickPick(): [string, TargetQuickPickItem[]] {
if (this.activePage === undefined) {
this.activePage = this.getDefaultPage();
Expand Down Expand Up @@ -201,6 +273,11 @@ export class TargetQuickPick {
return [placeholder, items];
}

/**
* Shows the quick pick and returns user selection.
*
* If the user selected nothing, returns targetless.
*/
async showAndGet(): Promise<UserSelection> {
while (true) {
const [placeHolder, items] = this.prepareQuickPick();
Expand Down

0 comments on commit 39c177e

Please sign in to comment.