Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Init redesign #6045

Merged
merged 27 commits into from
Feb 27, 2025
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
3a7318c
Init redesign initial pass
timotheeguerin Feb 15, 2025
e98e0c8
progress
timotheeguerin Feb 15, 2025
e184345
Better instructions
timotheeguerin Feb 18, 2025
eba0c54
Styles
timotheeguerin Feb 18, 2025
f2abace
tweaks
timotheeguerin Feb 18, 2025
a1c4042
remove empty template
timotheeguerin Feb 18, 2025
38b74a2
.
timotheeguerin Feb 18, 2025
d738bb8
Create init-redesign-2025-1-18-19-38-34.md
timotheeguerin Feb 18, 2025
8035187
Fix
timotheeguerin Feb 18, 2025
6feb2e3
Merge branch 'main' of https://github.com/Microsoft/typespec into ini…
timotheeguerin Feb 18, 2025
6ca8164
Merge branch 'init-redesign' of https://github.com/timotheeguerin/typ…
timotheeguerin Feb 18, 2025
5b0f2ad
.
timotheeguerin Feb 18, 2025
f168bc0
Apply suggestions from code review
timotheeguerin Feb 19, 2025
199a406
regen
timotheeguerin Feb 19, 2025
60fd207
.
timotheeguerin Feb 19, 2025
a4df073
tweaks
timotheeguerin Feb 19, 2025
43b532c
tweaks
timotheeguerin Feb 19, 2025
1281a8b
s
timotheeguerin Feb 19, 2025
e5e405a
Update packages/compiler/src/init/init.ts
timotheeguerin Feb 20, 2025
8df9607
Update packages/compiler/src/init/init.ts
timotheeguerin Feb 20, 2025
10aa713
Update packages/compiler/src/init/init.ts
timotheeguerin Feb 20, 2025
9e28b0a
Create init-redesign-2025-1-20-20-5-0.md
timotheeguerin Feb 21, 2025
dc32739
Merge branch 'main' into init-redesign
timotheeguerin Feb 21, 2025
49f16d2
format
timotheeguerin Feb 21, 2025
ea1061a
Merge branch 'main' of https://github.com/Microsoft/typespec into ini…
timotheeguerin Feb 27, 2025
8f903b4
add warning for remote templates
timotheeguerin Feb 27, 2025
7e7bf08
fix
timotheeguerin Feb 27, 2025
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
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`
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: "OpenAPI3.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 will be emitting 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
4 changes: 1 addition & 3 deletions packages/compiler/src/core/cli/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,8 @@ import {
withCliHostAndDiagnostics,
} from "./utils.js";

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

async function main() {
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
Loading