chore: resolve comments

This commit is contained in:
Adrian Z 2024-04-29 20:32:16 +08:00
parent 17ef5f8b4c
commit 580e47b577
6 changed files with 98 additions and 21 deletions

View file

@ -45,7 +45,7 @@ export class CheckoutCommand implements ICommand<ICheckoutCommandOptions> {
* have been implemented, while other scenarios are yet to be implemented.
* 1. sparo checkout [-b|-B] <new-branch> [start-point] [--profile <profile...>]
* 2. sparo checkout [branch] [--profile <profile...>]
* 3. sparo checkout [branch] [--to <project-name...>]
* 3. sparo checkout [branch] [--to <project-name...>] [--from <project-name...>]
*
* TODO: implement more checkout functionalities
*/
@ -71,10 +71,18 @@ export class CheckoutCommand implements ICommand<ICheckoutCommandOptions> {
.default('profile', [])
.array('add-profile')
.default('add-profile', [])
.array('to')
.default('to', [])
.array('from')
.default('from', []);
.option('to', {
type: 'array',
default: [],
description:
'Checkout projects up to (and including) project <to..>, can be used together with option --profile/--add-profile to form a union selection of the two options. The projects selectors here will never replace what have been checked out by profiles'
})
.option('from', {
type: 'array',
default: [],
description:
'Checkout projects downstream from (and including itself and all its dependencies) project <from..>, can be used together with option --profile/--add-profile to form a union selection of the two options. The projects selectors here will never replace what have been checked out by profiles'
});
}
public handler = async (
@ -147,10 +155,11 @@ export class CheckoutCommand implements ICommand<ICheckoutCommandOptions> {
}
// preprocess profile related args
const { isNoProfile, profiles, addProfiles } = await this._sparoProfileService.preprocessProfileArgs({
addProfilesFromArg: args.addProfile ?? [],
profilesFromArg: args.profile
});
const { isNoProfile, profiles, addProfiles, isProfileRestoreFromLocal } =
await this._sparoProfileService.preprocessProfileArgs({
addProfilesFromArg: args.addProfile ?? [],
profilesFromArg: args.profile
});
// Check wether profiles exist in local or operation branch
// Skip check in the following cases:
@ -220,7 +229,8 @@ export class CheckoutCommand implements ICommand<ICheckoutCommandOptions> {
profiles: isNoProfile ? undefined : profiles,
addProfiles,
fromProjects,
toProjects
toProjects,
isProfileRestoreFromLocal
});
}
};

View file

@ -2,7 +2,7 @@ import { FileSystem, Async } from '@rushstack/node-core-library';
import path from 'path';
import { inject } from 'inversify';
import { Service } from '../decorator';
import { SparoProfile, ISelection } from '../logic/SparoProfile';
import { SparoProfile, ISelection, ISparoProfileJson } from '../logic/SparoProfile';
import { TerminalService } from './TerminalService';
import { GitService } from './GitService';
import { GitSparseCheckoutService } from './GitSparseCheckoutService';
@ -18,6 +18,7 @@ export interface IResolveSparoProfileOptions {
}
const defaultSparoProfileFolder: string = 'common/sparo-profiles';
const INTERNAL_RUSH_SELECTOR_PSEUDO_PROFILE: string = '__INTERNAL_RUSH_SELECTOR_PSEUDO_PROFILE__';
@Service()
export class SparoProfileService {
@ -170,10 +171,12 @@ ${availableProfiles.join(',')}
addProfilesFromArg: string[];
}): Promise<{
isNoProfile: boolean;
isProfileRestoreFromLocal: boolean;
profiles: Set<string>;
addProfiles: Set<string>;
}> {
let isNoProfile: boolean = false;
let isProfileRestoreFromLocal: boolean = false;
/**
* --profile is defined as array type parameter, specifying --no-profile is resolved to false by yargs.
*
@ -210,18 +213,45 @@ ${availableProfiles.join(',')}
// 1. If profile specified from CLI parameter, preferential use it.
// 2. If none profile specified, read from existing profile from local state as default.
const localStateProfiles: ILocalStateProfiles | undefined = await this._localState.getProfiles();
isProfileRestoreFromLocal = true;
if (localStateProfiles) {
Object.keys(localStateProfiles).forEach((p) => profiles.add(p));
Object.keys(localStateProfiles).forEach((p) => {
if (p === INTERNAL_RUSH_SELECTOR_PSEUDO_PROFILE) return;
profiles.add(p);
});
}
}
return {
isNoProfile,
profiles,
addProfiles
addProfiles,
isProfileRestoreFromLocal
};
}
private async _syncRushSelectors(): Promise<ISelection[]>;
private async _syncRushSelectors(selections: ISelection[]): Promise<void>;
private async _syncRushSelectors(selections?: ISelection[]): Promise<void | ISelection[]> {
if (typeof selections !== 'undefined') {
return this._localState.setProfiles(
{
[INTERNAL_RUSH_SELECTOR_PSEUDO_PROFILE]: {
selections
}
},
'add'
);
} else {
const localStateProfiles: ILocalStateProfiles | undefined = await this._localState.getProfiles();
if (localStateProfiles) {
const rushSelectorProfiles: ISparoProfileJson | undefined =
localStateProfiles[INTERNAL_RUSH_SELECTOR_PSEUDO_PROFILE];
return rushSelectorProfiles?.selections || [];
}
return [];
}
}
/**
* sync local sparse checkout state with specified profiles
*/
@ -229,13 +259,19 @@ ${availableProfiles.join(',')}
profiles,
addProfiles,
fromProjects,
toProjects
toProjects,
isProfileRestoreFromLocal
}: {
profiles?: Set<string>;
addProfiles?: Set<string>;
fromProjects?: Set<string>;
toProjects?: Set<string>;
isProfileRestoreFromLocal?: boolean;
}): Promise<void> {
// only if user didn't specify any profile during a sparo checkout, we need to
// retain any previously checked out projects based on Rush Selectors
// https://rushjs.io/pages/developer/selecting_subsets/
const rushSelectorState: ISelection[] = isProfileRestoreFromLocal ? await this._syncRushSelectors() : [];
this._localState.reset();
const allProfiles: string[] = Array.from([...(profiles ?? []), ...(addProfiles ?? [])]);
if (allProfiles.length > 1) {
@ -305,9 +341,9 @@ ${availableProfiles.join(',')}
// handle case of `sparo checkout --to project-A project-B --from project-C project-D
const toSelector: Set<string> = toProjects || new Set();
const fromSelector: Set<string> = toProjects || new Set();
const fromSelector: Set<string> = fromProjects || new Set();
// If Rush Selector --to <projects> is specified, using `git sparse-checkout add` to add folders of the projects specified
const projectsSelections: ISelection[] = [];
const projectsSelections: ISelection[] = [...rushSelectorState];
for (const project of toSelector) {
projectsSelections.push({
@ -323,6 +359,7 @@ ${availableProfiles.join(',')}
}
if (projectsSelections.length > 0) {
await this._syncRushSelectors(projectsSelections);
await this._gitSparseCheckoutService.checkoutAsync({
selections: projectsSelections,
checkoutAction: 'add'

View file

@ -20,4 +20,19 @@ Options:
already exists, reset it to <start-point> [boolean]
--profile [array] [default: []]
--add-profile [array] [default: []]
--to Checkout projects up to (and including) project <to..>, can
be used together with option --profile/--add-profile to
form a union selection of the two options. The projects
selectors here will never replace what have been checked
out by profiles [array] [default: []]
--from Checkout projects downstream from (and including itself and
all its dependencies) project <from..>, can be used
together with option --profile/--add-profile to form a
union selection of the two options. The projects selectors
here will never replace what have been checked out by
profiles [array] [default: []]
```

View file

@ -19,7 +19,16 @@ Options:
-b Create a new branch and start it at <start-point> [boolean]
-B Create a new branch and start it at <start-point>; if it
already exists, reset it to <start-point> [boolean]
--to Checkout projects up to (and including) project <to..>, can
be used together with option --profile/--add-profile to
form a union selection of the two options. The projects
selectors here will never replace what have been checked
out by profiles [array] [default: []]
--from Checkout projects downstream from (and including itself and
all its dependencies) project <from..>, can be used
together with option --profile/--add-profile to form a
union selection of the two options. The projects selectors
here will never replace what have been checked out by
profiles [array] [default: []]
--profile [array] [default: []]
--add-profile [array] [default: []]
--to [array] [default: []]
--from [array] [default: []]

View file

@ -1,4 +1,4 @@
Running "sparo checkout --from build-test-utilities":
Running "sparo checkout --from sparo":
[bold]Sparo accelerator for Git __VERSION__ -[normal][cyan] https://tiktok.github.io/sparo/[default]
Node.js version is __VERSION__ (LTS)
@ -27,3 +27,9 @@ Checking out __FOLDER_COUNT__ folders...
[gray]-------------------------------------------------------------------------------[default]
Sparse checkout completed in __DURATION__
Checking out __FOLDER_COUNT__ folders...
[gray]--[[default] [bold]git sparse-checkout[normal] [gray]]------------------------------------------------------[default]
[gray]-------------------------------------------------------------------------------[default]
Sparse checkout completed in __DURATION__

View file

@ -91,7 +91,7 @@ export async function runAsync(runScriptOptions: IRunScriptOptions): Promise<voi
{
kind: 'sparo-command',
name: 'checkout-from',
args: ['checkout', '--from', 'build-test-utilities'],
args: ['checkout', '--from', 'sparo'],
currentWorkingDirectory: repoFolder
},
// sparo list-profiles