Skip to content

Commit

Permalink
Init redesign (#6045)
Browse files Browse the repository at this point in the history
fix #5876
fix [#5859](#5859)


## Non empty folder confirmation

<img width="560" alt="image"
src="https://github.com/user-attachments/assets/980f7a7b-35bc-4889-8e1a-3e8d3b2edfb8"
/>

## Template selection

<img width="603" alt="image"
src="https://github.com/user-attachments/assets/2295cdbc-bb89-4212-9aa7-d1023b8e9b30"
/>

## Installaling dependencies

<img width="822" alt="image"
src="https://github.com/user-attachments/assets/f8ae2e36-99fc-4bed-b4f3-8cccd8bac9cf"
/>

## Completed
<img width="586" alt="image"
src="https://github.com/user-attachments/assets/749d25d6-3182-4548-b42c-6ed64e191662"
/>


## Interupted 
<img width="421" alt="image"
src="https://github.com/user-attachments/assets/07c5acad-d115-464c-9e81-feff2fae83c7"
/>

---------

Co-authored-by: Crystal Barragan <[email protected]>
  • Loading branch information
timotheeguerin and ccbarragan authored Feb 27, 2025
1 parent 1696b0d commit cf7aaf0
Show file tree
Hide file tree
Showing 17 changed files with 580 additions and 180 deletions.
8 changes: 8 additions & 0 deletions .chronus/changes/init-redesign-2025-1-18-19-38-34.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
# Change versionKind to one of: internal, fix, dependencies, feature, deprecation, breaking
changeKind: feature
packages:
- "@typespec/compiler"
---

Redesign and simplification of `tsp init`
6 changes: 6 additions & 0 deletions .chronus/changes/init-redesign-2025-1-20-20-5-0.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
# Change versionKind to one of: internal, fix, dependencies, feature, deprecation, breaking
changeKind: internal
packages:
- typespec-vscode
---
30 changes: 13 additions & 17 deletions packages/compiler/.scripts/build-init-templates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,56 +9,52 @@ const pkgJson = JSON.parse(
const minCompilerVersion = pkgJson.version;

const builtInTemplates: Record<string, InitTemplate> = {
empty: {
title: "Empty project",
description: "Create an empty project.",
libraries: [],
compilerVersion: minCompilerVersion,
},
rest: {
title: "Generic REST API",
description: "Create a project representing a generic REST API",
description: "Create a project representing a generic REST API service.",
compilerVersion: minCompilerVersion,
libraries: ["@typespec/http", "@typespec/rest", "@typespec/openapi", "@typespec/openapi3"],
emitters: {
"@typespec/openapi3": {
selected: true,
label: "OpenAPI 3.1 document",
options: {
"emitter-output-dir": "{output-dir}/schema",
"openapi-versions": ["3.1.0"],
},
},
"@typespec/http-client-csharp": {
description: "CSharp Client emitter",
label: "C# client",
options: {
"emitter-output-dir": "{output-dir}/clients/csharp",
},
},
"@typespec/http-client-java": {
description: "Java Client emitter",
label: "Java client",
options: {
"emitter-output-dir": "{output-dir}/clients/java",
},
},
"@azure-tools/typespec-ts": {
description: "JavaScript Client emitter",
label: "JavaScript client",
options: {
"emitter-output-dir": "{output-dir}/clients/js",
},
},
"@typespec/http-client-python": {
description: "Python Client emitter",
label: "Python client",
options: {
"emitter-output-dir": "{output-dir}/clients/python",
},
},
"@typespec/http-server-csharp": {
description: "CSharp server stubs",
label: "C# server stubs",
options: {
"emitter-output-dir": "{output-dir}/server/generated",
},
},
"@typespec/http-server-javascript": {
description: "Javascript server stubs",
label: "JavaScript server stubs",
options: {
"emitter-output-dir": "{output-dir}/server",
},
Expand All @@ -67,8 +63,8 @@ const builtInTemplates: Record<string, InitTemplate> = {
files: [...(await localDir("rest"))],
},
"library-ts": {
title: "TypeSpec Library (With TypeScript)",
description: "Create a new package to add decorators or linters to typespec.",
title: "TypeSpec library",
description: "Build your own TypeSpec library with custom types, decorators or linters.",
compilerVersion: minCompilerVersion,
libraries: [],
files: [
Expand All @@ -78,8 +74,8 @@ const builtInTemplates: Record<string, InitTemplate> = {
],
},
"emitter-ts": {
title: "TypeSpec Emitter (With TypeScript)",
description: "Create a new package that will be emitting typespec",
title: "TypeSpec emitter",
description: "Create a new package that emits artifacts from TypeSpec.",
compilerVersion: minCompilerVersion,
libraries: [],
files: [
Expand Down
4 changes: 2 additions & 2 deletions packages/compiler/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -92,14 +92,15 @@
},
"dependencies": {
"@babel/code-frame": "~7.26.2",
"@inquirer/prompts": "^7.3.1",
"@npmcli/arborist": "^8.0.0",
"ajv": "~8.17.1",
"change-case": "~5.4.4",
"globby": "~14.0.2",
"is-unicode-supported": "^2.1.0",
"mustache": "~4.2.0",
"picocolors": "~1.1.1",
"prettier": "~3.4.2",
"prompts": "~2.4.2",
"semver": "^7.6.3",
"temporal-polyfill": "^0.2.5",
"vscode-languageserver": "~9.0.1",
Expand All @@ -112,7 +113,6 @@
"@types/mustache": "~4.2.5",
"@types/node": "~22.10.10",
"@types/npmcli__arborist": "^6.3.0",
"@types/prompts": "~2.4.9",
"@types/semver": "^7.5.8",
"@types/yargs": "~17.0.33",
"@typespec/internal-build-utils": "workspace:~",
Expand Down
4 changes: 4 additions & 0 deletions packages/compiler/src/core/cli/actions/compile/compile.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { typespecVersion } from "../../../../utils/misc.js";
import { logDiagnostics } from "../../../diagnostics.js";
import { resolveTypeSpecEntrypoint } from "../../../entrypoint-resolution.js";
import { CompilerOptions } from "../../../options.js";
Expand All @@ -14,6 +15,9 @@ import { CompileCliArgs, getCompilerOptions } from "./args.js";
import { ProjectWatcher, WatchHost, createWatchHost, createWatcher } from "./watch.js";

export async function compileAction(host: CliCompilerHost, args: CompileCliArgs) {
// eslint-disable-next-line no-console
console.log(`TypeSpec compiler v${typespecVersion}\n`);

const diagnostics: Diagnostic[] = [];
const entrypoint = await resolveTypeSpecEntrypoint(
host,
Expand Down
3 changes: 0 additions & 3 deletions packages/compiler/src/core/cli/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,6 @@ import {
} from "./utils.js";

async function main() {
// eslint-disable-next-line no-console
console.log(`TypeSpec compiler v${typespecVersion}\n`);

await yargs(process.argv.slice(2))
.scriptName("tsp")
.help()
Expand Down
31 changes: 26 additions & 5 deletions packages/compiler/src/core/install.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,14 @@ interface SpawnError {
export async function installTypeSpecDependencies(
host: CliCompilerHost,
directory: string,
stdio: "inherit" | "pipe" = "inherit",
): Promise<void> {
// Only use the builtin npm when running in standalone tsp mode.
// TBD how we'll change this as we move to a more integrated setup and resolve the user package manager.
if (getTypeSpecEngine() === "tsp") {
await installWithBuiltinNpm(host, directory);
} else {
await installWithNpmExe(host, directory);
await installWithNpmExe(host, directory, stdio);
}
}

Expand All @@ -34,15 +35,31 @@ async function installWithBuiltinNpm(host: CliCompilerHost, directory: string):
await arb.reify();
}

async function installWithNpmExe(host: CliCompilerHost, directory: string): Promise<void> {
async function installWithNpmExe(
host: CliCompilerHost,
directory: string,
stdio: "inherit" | "pipe",
): Promise<void> {
const child = spawn("npm", ["install"], {
shell: process.platform === "win32",
stdio: "inherit",
stdio: "pipe",
cwd: directory,
env: process.env,
});

return new Promise(() => {
const stdout: string[] = [];
if (child.stdout) {
child.stdout.on("data", (data) => {
stdout.push(data.toString());
});
}
if (child.stderr) {
child.stderr.on("data", (data) => {
stdout.push(data.toString());
});
}

return new Promise((resolve, reject) => {
child.on("error", (error: SpawnError) => {
if (error.code === "ENOENT") {
host.logger.error(
Expand All @@ -54,7 +71,11 @@ async function installWithNpmExe(host: CliCompilerHost, directory: string): Prom
process.exit(error.errno);
});
child.on("exit", (exitCode) => {
process.exit(exitCode ?? -1);
if (exitCode !== 0) {
reject(new Error(`Npm installed failed with exit code ${exitCode}\n${stdout.join("\n")}`));
} else {
resolve();
}
});
});
}
6 changes: 6 additions & 0 deletions packages/compiler/src/init/file-templating.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import { camelCase, kebabCase, pascalCase } from "change-case";
import Mustache from "mustache";
import { getBaseFileName } from "../core/path-utils.js";
import type { InitTemplate } from "./init-template.js";
import type { ScaffoldingConfig } from "./scaffold.js";

export type FileTemplatingContext = Omit<InitTemplate, "libraries"> &
ScaffoldingConfig & {
/** Name of the folder */
folderName: string;

casing: CasingUtils;
/**
* NormalizeVersion function replaces `-` with `_`.
Expand All @@ -29,9 +33,11 @@ export interface CasingUtils {
}

export function createFileTemplatingContext(config: ScaffoldingConfig): FileTemplatingContext {
const folderName = getBaseFileName(config.directory);
return {
...config.template,
...config,
folderName,
normalizeVersion,
toLowerCase,
normalizePackageName,
Expand Down
3 changes: 3 additions & 0 deletions packages/compiler/src/init/init-template.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ export interface InitTemplate {
* Describes emitter dependencies that will be added to the generated project.
*/
export interface EmitterTemplate {
/** Friendly name for the emitter */
label?: string;
/** Emitter Selection Description */
description?: string;
/** Whether emitter is selected by default in the list */
Expand Down Expand Up @@ -126,6 +128,7 @@ export const InitTemplateSchema: JSONSchemaType<InitTemplate> = {
additionalProperties: {
type: "object",
properties: {
label: { type: "string", nullable: true },
description: { type: "string", nullable: true },
selected: { type: "boolean", nullable: true },
options: {} as any,
Expand Down
Loading

0 comments on commit cf7aaf0

Please sign in to comment.