Last active
June 20, 2023 10:45
-
-
Save mrgrain/f9d46f276e55593418a125de932be38c to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env node | |
const { spawnSync } = require("node:child_process"); | |
const fs = require("node:fs"); | |
const os = require("node:os"); | |
const path = require("node:path"); | |
const spawny = (command, cwd) => { | |
rawny(command.split(" "), cwd); | |
} | |
const rawny = (commands, cwd) => { | |
const [cmd, ...rest] = commands; | |
console.log(commands.join(" ")); | |
const res = spawnSync(cmd, rest, { stdio: 'inherit', cwd }); | |
if (res.status !== 0) { | |
throw Error(res.stderr.toString()) | |
} | |
} | |
const loopy = async (block, message = 'Please fix any issues and press any key to try again') => { | |
try { | |
block() | |
} catch (e) { | |
await confirm(message); | |
await loopy(block, message); | |
} | |
} | |
const npxProjen = (cwd) => spawny('npx projen default', cwd) | |
const confirm = async (msg = 'Press any key to continue') => { | |
const stdin = process.stdin; | |
stdin.resume(); | |
stdin.setEncoding('utf8'); | |
return new Promise((resolve, reject) => { | |
console.log(msg); | |
stdin.once('data', function (key) { | |
// ctrl-c ( end of text ) | |
if (key === '\u0003') { | |
process.exitCode = 1; | |
return reject(); | |
} | |
return resolve(); | |
}); | |
}) | |
} | |
const prepareWorkDir = (repo = undefined) => { | |
if (!repo) { | |
return process.cwd(); | |
} | |
const basedir = path.join(os.homedir(), ".pjs2ts"); | |
fs.mkdirSync(basedir, { recursive: true }); | |
return fs.mkdtempSync(path.join(basedir, `${repo.replaceAll('/', '-')}-`)); | |
} | |
let workDir; | |
let repo; | |
async function main() { | |
/** | |
* Configuration | |
*/ | |
repo = process.argv.slice(2).at(0); | |
if (!repo) { | |
console.log("Using current path...") | |
} | |
workDir = prepareWorkDir(repo); | |
const rcJsName = process.argv.slice(2).at(1) ?? ".projenrc.js"; | |
const rcTsName = '.projenrc.ts'; | |
const rcFilePath = path.join(workDir, rcJsName); | |
/** | |
* Checkout repo to tmp dir | |
*/ | |
if (repo) { | |
spawny(`gh repo clone ${repo} .`, workDir); | |
} | |
spawny(`git switch -c mrgrain/chore/projenrcts-${path.basename(workDir)}`, workDir); | |
spawny(`yarn install`, workDir); | |
/** | |
* Add projenrcTs: true to your project. | |
*/ | |
console.log('Setting `projenrcTs: true`'); | |
const rcFileBuffer = fs.readFileSync(rcFilePath, { encoding: 'utf8' }).split('\n'); | |
const nameLine = rcFileBuffer.findIndex((l) => l.match(/name\:.*,/)); | |
rcFileBuffer.splice(nameLine + 1, 0, ' projenrcTs: true,'); | |
fs.writeFileSync(rcFilePath, rcFileBuffer.join('\n')); | |
/** | |
* Run npx projen. | |
*/ | |
npxProjen(workDir); | |
/** | |
* Rename .projenrc.js to .projenrc.ts. | |
*/ | |
console.log(`${rcJsName} -> ${rcTsName}`); | |
const newRcFilePath = path.join(workDir, rcTsName); | |
fs.renameSync(rcFilePath, newRcFilePath); | |
/** | |
* Update requires to imports. | |
*/ | |
spawny(`npx --yes [email protected] ${rcTsName}`, workDir); | |
/** | |
* Run npx projen. | |
*/ | |
spawny(`code -a ${workDir}`); | |
spawny(`code ${workDir}/${rcTsName}`); | |
console.log("Please make sure the project compiles.") | |
await loopy(() => npxProjen(workDir)); | |
/** | |
* Commit changes to branch & create PR | |
*/ | |
spawny('git add .', workDir); | |
rawny(['git', 'commit', '-m', `chore: ${rcTsName}`], workDir); | |
spawny("git push -u origin HEAD", workDir) | |
spawny('gh pr create --fill', workDir); | |
} | |
main().catch(e => { | |
process.exitCode = 1; | |
console.error('Error: ' + e.message); | |
}).finally(async () => { | |
if (repo && workDir) { | |
console.log(`rm -rf ${workDir}`); | |
await confirm('Press any key to start cleanup') | |
fs.rmSync(workDir, { recursive: true, force: true }); | |
} | |
process.exit(0); | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment