Skip to content
Merged
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
4 changes: 3 additions & 1 deletion tools/tsp-client/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,15 @@ Convert an existing swagger specification to a TypeSpec project. This command sh
--commit Commit to be used for project init or update [string]
-d, --debug Enable debug logging [boolean]
--emitter-options The options to pass to the emitter [string]
--generate-lock-file Generate a lock file under the eng/ directory from
an existing emitter-package.json [boolean]
-h, --help Show help [boolean]
--local-spec-repo Path to local repository with the TypeSpec project [string]
--save-inputs Don't clean up the temp directory after generation [boolean]
--skip-sync-and-generate Skip sync and generate during project init [boolean]
--swagger-readme Path or url to swagger readme file [string]
-o, --output-dir Specify an alternate output directory for the
generated files. Default is your local directory. [string]
generated files. Default is your current directory [string]
--repo Repository where the project is defined for init
or update [string]
-v, --version Show version number [boolean]
Expand Down
23 changes: 22 additions & 1 deletion tools/tsp-client/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,22 @@ async function convert(readme: string, outputDir: string): Promise<void> {
});
}

async function generateLockFile(rootUrl: string, repoRoot: string) {
Logger.info("Generating lock file...");
const args: string[] = ["install"];
if (process.env['TSPCLIENT_FORCE_INSTALL']?.toLowerCase() === "true") {
args.push("--force");
}
const tempRoot = await createTempDirectory(rootUrl);
await cp(joinPaths(repoRoot, "eng", "emitter-package.json"), joinPaths(tempRoot, "package.json"));
await npmCommand(tempRoot, args);
const lockFile = await stat(joinPaths(tempRoot, "package-lock.json"));
if (lockFile.isFile()) {
await cp(joinPaths(tempRoot, "package-lock.json"), joinPaths(repoRoot, "eng", "emitter-package-lock.json"));
}
await removeDirectory(tempRoot);
Logger.info(`Lock file generated in ${joinPaths(rootUrl, "emitter-package-lock.json")}`);
}

async function main() {
const options = await getOptions();
Expand All @@ -285,7 +301,12 @@ async function main() {
} catch (err) {
Logger.debug(`Error occurred while attempting to remove sparse-spec directory: ${err}`);
}


if (options.generateLockFile) {
await generateLockFile(rootUrl, repoRoot);
return;
}

switch (options.command) {
case "init":
const emitter = await getEmitterFromRepoConfig(joinPaths(repoRoot, "eng", "emitter-package.json"));
Expand Down
2 changes: 2 additions & 0 deletions tools/tsp-client/src/log.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ Options:
--commit Commit to be used for project init or update [string]
-d, --debug Enable debug logging [boolean]
--emitter-options The options to pass to the emitter [string]
--generate-lock-file Generate a lock file under the eng/ directory from
an existing emitter-package.json [boolean]
-h, --help Show help [boolean]
--local-spec-repo Path to local repository with the TypeSpec project [string]
--save-inputs Don't clean up the temp directory after generation [boolean]
Expand Down
72 changes: 40 additions & 32 deletions tools/tsp-client/src/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export interface Options {
isUrl: boolean;
localSpecRepo?: string;
emitterOptions?: string;
generateLockFile: boolean;
swaggerReadme?: string;
}

Expand Down Expand Up @@ -53,6 +54,9 @@ export async function getOptions(): Promise<Options> {
["emitter-options"]: {
type: "string",
},
["generate-lock-file"]: {
"type": "boolean",
},
["local-spec-repo"]: {
type: "string",
},
Expand All @@ -77,50 +81,53 @@ export async function getOptions(): Promise<Options> {
process.exit(0);
}

if (positionals.length === 0) {
Logger.error("Command is required");
printUsage();
process.exit(1);
}
let isUrl = true;
const supportedCommands = ["sync", "generate", "update", "init", "convert"];

const command = positionals[0];
if (!command) {
Logger.error("Command is required");
printUsage();
process.exit(1);
}

if (!supportedCommands.includes(command)) {
Logger.error(`Unknown command ${command}`);
printUsage();
process.exit(1);
}
if (!values["generate-lock-file"]) {
if (positionals.length === 0) {
Logger.error("Command is required");
printUsage();
process.exit(1);
}

let isUrl = true;
if (command === "init") {
if (!values["tsp-config"]) {
Logger.error("tspConfig is required");
if (!command) {
Logger.error("Command is required");
printUsage();
process.exit(1);
}
if (await doesFileExist(values["tsp-config"])) {
isUrl = false;

if (!supportedCommands.includes(command)) {
Logger.error(`Unknown command ${command}`);
printUsage();
process.exit(1);
}
if (!isUrl) {
if (!values.commit || !values.repo) {
Logger.error("The commit and repo options are required when tspConfig is a local directory");

if (command === "init") {
if (!values["tsp-config"]) {
Logger.error("tspConfig is required");
printUsage();
process.exit(1);
}
if (await doesFileExist(values["tsp-config"])) {
isUrl = false;
}
if (!isUrl) {
if (!values.commit || !values.repo) {
Logger.error("The commit and repo options are required when tspConfig is a local directory");
printUsage();
process.exit(1);
}
}
}
}

if (command === "convert") {
if (!values["swagger-readme"]) {
Logger.error("Must specify a swagger readme with the `--swagger-readme` flag");
printUsage();
process.exit(1);
if (command === "convert") {
if (!values["swagger-readme"]) {
Logger.error("Must specify a swagger readme with the `--swagger-readme` flag");
printUsage();
process.exit(1);
}
}
}

Expand Down Expand Up @@ -154,7 +161,7 @@ export async function getOptions(): Promise<Options> {

return {
debug: values.debug ?? false,
command: command,
command: command ?? "",
tspConfig: values["tsp-config"],
noCleanup: values["save-inputs"] ?? false,
skipSyncAndGenerate: values["skip-sync-and-generate"] ?? false,
Expand All @@ -164,6 +171,7 @@ export async function getOptions(): Promise<Options> {
isUrl: isUrl,
localSpecRepo: values["local-spec-repo"],
emitterOptions: values["emitter-options"],
generateLockFile: values["generate-lock-file"] ?? false,
swaggerReadme: values["swagger-readme"],
};
}