-
-
Notifications
You must be signed in to change notification settings - Fork 70
feat: Select ecosystem packages in CLI #2556
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
Changes from all commits
4d75e5e
8a02ff8
f0df00b
d083c77
edb62b8
33260bc
5ee50e2
3abc4e8
6125e5d
4d8ccf5
8cf64b4
7c8ab91
d93fdfa
9bbb422
8b994d4
c330cc1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,17 +1,26 @@ | ||
| import type { Agent } from 'package-manager-detector'; | ||
| import * as p from '@clack/prompts'; | ||
|
|
||
| import { hasDependency } from '../utils/pkg.ts'; | ||
| import type { PackageJsonWithDeps } from '../utils/types.ts'; | ||
| import { appendVersion, hasDependency } from '../utils/pkg.ts'; | ||
| import type { PackageJson } from '../utils/types.ts'; | ||
| import { pmAdd } from '../utils/pm.ts'; | ||
| import { confirmStep } from '../utils/prompts.ts'; | ||
| import { multiselectPkgs } from '../utils/inputs.ts'; | ||
|
|
||
| export async function ensureTypegpu(pm: Agent, pkg: PackageJsonWithDeps) { | ||
| export async function ensureTypegpu(pm: Agent, pkg: PackageJson): Promise<boolean> { | ||
| if (hasDependency(pkg, 'typegpu')) { | ||
| p.log.info('typegpu is already installed.'); | ||
| return; | ||
| return true; | ||
| } | ||
| if (!(await confirmStep('Install typegpu?'))) return; | ||
| if (!(await confirmStep('Install typegpu?'))) return false; | ||
| pmAdd(pm, ['typegpu'], false); | ||
| // no p.log.success because pmAdd already logs it | ||
| return true; | ||
| } | ||
|
|
||
| export async function askForPkgs(pm: Agent, pkg: PackageJson) { | ||
| const pkgs = (await multiselectPkgs(pkg))?.map(({ pkg, ver }) => appendVersion(pkg, ver)); | ||
| if (pkgs) { | ||
| pmAdd(pm, pkgs, false); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,8 +3,9 @@ import path from 'node:path'; | |
| import * as p from '@clack/prompts'; | ||
|
|
||
| import { cancelExit, failAndExit } from './prompts.ts'; | ||
| import { PackageJsonWithNameSchema } from './types.ts'; | ||
| import { type } from 'arktype'; | ||
| import { PackageJsonSchema } from './types.ts'; | ||
| import { multiselectPkgs } from './inputs.ts'; | ||
|
|
||
| const renameFiles = { | ||
| _gitignore: '.gitignore', | ||
|
|
@@ -49,7 +50,11 @@ export async function prepareDirectory(cwd: string, projectDir: string) { | |
| return dir; | ||
| } | ||
|
|
||
| export function copyTemplate(templateDir: string, projectDir: string, packageName: string) { | ||
| export async function scaffoldProject( | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I dislike how this function became async, but we cannot ask for packages to add before reading the JSON (otherwise, we might suggest packages already present in the preset) |
||
| templateDir: string, | ||
| projectDir: string, | ||
| packageName: string, | ||
| ) { | ||
| const entries = fs.readdirSync(templateDir); | ||
| for (const entry of entries.filter((f) => f !== '_package.json' && f !== 'index.html')) { | ||
| const src = path.join(templateDir, entry); | ||
|
|
@@ -65,10 +70,18 @@ export function copyTemplate(templateDir: string, projectDir: string, packageNam | |
|
|
||
| const srcPackage = path.join(templateDir, '_package.json'); | ||
| const destPackage = path.join(projectDir, 'package.json'); | ||
| const pkg = PackageJsonWithNameSchema(JSON.parse(fs.readFileSync(srcPackage, 'utf-8'))); | ||
| const pkg = PackageJsonSchema(JSON.parse(fs.readFileSync(srcPackage, 'utf-8'))); | ||
| if (pkg instanceof type.errors) { | ||
| failAndExit(`[INTERNAL] Invalid package.json in template ${templateDir}`, pkg.summary); | ||
| } | ||
| pkg.name = packageName; | ||
| const pkgs = await multiselectPkgs(pkg); | ||
| if (pkgs) { | ||
| pkg.dependencies ??= {}; | ||
| for (const { pkg: dep, ver } of pkgs) { | ||
| pkg.dependencies[dep] = ver; | ||
| } | ||
| } | ||
|
|
||
| fs.writeFileSync(destPackage, JSON.stringify(pkg, null, 2) + '\n' /* to make oxfmt happy */); | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,8 +1,29 @@ | ||
| import type { PackageJsonWithDeps } from './types.ts'; | ||
| import type { PackageJson } from './types.ts'; | ||
|
|
||
| export function hasDependency(pkg: PackageJsonWithDeps, name: string) { | ||
| export function hasDependency(pkg: PackageJson, name: string) { | ||
| const deps = pkg.dependencies ?? {}; | ||
| const devDeps = pkg.devDependencies ?? {}; | ||
| const peerDeps = pkg.peerDependencies ?? {}; | ||
| return name in deps || name in devDeps || name in peerDeps; | ||
| } | ||
|
|
||
| export const VERSION = '^0.11.0'; | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hardcoded. If we wish, we can create a map from package to version in future. |
||
|
|
||
| export const typegpuPkgs = [ | ||
| { value: '@typegpu/color', hint: 'helpers for converting color spaces' }, | ||
| // { value: '@typegpu/geometry', hint: 'helpers for drawing points and lines' }, | ||
| // { value: '@typegpu/gl', hint: 'WebGL utilities for TypeGPU integration' }, | ||
| { | ||
| value: '@typegpu/noise', | ||
| hint: 'helpers for Perlin noise and general purpose random number generation.', | ||
| }, | ||
| { value: '@typegpu/radiance-cascades', hint: 'implementation of Radiance Cascades algorithm' }, | ||
| { value: '@typegpu/react', hint: 'React hooks for TypeGPU integration' }, | ||
| { value: '@typegpu/sdf', hint: 'helpers for creating Signed Distance Fields' }, | ||
| // { value: '@typegpu/sort', hint: 'implementations of scanning and sorting algorithms' }, | ||
| { value: '@typegpu/three', hint: 'Three.js utilities for TypeGPU integration' }, | ||
| ] as const satisfies { value: string; hint: string }[]; | ||
|
|
||
| export function appendVersion(pkg: string, version: string) { | ||
| return `${pkg}@${version}`; | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,16 +1,12 @@ | ||
| import { type } from 'arktype'; | ||
|
|
||
| export const PackageJsonWithDepsSchema = type({ | ||
| export const PackageJsonSchema = type({ | ||
| name: 'string', | ||
| 'dependencies?': 'Record<string, string>', | ||
| 'devDependencies?': 'Record<string, string>', | ||
| 'peerDependencies?': 'Record<string, string>', | ||
| }); | ||
|
Comment on lines
+3
to
8
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. do we care? |
||
| export type PackageJsonWithDeps = typeof PackageJsonWithDepsSchema.infer; | ||
|
|
||
| export const PackageJsonWithNameSchema = type({ | ||
| name: 'string', | ||
| }); | ||
| export type PackageJsonWithName = typeof PackageJsonWithNameSchema.infer; | ||
| export type PackageJson = typeof PackageJsonSchema.infer; | ||
|
|
||
| export const TsConfigSchema = type({ | ||
| 'compilerOptions?': { | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.