Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

feat(api): rebuild command #798

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 94 additions & 0 deletions packages/api/src/commands/rebuild.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import path from 'node:path';

import chalk from 'chalk';
import { Command, Option } from 'commander';
import ora from 'ora';

import { SupportedLanguages, uninstallerFactory } from '../codegen/factory.js';
import promptTerminal from '../lib/prompt.js';
import logger from '../logger.js';
import Storage from '../storage.js';

interface Options {
yes?: boolean;
}

const cmd = new Command();
cmd
.name('rebuild')
.description('rebuild an installed SDK')
.argument('<identifier>', 'the SDK to rebuild')
.addOption(new Option('-y, --yes', 'Automatically answer "yes" to any prompts printed'))
.action(async (identifier: string, options: Options) => {
// We don't know if we have `identifier` in the storage system yet, we just need to preload the
// system so we can access lockfiles.
const storage = new Storage('', SupportedLanguages.JS, identifier);

const entry = Storage.getFromLockfile(identifier);
if (!entry) {
logger(
`You do not appear to have ${identifier} installed. You can run \`npx api list\` to see what SDKs are present.`,
true,
);
process.exit(1);
}

storage.setLanguage(entry?.language);
storage.setIdentifier(identifier);

const directory = path.relative(process.cwd(), storage.getIdentifierStorageDir());
if (!options.yes) {
await promptTerminal({
type: 'confirm',
name: 'value',
message: `Are you sure you want to uninstall ${chalk.yellow(identifier)}? This will delete the ${chalk.yellow(
directory,
)} directory and potentially any changes you may have made there.`,
initial: true,
}).then(({ value }) => {
if (!value) {
process.exit(1);
}
});
}

let spinner = ora(`Uninstalling ${chalk.grey(identifier)}`).start();

// If we have a known package name for this then we can uninstall it from within cooresponding
// package manager.
const pkgName = storage.getPackageName();
if (pkgName) {
const language = storage.getSDKLanguage();
await uninstallerFactory(language, storage)
.then(() => {
spinner.succeed(spinner.text);
})
.catch(err => {
spinner.fail(spinner.text);
logger(err.message, true);
process.exit(1);
});
}

spinner = ora(`Removing ${chalk.grey(directory)}`).start();
await storage
.remove()
.then(() => {
spinner.succeed(spinner.text);
})
.catch(err => {
spinner.fail(spinner.text);
logger(err.message, true);
process.exit(1);
});

logger('🚀 All done!');
})
.addHelpText(
'after',
`
Examples:
$ npx api rebuild petstore`,
);

export default cmd;
16 changes: 16 additions & 0 deletions packages/api/src/storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,22 @@ export default class Storage {
Storage.lockfile = false;
}

static initForIdentifier(identifier: string) {
// We don't know if we have `identifier` in the storage system yet, we just need to preload the
// system so we can access lockfiles.
const storage = new Storage('', SupportedLanguages.JS, identifier);

const entry = Storage.getFromLockfile(identifier);
if (!entry) {
throw new Error(`${identifier} does not exist in the lockfile.`);
}

storage.setLanguage(entry?.language);
storage.setIdentifier(identifier);

return storage;
}

static getLockfilePath() {
return path.join(Storage.dir, 'api.json');
}
Expand Down