(options: {
preferredProjectLocation: string | null
repositoryUrl: string
})
| 121 | } |
| 122 | |
| 123 | export async function createProjectFromGitHubUrl(options: { |
| 124 | preferredProjectLocation: string | null |
| 125 | repositoryUrl: string |
| 126 | }) { |
| 127 | const preferredProjectLocation = options.preferredProjectLocation?.trim() ?? '' |
| 128 | if (preferredProjectLocation.length === 0) { |
| 129 | throw new Error('Set a default project location in Settings first.') |
| 130 | } |
| 131 | |
| 132 | const repository = parseGitHubRepositoryUrl(options.repositoryUrl) |
| 133 | if (!repository) { |
| 134 | throw new Error('Paste a GitHub repository URL such as https://github.com/owner/repo.') |
| 135 | } |
| 136 | |
| 137 | const existingProjectId = await findExistingGitHubProject(repository.canonicalUrl) |
| 138 | if (existingProjectId) { |
| 139 | moveProjectToTop(existingProjectId) |
| 140 | return { projectId: existingProjectId } |
| 141 | } |
| 142 | |
| 143 | const parentDirectory = path.resolve(preferredProjectLocation) |
| 144 | const projectPath = path.join(parentDirectory, sanitizeProjectFolderName(repository.folderName)) |
| 145 | await mkdir(parentDirectory, { recursive: true }) |
| 146 | |
| 147 | const existingDirectoryProject = await addExistingRepositoryProject( |
| 148 | projectPath, |
| 149 | repository.canonicalUrl, |
| 150 | ) |
| 151 | if (existingDirectoryProject) { |
| 152 | return existingDirectoryProject |
| 153 | } |
| 154 | |
| 155 | if (await directoryExists(projectPath)) { |
| 156 | throw new Error( |
| 157 | `A folder named ${repository.folderName} already exists there. Choose an empty location before cloning this GitHub repository.`, |
| 158 | ) |
| 159 | } |
| 160 | |
| 161 | try { |
| 162 | await execFile('git', ['clone', '--progress', repository.cloneUrl, projectPath], { |
| 163 | cwd: parentDirectory, |
| 164 | env: getNonInteractiveGitEnv(), |
| 165 | timeout: 120_000, |
| 166 | maxBuffer: 1024 * 1024 * 4, |
| 167 | }) |
| 168 | } catch (error) { |
| 169 | const resolvedProjectPath = await resolvePathIfPresent(projectPath) |
| 170 | const resolvedExistingProject = await findExistingGitHubProject(repository.canonicalUrl) |
| 171 | if ( |
| 172 | resolvedExistingProject && |
| 173 | (await resolvePathIfPresent(resolvedExistingProject)) === resolvedProjectPath |
| 174 | ) { |
| 175 | moveProjectToTop(resolvedExistingProject) |
| 176 | return { projectId: resolvedExistingProject } |
| 177 | } |
| 178 | |
| 179 | throw new Error(`Unable to clone ${repository.canonicalUrl}: ${formatGitCommandError(error)}`) |
| 180 | } |
no test coverage detected