src/desktop/gitlab/select_project.ts (92 lines of code) (raw):
import vscode from 'vscode';
import { gitExtensionWrapper } from '../git/git_extension_wrapper';
import { createRemoteUrlPointers, GitRemoteUrlPointer, GitRepository } from '../git/new_git';
import { MultipleProjectsItem } from '../tree_view/items/multiple_projects_item';
import { NoProjectItem } from '../tree_view/items/no_project_item';
import { ProjectItemModel } from '../tree_view/items/project_item_model';
import { convertToGitLabProject, getProject } from '../../common/gitlab/api/get_project';
import { getGitLabServiceForAccount } from './get_gitlab_service';
import { getProjectRepository } from './gitlab_project_repository';
import { ProjectInRepository } from './new_project';
import { pickAccount } from './pick_account';
import { pickProject } from './pick_project';
import { convertProjectToSetting, selectedProjectStore } from './selected_project_store';
const selectRepository = async (): Promise<GitRepository | undefined> => {
const options = gitExtensionWrapper.gitRepositories.map(repository => ({
repository,
label: repository.rootFsPath,
}));
const choice = await vscode.window.showQuickPick(options, { title: 'Select Git repository' });
if (!choice) return undefined;
return choice.repository;
};
const pickRemoteUrl = async (pointers: GitRemoteUrlPointer[]) => {
if (pointers.length === 0) return undefined;
if (pointers.length === 1) return pointers[0];
return vscode.window.showQuickPick(
pointers.map(p => ({ ...p, label: p.urlEntry.url, description: p.remote.name })),
{ title: 'Select remote URL' },
);
};
const manuallyAssignProject = async (repository: GitRepository) => {
const account = await pickAccount();
if (!account) return;
const pointer = await pickRemoteUrl(createRemoteUrlPointers(repository));
if (!pointer) return;
const projectWithRepoInfo = await pickProject(getGitLabServiceForAccount(account));
if (!projectWithRepoInfo) return;
const { project } = await getGitLabServiceForAccount(account).fetchFromApi(
getProject(projectWithRepoInfo.fullPath),
);
if (!project) return;
const projectInRepository: ProjectInRepository = {
account,
pointer,
project: convertToGitLabProject(project),
initializationType: 'selected',
};
const selectedProjectSetting = convertProjectToSetting(projectInRepository);
await selectedProjectStore.addSelectedProject(selectedProjectSetting);
await vscode.window.showInformationMessage(
`Success: you assigned project ${project.fullPath} to remote URL ${pointer.urlEntry.url} in repository ${repository.rootFsPath}`,
);
};
const selectProject = async (repository: GitRepository) => {
const projects = getProjectRepository().getProjectsForRepository(repository.rootFsPath);
const options = [
...projects.map(p => ({
...p,
label: p.project.namespaceWithPath,
description: 'detected',
detail: `${p.account.instanceUrl} (${p.account.username})`,
isOther: false as const,
})),
{
label: 'Manually Assign GitLab Project to Repository',
detail: 'Use this if your Git remote URL does not have the standard format.',
isOther: true as const,
},
];
const selectedProject = await vscode.window.showQuickPick(options, {
title: 'Select GitLab Project',
});
if (!selectedProject) return;
if (selectedProject.isOther) {
await manuallyAssignProject(repository);
return;
}
await selectedProjectStore.addSelectedProject(convertProjectToSetting(selectedProject));
};
export const assignProject = async (item: NoProjectItem) => manuallyAssignProject(item.repository);
export const selectProjectCommand = async (item: MultipleProjectsItem | NoProjectItem) =>
selectProject(item.repository);
export const selectProjectForRepository = async () => {
const repository = await selectRepository();
if (!repository) return;
await selectProject(repository);
};
export const clearSelectedProjects = async (item: ProjectItemModel) => {
await selectedProjectStore.clearSelectedProjects(
item.projectInRepository.pointer.repository.rootFsPath,
);
};