diff --git a/.changeset/two-points-cheer.md b/.changeset/two-points-cheer.md new file mode 100644 index 000000000..d41de5eb1 --- /dev/null +++ b/.changeset/two-points-cheer.md @@ -0,0 +1,5 @@ +--- +"create-eth": patch +--- + +cli: allow github url as extension flag diff --git a/src/utils/external-extensions.ts b/src/utils/external-extensions.ts index 376726d46..504a70905 100644 --- a/src/utils/external-extensions.ts +++ b/src/utils/external-extensions.ts @@ -4,23 +4,45 @@ import { fileURLToPath } from "url"; import { ExternalExtension, RawOptions, SolidityFramework } from "../types"; import { CURATED_EXTENSIONS } from "../curated-extensions"; import { SOLIDITY_FRAMEWORKS } from "./consts"; + +function deconstructGithubUrl(url: string) { + const urlParts = url.split("/"); + const ownerName = urlParts[3]; + const repoName = urlParts[4]; + const branch = urlParts[5] === "tree" ? urlParts[6] : undefined; + + return { ownerName, repoName, branch }; +} + // Gets the data from the argument passed to the `--extension` option. -// e.g. owner/project:branch => { githubBranchUrl, githubUrl, branch, owner, project } export const getDataFromExternalExtensionArgument = (externalExtension: string) => { if (CURATED_EXTENSIONS[externalExtension.toLowerCase()]) { externalExtension = getArgumentFromExternalExtensionOption(CURATED_EXTENSIONS[externalExtension]); } + const isGithubUrl = externalExtension.startsWith("https://github.com/"); + // Check format: owner/project:branch (branch is optional) const regex = /^[^/]+\/[^/]+(:[^/]+)?$/; - if (!regex.test(externalExtension)) { - throw new Error(`Invalid extension format. Use "owner/project" or "owner/project:branch"`); + if (!regex.test(externalExtension) && !isGithubUrl) { + throw new Error(`Invalid extension format. Use "owner/project", "owner/project:branch" or github url.`); } - // Extract owner, project and branch - const owner = externalExtension.split("/")[0]; - const project = externalExtension.split(":")[0].split("/")[1]; - const branch = externalExtension.split(":")[1]; + let owner; + let project; + let branch; + + if (isGithubUrl) { + const { ownerName, repoName, branch: urlBranch } = deconstructGithubUrl(externalExtension); + owner = ownerName; + project = repoName; + branch = urlBranch; + } else { + // Extract owner, project and branch if format passed is owner/project:branch + owner = externalExtension.split("/")[0]; + project = externalExtension.split(":")[0].split("/")[1]; + branch = externalExtension.split(":")[1]; + } const githubUrl = `https://github.com/${owner}/${project}`; let githubBranchUrl; @@ -72,9 +94,7 @@ export const getSolidityFrameworkDirsFromExternalExtension = async ( } const { branch, repository } = externalExtension; - const splitUrl = repository.split("/"); - const ownerName = splitUrl[splitUrl.length - 2]; - const repoName = splitUrl[splitUrl.length - 1]; + const { ownerName, repoName } = deconstructGithubUrl(repository); const githubApiUrl = `https://api.github.com/repos/${ownerName}/${repoName}/contents/extension/packages${branch ? `?ref=${branch}` : ""}`; const res = await fetch(githubApiUrl); if (!res.ok) {