Skip to content

Instantly share code, notes, and snippets.

@mrgrain
Last active June 20, 2023 10:45
Show Gist options
  • Save mrgrain/f9d46f276e55593418a125de932be38c to your computer and use it in GitHub Desktop.
Save mrgrain/f9d46f276e55593418a125de932be38c to your computer and use it in GitHub Desktop.
#!/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