-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
36 changed files
with
2,265 additions
and
61 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes.
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
# `@turbo/gen` | ||
|
||
> This package is currently in **beta**. Please report any issues you encounter, and give us feedback about your experience using it! | ||
Easily extend your Turborepo with new apps, and packages. Create new empty workspaces, copy existing workspaces, add workspaces from remote sources (just like `create-turbo`!) or run custom generators defined using [Plop](https://plopjs.com/) configurations. | ||
|
||
## Usage | ||
|
||
```bash | ||
Usage: @turbo/gen [options] [command] | ||
|
||
Extend your Turborepo | ||
|
||
Options: | ||
-v, --version Output the current version | ||
-h, --help Display help for command | ||
|
||
Commands: | ||
add|a [options] Add a new package or app to your project | ||
generate|g [options] [generator-name] Run custom generators | ||
help [command] display help for command | ||
``` | ||
|
||
## Add | ||
|
||
Extend your Turborepo with new apps or packages. Create new empty workspaces, copy existing workspaces, or add workspaces from remote sources (just like `create-turbo`!). | ||
|
||
### Usage | ||
|
||
#### Blank Workspace | ||
|
||
```bash | ||
@turbo/gen add | ||
``` | ||
|
||
#### Copy a Local Workspace | ||
|
||
```bash | ||
@turbo/gen add --copy | ||
``` | ||
|
||
#### Copy a Remote Workspace | ||
|
||
```bash | ||
@turbo/gen add -e <git-url> | ||
``` | ||
|
||
## Generate | ||
|
||
Extend your Turborepo with custom generators defined using [Plop](https://plopjs.com/) configurations. | ||
|
||
### Usage | ||
|
||
```bash | ||
@turbo/gen generate [generator-name] | ||
``` | ||
|
||
### Writing Generators | ||
|
||
`@turbo/gen` will search the root of your monorepo, and every workspace for generators defined at: | ||
|
||
```bash | ||
turbo/generators/config.js | ||
``` | ||
|
||
**NOTE**: By default, generators are run from the _root_ of the _workspace_ where they are defined. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import path from "path"; | ||
import { PackageManager } from "@turbo/workspaces"; | ||
|
||
export function getWorkspaceDetailsMockReturnValue({ | ||
root, | ||
packageManager = "npm", | ||
}: { | ||
root: string; | ||
packageManager: PackageManager; | ||
}) { | ||
return { | ||
name: "mock-project", | ||
packageManager, | ||
paths: { | ||
root, | ||
packageJson: path.join(root, "package.json"), | ||
lockfile: path.join(root, "yarn.lock"), | ||
nodeModules: path.join(root, "node_modules"), | ||
}, | ||
workspaceData: { | ||
globs: ["packages/*"], | ||
workspaces: [ | ||
{ | ||
name: "packages/mock-package", | ||
paths: { | ||
root: path.join(root, "packages/mock-package"), | ||
packageJson: path.join(root, "packages/mock-package/package.json"), | ||
nodeModules: path.join(root, "packages/mock-package/node_modules"), | ||
}, | ||
}, | ||
], | ||
}, | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
/** @type {import('ts-jest/dist/types').InitialOptionsTsJest} */ | ||
module.exports = { | ||
preset: "ts-jest/presets/js-with-ts", | ||
testEnvironment: "node", | ||
testPathIgnorePatterns: ["/__fixtures__/", "/__tests__/test-utils.ts"], | ||
coveragePathIgnorePatterns: ["/__fixtures__/", "/__tests__/test-utils.ts"], | ||
transformIgnorePatterns: ["/node_modules/(?!(ansi-regex)/)"], | ||
modulePathIgnorePatterns: ["<rootDir>/node_modules", "<rootDir>/dist"], | ||
collectCoverage: true, | ||
verbose: true, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
{ | ||
"name": "@turbo/gen", | ||
"version": "0.0.1-alpha.5", | ||
"description": "Extend a Turborepo", | ||
"homepage": "https://turbo.build/repo", | ||
"license": "MPL-2.0", | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/vercel/turbo", | ||
"directory": "packages/turbo-gen" | ||
}, | ||
"bugs": { | ||
"url": "https://github.com/vercel/turbo/issues" | ||
}, | ||
"bin": "dist/cli.js", | ||
"scripts": { | ||
"build": "tsup", | ||
"test": "jest", | ||
"lint": "eslint src/**/*.ts", | ||
"check-types": "tsc --noEmit" | ||
}, | ||
"dependencies": { | ||
"chalk": "2.4.2", | ||
"commander": "^10.0.0", | ||
"fs-extra": "^10.1.0", | ||
"inquirer": "^8.2.4", | ||
"minimatch": "^9.0.0", | ||
"node-plop": "^0.26.3", | ||
"semver": "^7.3.8", | ||
"update-check": "^1.5.4", | ||
"validate-npm-package-name": "^5.0.0" | ||
}, | ||
"devDependencies": { | ||
"@turbo/test-utils": "workspace:*", | ||
"@turbo/tsconfig": "workspace:*", | ||
"@turbo/utils": "workspace:*", | ||
"@turbo/workspaces": "workspace:*", | ||
"@types/fs-extra": "^9.0.13", | ||
"@types/inquirer": "^8.2.5", | ||
"@types/jest": "^27.4.0", | ||
"@types/node": "^16.11.12", | ||
"@types/semver": "^7.3.9", | ||
"@types/validate-npm-package-name": "^4.0.0", | ||
"eslint": "^7.23.0", | ||
"jest": "^27.4.3", | ||
"ts-jest": "^27.1.1", | ||
"tsup": "^6.7.0", | ||
"typescript": "^4.5.5" | ||
}, | ||
"files": [ | ||
"dist" | ||
], | ||
"publishConfig": { | ||
"access": "public" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
#!/usr/bin/env node | ||
|
||
import chalk from "chalk"; | ||
import { Argument, Command, Option } from "commander"; | ||
import notifyUpdate from "./utils/notifyUpdate"; | ||
import { logger } from "@turbo/utils"; | ||
|
||
import { add, generate, raw } from "./commands"; | ||
import cliPkg from "../package.json"; | ||
|
||
const turboGenCli = new Command(); | ||
|
||
turboGenCli | ||
.name(chalk.bold(logger.turboGradient("@turbo/gen"))) | ||
.description("Extend your Turborepo") | ||
.version(cliPkg.version, "-v, --version", "Output the current version") | ||
.helpOption("-h, --help", "Display help for command") | ||
.showHelpAfterError(false); | ||
|
||
turboGenCli | ||
.command("raw", { hidden: true }) | ||
.argument("<type>", "The type of generator to run") | ||
.addOption(new Option("--json <arguments>", "Arguments as raw JSON")) | ||
.action(raw); | ||
|
||
turboGenCli | ||
.command("add") | ||
.aliases(["a"]) | ||
.description("Add a new package or app to your project") | ||
.addOption( | ||
new Option("-n, --name <workspace-name>", "Name for the new workspace") | ||
) | ||
.addOption( | ||
new Option("-b, --empty", "Generate an empty workspace") | ||
.conflicts("copy") | ||
.default(true) | ||
) | ||
.addOption( | ||
new Option( | ||
"-c, --copy", | ||
"Generate a workspace using an existing workspace as a template" | ||
).conflicts("empty") | ||
) | ||
.addOption( | ||
new Option( | ||
"-d, --destination <dir>", | ||
"Where the new workspace should be created" | ||
) | ||
) | ||
.addOption( | ||
new Option("-w, --what <type>", "The type of workspace to create").choices([ | ||
"app", | ||
"package", | ||
]) | ||
) | ||
.addOption( | ||
new Option( | ||
"-r, --root <dir>", | ||
"The root of your repository (default: directory with root turbo.json)" | ||
) | ||
) | ||
.addOption( | ||
new Option( | ||
"-e, --example [github-url]", | ||
`An example package to add. You can use a GitHub URL with any branch and/or subdirectory.` | ||
).implies({ copy: true }) | ||
) | ||
.addOption( | ||
new Option( | ||
"-p, --example-path <path-to-example>", | ||
`In a rare case, your GitHub URL might contain a branch name with | ||
a slash (e.g. bug/fix-1) and the path to the example (e.g. foo/bar). | ||
In this case, you must specify the path to the example separately: | ||
--example-path foo/bar | ||
` | ||
).implies({ copy: true }) | ||
) | ||
.addOption( | ||
new Option( | ||
"--show-all-dependencies", | ||
"Do not filter available dependencies by the workspace type" | ||
).default(false) | ||
) | ||
.action(add); | ||
|
||
turboGenCli | ||
.command("generate") | ||
.aliases(["g", "gen"]) | ||
.description("Run custom generators") | ||
.addArgument( | ||
new Argument("[generator-name]", "The name of the generator to run") | ||
) | ||
.addOption( | ||
new Option( | ||
"-c, --config <config>", | ||
"Generator configuration file (default: turbo/generators/config.js" | ||
) | ||
) | ||
.addOption( | ||
new Option( | ||
"-r, --root <dir>", | ||
"The root of your repository (default: directory with root turbo.json)" | ||
) | ||
) | ||
.addOption( | ||
new Option( | ||
"-a, --args <args...>", | ||
"Arguments passed directly to generator" | ||
).default([]) | ||
) | ||
.action(generate); | ||
|
||
turboGenCli | ||
.parseAsync() | ||
.then(notifyUpdate) | ||
.catch(async (reason) => { | ||
console.log(); | ||
if (reason.command) { | ||
logger.error(`${chalk.bold(reason.command)} has failed.`); | ||
} else { | ||
logger.error("Unexpected error. Please report it as a bug:"); | ||
console.log(reason); | ||
} | ||
console.log(); | ||
await notifyUpdate(); | ||
process.exit(1); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import { logger } from "@turbo/utils"; | ||
import { getProject } from "../../utils/getProject"; | ||
import { copy, empty } from "../../generators"; | ||
import { WorkspaceType } from "../../generators/types"; | ||
|
||
export interface TurboGeneratorOptions { | ||
name?: string; | ||
// default to true | ||
empty: boolean; | ||
copy?: boolean; | ||
destination?: string; | ||
what?: WorkspaceType; | ||
root?: string; | ||
example?: string; | ||
examplePath?: string; | ||
// defaults to false | ||
showAllDependencies: boolean; | ||
} | ||
|
||
export async function add(opts: TurboGeneratorOptions) { | ||
const project = await getProject(opts); | ||
|
||
console.log(); | ||
const args = { project, opts }; | ||
if (opts.copy) { | ||
if (opts.example) { | ||
logger.info(`Copy a remote workspace from ${opts.example}`); | ||
} else { | ||
logger.info(`Copy an existing workspace from ${project.name}`); | ||
} | ||
console.log(); | ||
await copy(args); | ||
} else { | ||
logger.info(`Add an empty workspace to ${project.name}`); | ||
console.log(); | ||
await empty(args); | ||
} | ||
} |
Oops, something went wrong.