UNPKG

isaacscript

Version:

A command line tool for managing Isaac mods written in TypeScript.

140 lines 6.39 kB
import chalk from "chalk"; import { commandExists, isFile, readFile } from "complete-node"; import path from "node:path"; import yaml from "yaml"; import { HOME_DIR, PROJECT_NAME, PROJECT_VERSION } from "./constants.js"; import { execShell, execShellString } from "./exec.js"; import { getInputString, getInputYesNo } from "./prompt.js"; export async function promptGitHubRepoOrGitRemoteURL(projectName, yes, skipGit, dev, verbose) { if (skipGit || dev) { return undefined; } // Hard-code certain project names as never causing a Git repository to be initialized. if (projectName.startsWith("test") || projectName === "foo") { return undefined; } // We do not need to prompt the user if they do not have Git installed. const gitExists = await commandExists("git"); if (!gitExists) { console.log('Git does not seem to be installed. (The "git" command is not in the path.) Skipping Git-related things.'); return undefined; } const gitHubUsername = await getGitHubUsername(); if (gitHubUsername !== undefined) { const { exitStatus } = execShell("gh", ["repo", "view", projectName], verbose, true); const gitHubRepoExists = exitStatus === 0; const url = `https://github.com/${gitHubUsername}/${projectName}`; if (gitHubRepoExists) { console.log(`Detected an existing GitHub repository at: ${chalk.green(url)}`); const guessedRemoteURL = getGitRemoteURL(projectName, gitHubUsername); if (yes) { console.log(`Using a Git remote URL of: ${chalk.green(guessedRemoteURL)}`); return guessedRemoteURL; } const shouldUseGuessedURL = await getInputYesNo(`Do you want to use a Git remote URL of: ${chalk.green(guessedRemoteURL)}`); if (shouldUseGuessedURL) { return guessedRemoteURL; } // Assume that since they do not want to connect this project to the existing GitHub // repository, they do not want to initialize a remote Git URL at all. return undefined; } if (yes) { execShell("gh", ["repo", "create", projectName, "--public"]); console.log(`Created a new GitHub repository at: ${chalk.green(url)}`); return getGitRemoteURL(projectName, gitHubUsername); } const createNewGitHubRepo = await getInputYesNo(`Would you like to create a new GitHub repository at: ${chalk.green(url)}`); if (createNewGitHubRepo) { execShell("gh", ["repo", "create", projectName, "--public"]); console.log("Successfully created a new GitHub repository."); return getGitRemoteURL(projectName, gitHubUsername); } // Assume that since they do not want to create a new GitHub repository, they do not want to // initialize a remote Git URL at all. return undefined; } const gitRemoteURL = await getInputString(`Paste in the remote Git URL for your project. For example, if you have an SSH key, it would be something like: ${chalk.green("git@github.com:Alice/green-candle.git")} If you don't have an SSH key, it would be something like: ${chalk.green("https://github.com/Alice/green-candle.git")} If you don't want to initialize a Git repository for this project, press enter to skip. `); return gitRemoteURL === "" ? undefined : gitRemoteURL; } /** * If the GitHub CLI is installed, we can derive the user's GitHub username from their YAML * configuration. */ async function getGitHubUsername() { const ghExists = await commandExists("gh"); if (!ghExists) { return undefined; } const githubCLIHostsPath = getGithubCLIHostsPath(); if (githubCLIHostsPath === undefined) { return undefined; } const file = await isFile(githubCLIHostsPath); if (!file) { return undefined; } const configYAMLRaw = await readFile(githubCLIHostsPath); const configYAML = yaml.parse(configYAMLRaw); const githubCom = configYAML["github.com"]; if (githubCom === undefined) { return undefined; } const { user } = githubCom; if (user === undefined || user === "") { return undefined; } return user; } function getGithubCLIHostsPath() { if (process.platform === "win32") { const appData = process.env["APPDATA"]; if (appData === undefined || appData === "") { return undefined; } return path.join(appData, "GitHub CLI", "hosts.yml"); } // The location is the same on both macOS and Linux. return path.join(HOME_DIR, ".config", "gh", "hosts.yml"); } function getGitRemoteURL(projectName, gitHubUsername) { return `git@github.com:${gitHubUsername}/${projectName}.git`; } export async function initGitRepository(projectPath, gitRemoteURL, verbose) { const gitExists = await commandExists("git"); if (!gitExists) { return; } if (gitRemoteURL === undefined) { return; } execShellString("git init --initial-branch main", verbose, false, projectPath); execShell("git", ["remote", "add", "origin", gitRemoteURL], verbose, false, projectPath); if (isGitNameAndEmailConfigured(verbose)) { execShellString("git add --all", verbose, false, projectPath); const commitMessage = `chore: add files from ${PROJECT_NAME} ${PROJECT_VERSION} template`; execShell("git", ["commit", "--message", commitMessage], verbose, false, projectPath); execShellString("git push --set-upstream origin main", verbose, false, projectPath); } } function isGitNameAndEmailConfigured(verbose) { const nameExitStatus = execShellString("git config --global user.name", verbose, true).exitStatus; const emailExitStatus = execShellString("git config --global user.email", verbose, true).exitStatus; return nameExitStatus === 0 && emailExitStatus === 0; } export function gitCommitAllAndPush(message, verbose) { execShellString("git add --all", verbose); execShell("git", ["commit", "--message", message], verbose); execShellString("git push", verbose); console.log(`Committed and pushed to the git repository with a message of: ${message}`); } export function getReleaseGitCommitMessage(version) { return `chore: release ${version}`; } //# sourceMappingURL=git.js.map