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

Create Block: Adds --target-dir flag to allow the tool to target where to scaffold #53781

Merged
merged 12 commits into from
Oct 28, 2024
Merged
4 changes: 4 additions & 0 deletions packages/create-block/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## Unreleased

### Enhancement

- Add `--target-dir` flag to allow indicating where resulting files will be scaffolded ([#53781](https://github.com/WordPress/gutenberg/pull/53781))

## 4.53.0 (2024-10-16)

## 4.52.0 (2024-10-03)
Expand Down
31 changes: 15 additions & 16 deletions packages/create-block/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,8 @@ $ npm start

The `slug` provided (`todo-list` in the example) defines the folder name for the scaffolded plugin and the internal block name. The WordPress plugin generated must [be installed manually](https://wordpress.org/documentation/article/manage-plugins/#manual-plugin-installation-1).


_(requires `node` version `20.10.0` or above, and `npm` version `10.2.3` or above)_


> [Watch a video introduction to create-block on Learn.wordpress.org](https://learn.wordpress.org/tutorial/using-the-create-block-tool/)

## Usage
Expand All @@ -42,25 +40,26 @@ $ npx @wordpress/create-block@latest [options] [slug]

When no `slug` is provided, the script will run in interactive mode and will start prompting for the input required (`slug`, title, namespace...) to scaffold the project.


### `slug`

The use of `slug` is optional.

When provided it triggers the _quick mode_, where this `slug` is used:
- as the block slug (required for its identification)
- as the output location (folder name) for scaffolded files
- as the name of the WordPress plugin.

- as the block slug (required for its identification)
- as the output location (folder name) for scaffolded files
- as the name of the WordPress plugin.

The rest of the configuration is set to all default values unless overridden with some options listed below.

### `options`


```bash
-V, --version output the version number
-t, --template <name> project template type name; allowed values: "static" (default), "es5", the name of an external npm package, or the path to a local directory
--variant choose a block variant as defined by the template
--no-plugin scaffold block files only
--target-dir <directory> the directory where the files will be scaffolded, defaults to the slug
--namespace <value> internal namespace for the block name
--title <value> display title for the block and the WordPress plugin
--short-description <value> short description for the block and the WordPress plugin
Expand All @@ -69,7 +68,6 @@ The rest of the configuration is set to all default values unless overridden wit
--no-wp-scripts disable integration with `@wordpress/scripts` package
--wp-env enable integration with `@wordpress/env` package
-h, --help output usage information
--variant choose a block variant as defined by the template
```

#### `--template`
Expand All @@ -94,21 +92,14 @@ With this argument, `create-block` will generate a [dynamic block](https://devel
$ npx @wordpress/create-block@latest --variant dynamic
```

#### `--help`

With this argument, the `create-block` package outputs usage information.

```bash
$ npx @wordpress/create-block@latest --help
```

#### `--no-plugin`

With this argument, the `create-block` package runs in _No plugin mode_ which only scaffolds block files into the current directory.

```bash
$ npx @wordpress/create-block@latest --no-plugin
```

#### `--wp-env`

With this argument, the `create-block` package will add to the generated plugin the configuration and the script to run [`wp-env` package](https://developer.wordpress.org/block-editor/reference-guides/packages/packages-env/) within the plugin. This will allow you to easily set up a local WordPress environment (via Docker) for building and testing the generated plugin.
Expand All @@ -117,6 +108,14 @@ With this argument, the `create-block` package will add to the generated plugin
$ npx @wordpress/create-block@latest --wp-env
```

#### `--help`

With this argument, the `create-block` package outputs usage information.

```bash
$ npx @wordpress/create-block@latest --help
```

## Available commands in the scaffolded project

The plugin folder created when executing this command, is a node package with a modern build setup that requires no configuration.
Expand Down
10 changes: 8 additions & 2 deletions packages/create-block/lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,12 @@ program
'project template type name; allowed values: "standard", "es5", the name of an external npm package, or the path to a local directory',
'standard'
)
.option( '--variant <variant>', 'the variant of the template to use' )
.option( '--no-plugin', 'scaffold only block files' )
.option(
'--target-dir <directory>',
'the directory where the files will be scaffolded, defaults to the slug'
)
.option( '--namespace <value>', 'internal namespace for the block name' )
.option(
'--title <value>',
Expand All @@ -57,8 +63,6 @@ program
'disable integration with `@wordpress/scripts` package'
)
.option( '--wp-env', 'enable integration with `@wordpress/env` package' )
.option( '--no-plugin', 'scaffold only block files' )
.option( '--variant <variant>', 'the variant of the template to use' )
.action(
async (
slug,
Expand All @@ -72,6 +76,7 @@ program
wpScripts,
wpEnv,
variant,
targetDir,
}
) => {
await checkSystemRequirements( engines );
Expand Down Expand Up @@ -102,6 +107,7 @@ program
title,
wpScripts,
wpEnv,
targetDir,
} ).filter( ( [ , value ] ) => value !== undefined )
);

Expand Down
23 changes: 12 additions & 11 deletions packages/create-block/lib/init-block.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* External dependencies
*/
const { dirname, join } = require( 'path' );
const { join } = require( 'path' );
const makeDir = require( 'make-dir' );
const { writeFile } = require( 'fs' ).promises;

Expand Down Expand Up @@ -35,16 +35,18 @@ async function initBlockJSON( {
viewScript,
customBlockJSON,
example,
rootDirectory,
} ) {
info( '' );
info( 'Creating a "block.json" file.' );

const outputFile = plugin
? join( process.cwd(), slug, folderName, 'block.json' )
: join( process.cwd(), slug, 'block.json' );
await makeDir( dirname( outputFile ) );
const blockFolderName = plugin
? join( rootDirectory, folderName )
: rootDirectory;
await makeDir( blockFolderName );

await writeFile(
outputFile,
join( blockFolderName, 'block.json' ),
JSON.stringify(
Object.fromEntries(
Object.entries( {
Expand Down Expand Up @@ -79,13 +81,12 @@ async function initBlockJSON( {
module.exports = async function ( outputTemplates, view ) {
await Promise.all(
Object.keys( outputTemplates ).map( async ( outputFile ) => {
const pathName = view.plugin
? join( view.folderName, outputFile )
: join( process.cwd(), view.slug, outputFile );

await writeOutputTemplate(
outputTemplates[ outputFile ],
pathName,
join(
view.plugin ? view.folderName : '',
outputFile.replace( /\$slug/g, view.slug )
),
view
);
} )
Expand Down
10 changes: 4 additions & 6 deletions packages/create-block/lib/init-package-json.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
*/
const { command } = require( 'execa' );
const npmPackageArg = require( 'npm-package-arg' );
const { join } = require( 'path' );
const writePkg = require( 'write-pkg' );

/**
Expand All @@ -25,14 +24,13 @@ module.exports = async ( {
customScripts,
isDynamicVariant,
customPackageJSON,
rootDirectory,
} ) => {
const cwd = join( process.cwd(), slug );

info( '' );
info( 'Creating a "package.json" file.' );

await writePkg(
cwd,
rootDirectory,
Object.fromEntries(
Object.entries( {
name: slug,
Expand Down Expand Up @@ -92,7 +90,7 @@ module.exports = async ( {
info( '' );
info( `Installing "${ packageArg }".` );
await command( `npm install ${ packageArg }`, {
cwd,
cwd: rootDirectory,
} );
} catch ( { message } ) {
info( '' );
Expand All @@ -115,7 +113,7 @@ module.exports = async ( {
info( '' );
info( `Installing "${ packageArg }".` );
await command( `npm install ${ packageArg } --save-dev`, {
cwd,
cwd: rootDirectory,
} );
} catch ( { message } ) {
info( '' );
Expand Down
8 changes: 3 additions & 5 deletions packages/create-block/lib/init-wp-env.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,19 @@ const { writeFile } = require( 'fs' ).promises;
*/
const { info } = require( './log' );

module.exports = async ( { slug } ) => {
const cwd = join( process.cwd(), slug );

module.exports = async ( { rootDirectory } ) => {
info( '' );
info(
'Installing `@wordpress/env` package. It might take a couple of minutes...'
);
await command( 'npm install @wordpress/env --save-dev', {
cwd,
cwd: rootDirectory,
} );

info( '' );
info( 'Configuring `@wordpress/env`...' );
await writeFile(
join( cwd, '.wp-env.json' ),
join( rootDirectory, '.wp-env.json' ),
JSON.stringify(
{
core: 'WordPress/WordPress',
Expand Down
11 changes: 4 additions & 7 deletions packages/create-block/lib/init-wp-scripts.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,33 +2,30 @@
* External dependencies
*/
const { command } = require( 'execa' );
const { join } = require( 'path' );

/**
* Internal dependencies
*/
const { info } = require( './log' );

module.exports = async ( { slug } ) => {
const cwd = join( process.cwd(), slug );

module.exports = async ( { rootDirectory } ) => {
info( '' );
info(
'Installing `@wordpress/scripts` package. It might take a couple of minutes...'
);
await command( 'npm install @wordpress/scripts --save-dev', {
cwd,
cwd: rootDirectory,
} );

info( '' );
info( 'Formatting JavaScript files.' );
await command( 'npm run format', {
cwd,
cwd: rootDirectory,
} );

info( '' );
info( 'Compiling block.' );
await command( 'npm run build', {
cwd,
cwd: rootDirectory,
} );
};
8 changes: 3 additions & 5 deletions packages/create-block/lib/output.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,17 @@ const { render } = require( 'mustache' );
const { writeFile } = require( 'fs' ).promises;

const writeOutputAsset = async ( inputFile, outputFile, view ) => {
const outputFilePath = join( view.slug, 'assets', outputFile );
const outputFilePath = join( view.rootDirectory, 'assets', outputFile );
await makeDir( dirname( outputFilePath ) );
writeFile( outputFilePath, inputFile );
};

const writeOutputTemplate = async ( inputFile, outputFile, view ) => {
const outputFilePath = view.plugin
? join( view.slug, outputFile.replace( /\$slug/g, view.slug ) )
: outputFile;
await makeDir( dirname( outputFilePath ) );
// If the rendered template is empty, don't write it. This is how we can conditionally add template files.
const renderedFile = render( inputFile, view );
if ( renderedFile.trim().length ) {
const outputFilePath = join( view.rootDirectory, outputFile );
await makeDir( dirname( outputFilePath ) );
writeFile( outputFilePath, renderedFile );
}
};
Expand Down
14 changes: 7 additions & 7 deletions packages/create-block/lib/scaffold.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
* External dependencies
*/
const { pascalCase, snakeCase } = require( 'change-case' );
const { join } = require( 'path' );

/**
* Internal dependencies
Expand Down Expand Up @@ -40,6 +41,7 @@ module.exports = async (
npmDevDependencies,
customScripts,
folderName,
targetDir,
editorScript,
editorStyle,
style,
Expand All @@ -56,7 +58,7 @@ module.exports = async (
) => {
slug = slug.toLowerCase();
namespace = namespace.toLowerCase();

const rootDirectory = join( process.cwd(), targetDir || slug );
const transformedValues = transformer( {
$schema,
apiVersion,
Expand Down Expand Up @@ -94,6 +96,7 @@ module.exports = async (
customBlockJSON,
example,
textdomain: slug,
rootDirectory,
} );

const view = {
Expand All @@ -117,11 +120,10 @@ module.exports = async (
return;
}

const projectType = plugin ? 'plugin' : 'block';
info( '' );
info(
plugin
? `Creating a new WordPress plugin in the ${ view.slug } directory.`
: `Creating a new block in the ${ view.slug } directory.`
`Creating a new WordPress ${ projectType } in the ${ rootDirectory } directory.`
);

if ( plugin ) {
Expand Down Expand Up @@ -164,9 +166,7 @@ module.exports = async (
info( '' );

success(
plugin
? `Done: WordPress plugin ${ title } bootstrapped in the ${ slug } directory.`
: `Done: Block "${ title }" bootstrapped in the ${ slug } directory.`
`Done: WordPress ${ projectType } ${ title } bootstrapped in the ${ rootDirectory } directory.`
);

if ( plugin && wpScripts ) {
Expand Down
Loading