Skip to content

Commit

Permalink
Create Block: Adds --target-dir flag to allow the tool to target wh…
Browse files Browse the repository at this point in the history
…ere to scaffold (#53781)

* Add --targetDir flag to allow targeting a directory where to scaffold the plugin/files.

* Not using the targetDir when in --no-plugin mode

* Change the name of the flag to match others and update changelog.

* WIP commit.

* Add logic to generate the paths for the root and block files in one place.

* Add a new parameter to allow passing the path once rather than generating it in the function.

* Modify the other functions to use the generated paths.

* Update the command description.

* Update packages/create-block/CHANGELOG.md

* Refactor the handling for the root directory

* Improve the documentation for target dir

* Reorder CLI options in the docs

---------

Co-authored-by: Greg Ziółkowski <[email protected]>
Unlinked contributors: afmarchetti.

Co-authored-by: ryanwelcher <[email protected]>
Co-authored-by: gziolo <[email protected]>
Co-authored-by: bacoords <[email protected]>
Co-authored-by: colorful-tones <[email protected]>
Co-authored-by: brettsmason <[email protected]>
Co-authored-by: iamleese <[email protected]>
Co-authored-by: carolinan <[email protected]>
  • Loading branch information
8 people authored Oct 28, 2024
1 parent 76e4dc7 commit d36959d
Show file tree
Hide file tree
Showing 9 changed files with 60 additions and 59 deletions.
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

0 comments on commit d36959d

Please sign in to comment.