From 3d45a3b5cd1664984b879c3a76224ca735f8527f Mon Sep 17 00:00:00 2001 From: Grzegorz Ziolkowski Date: Mon, 3 Jan 2022 11:38:09 +0100 Subject: [PATCH] Scripts: Add `plugin-zip` command to create a zip file for a WordPress plugin --- bin/test-create-block.sh | 3 + package-lock.json | 95 ++++++++++++++++--- packages/create-block/CHANGELOG.md | 4 + .../create-block/lib/init-package-json.js | 3 +- .../lib/templates/esnext/.gitignore.mustache | 5 +- packages/scripts/CHANGELOG.md | 1 + packages/scripts/README.md | 29 ++++++ packages/scripts/package.json | 2 + packages/scripts/scripts/plugin-zip.js | 56 +++++++++++ 9 files changed, 184 insertions(+), 14 deletions(-) create mode 100644 packages/scripts/scripts/plugin-zip.js diff --git a/bin/test-create-block.sh b/bin/test-create-block.sh index b6e22fdb42031..07ca263f041d1 100755 --- a/bin/test-create-block.sh +++ b/bin/test-create-block.sh @@ -36,3 +36,6 @@ status "Lintig CSS files..." status "Linting JavaScript files..." ../node_modules/.bin/wp-scripts lint-js + +status "Creating a plugin zip file..." +../node_modules/.bin/wp-scripts plugin-zip diff --git a/package-lock.json b/package-lock.json index 7a68a9f93f063..2f3cc808e5d45 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2545,6 +2545,15 @@ "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", "dev": true }, + "ignore-walk": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.4.tgz", + "integrity": "sha512-PY6Ii8o1jMRA1z4F2hRkH/xN59ox43DavKvD3oDpfurRlOJyAHpifIwpbdv1n4jt4ov0jSpw3kQ4GhJnpBL6WQ==", + "dev": true, + "requires": { + "minimatch": "^3.0.4" + } + }, "lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", @@ -2596,6 +2605,17 @@ "validate-npm-package-name": "^3.0.0" } }, + "npm-packlist": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.4.8.tgz", + "integrity": "sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A==", + "dev": true, + "requires": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1", + "npm-normalize-package-bin": "^1.0.1" + } + }, "path-parse": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", @@ -5750,6 +5770,28 @@ "npmlog": "^4.1.2", "tar": "^4.4.10", "temp-write": "^3.4.0" + }, + "dependencies": { + "ignore-walk": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.4.tgz", + "integrity": "sha512-PY6Ii8o1jMRA1z4F2hRkH/xN59ox43DavKvD3oDpfurRlOJyAHpifIwpbdv1n4jt4ov0jSpw3kQ4GhJnpBL6WQ==", + "dev": true, + "requires": { + "minimatch": "^3.0.4" + } + }, + "npm-packlist": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.4.8.tgz", + "integrity": "sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A==", + "dev": true, + "requires": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1", + "npm-normalize-package-bin": "^1.0.1" + } + } } }, "@lerna/package": { @@ -16568,6 +16610,7 @@ "@wordpress/postcss-plugins-preset": "file:packages/postcss-plugins-preset", "@wordpress/prettier-config": "file:packages/prettier-config", "@wordpress/stylelint-config": "file:packages/stylelint-config", + "adm-zip": "^0.5.9", "babel-jest": "^26.6.3", "babel-loader": "^8.2.3", "browserslist": "^4.17.6", @@ -16594,6 +16637,7 @@ "mini-css-extract-plugin": "^2.1.0", "minimist": "^1.2.0", "npm-package-json-lint": "^5.0.0", + "npm-packlist": "^3.0.0", "postcss": "^8.2.15", "postcss-loader": "^6.1.1", "prettier": "npm:wp-prettier@2.2.1-beta-1", @@ -16835,6 +16879,12 @@ "integrity": "sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA==", "dev": true }, + "adm-zip": { + "version": "0.5.9", + "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.9.tgz", + "integrity": "sha512-s+3fXLkeeLjZ2kLjCBwQufpI5fuN+kIGBxu6530nVQZGVol0d7Y/M88/xw9HGGUcJjKf8LutN3VPRUBq6N7Ajg==", + "dev": true + }, "agent-base": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", @@ -36192,9 +36242,9 @@ "dev": true }, "ignore-walk": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.1.tgz", - "integrity": "sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-4.0.1.tgz", + "integrity": "sha512-rzDQLaW4jQbh2YrOFlJdCtX8qgJTehFRYiUB2r1osqTeDzV/3+Jh8fz1oAPzUThf3iku8Ds4IDqawI5d8mUiQw==", "dev": true, "requires": { "minimatch": "^3.0.4" @@ -46233,10 +46283,13 @@ "dev": true }, "npm-bundled": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.0.6.tgz", - "integrity": "sha512-8/JCaftHwbd//k6y2rEWp6k1wxVfpFzB6t1p825+cUb7Ym2XQfhwIC5KwhrvzZRJu+LtDE585zVaS32+CGtf0g==", - "dev": true + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.1.2.tgz", + "integrity": "sha512-x5DHup0SuyQcmL3s7Rx/YQ8sbw/Hzg0rj48eN0dV7hf5cmQq5PXIeioroH3raV1QC1yh3uTYuMThvEQF3iKgGQ==", + "dev": true, + "requires": { + "npm-normalize-package-bin": "^1.0.1" + } }, "npm-lifecycle": { "version": "3.1.5", @@ -46657,13 +46710,31 @@ } }, "npm-packlist": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.4.4.tgz", - "integrity": "sha512-zTLo8UcVYtDU3gdeaFu2Xu0n0EvelfHDGuqtNIn5RO7yQj4H1TqNdBc/yZjxnWA0PVB8D3Woyp0i5B43JwQ6Vw==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-3.0.0.tgz", + "integrity": "sha512-L/cbzmutAwII5glUcf2DBRNY/d0TFd4e/FnaZigJV6JD85RHZXJFGwCndjMWiiViiWSsWt3tiOLpI3ByTnIdFQ==", "dev": true, "requires": { - "ignore-walk": "^3.0.1", - "npm-bundled": "^1.0.1" + "glob": "^7.1.6", + "ignore-walk": "^4.0.1", + "npm-bundled": "^1.1.1", + "npm-normalize-package-bin": "^1.0.1" + }, + "dependencies": { + "glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + } } }, "npm-pick-manifest": { diff --git a/packages/create-block/CHANGELOG.md b/packages/create-block/CHANGELOG.md index 7b91ea47086da..e29da97599dd0 100644 --- a/packages/create-block/CHANGELOG.md +++ b/packages/create-block/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +### New Features + +- Integrated a new `plugin-zip` command to create a zip file for a WordPress plugin ([#37687](https://github.com/WordPress/gutenberg/pull/37687)). + ### Enhancement - Speed up scaffolding process by omitting WordPress dependencies in the template ([#37639](https://github.com/WordPress/gutenberg/pull/37639)). diff --git a/packages/create-block/lib/init-package-json.js b/packages/create-block/lib/init-package-json.js index 98e7d0d680d87..7ebdf6a96d63e 100644 --- a/packages/create-block/lib/init-package-json.js +++ b/packages/create-block/lib/init-package-json.js @@ -40,8 +40,9 @@ module.exports = async ( { format: 'wp-scripts format', 'lint:css': 'wp-scripts lint-style', 'lint:js': 'wp-scripts lint-js', - start: 'wp-scripts start', 'packages-update': 'wp-scripts packages-update', + 'plugin-zip': 'wp-scripts plugin-zip', + start: 'wp-scripts start', }, }, isEmpty diff --git a/packages/create-block/lib/templates/esnext/.gitignore.mustache b/packages/create-block/lib/templates/esnext/.gitignore.mustache index 7e8c9eac7c441..f66335eb0c504 100644 --- a/packages/create-block/lib/templates/esnext/.gitignore.mustache +++ b/packages/create-block/lib/templates/esnext/.gitignore.mustache @@ -20,8 +20,11 @@ node_modules/ # Optional eslint cache .eslintcache -# Output of 'npm pack' +# Output of `npm pack` *.tgz +# Output of `wp-scripts plugin-zip` +*.zip + # dotenv environment variables file .env diff --git a/packages/scripts/CHANGELOG.md b/packages/scripts/CHANGELOG.md index c1b97def8299a..0b2bd20d740cd 100644 --- a/packages/scripts/CHANGELOG.md +++ b/packages/scripts/CHANGELOG.md @@ -11,6 +11,7 @@ ### New Features +- Added a new `plugin-zip` command to create a zip file for a WordPress plugin ([#37687](https://github.com/WordPress/gutenberg/pull/37687)). - Added optional support for React Fast Refresh in the `start` command. It can be activated with `--hot` CLI argument ([#28273](https://github.com/WordPress/gutenberg/pull/28273)). ### Bug Fixes diff --git a/packages/scripts/README.md b/packages/scripts/README.md index 137b1de54b79c..a361f3ff0f02c 100644 --- a/packages/scripts/README.md +++ b/packages/scripts/README.md @@ -37,6 +37,7 @@ _Example:_ "lint:md:js": "wp-scripts lint-md-js", "lint:pkg-json": "wp-scripts lint-pkg-json", "packages-update": "wp-scripts packages-update", + "plugin-zip": "wp-scripts plugin-zip", "start": "wp-scripts start", "test:e2e": "wp-scripts test-e2e", "test:unit": "wp-scripts test-unit-js" @@ -303,6 +304,34 @@ _Example:_ The command checks which packages whose name starts with `@wordpress/` are used in the project by reading the package.json file, and then executes `npm install @wordpress/package1@latest @wordpress/package2@latest ... --save` to change the package versions to the latest one. +### `packages-update` + +Creates a zip file for a WordPress plugin. + +_Example:_ + +```json +{ + "scripts": { + "plugin-zip": "wp-scripts plugin-zip" + } +} +``` + +By default, it uses [Plugin Handbook best practices](https://developer.wordpress.org/plugins/plugin-basics/best-practices/#file-organization) to discover files. + +#### Advanced information + +In the case where the plugin author wants to customize the files included in the zip file, they can provide the `files` field in the `package.json` file as documented in the [`npm-packlist`](https://www.npmjs.com/package/npm-packlist) package, example: + +```json +{ + "files": [ "dir" ] +} +``` + +It reuses the same logic as `npm pack` command to create an npm package tarball. + ### `start` Transforms your code according the configuration provided so it’s ready for development. The script will automatically rebuild if you make changes to the code, and you will see the build errors in the console. The entry point for your project’s code should be located in `src/index.js` (other supported extensions: `.jsx`, `.ts`, and `.tsx`). The output generated will be written to `build/index.js`. For single builds, better suited for production, see the [build](#build) script. diff --git a/packages/scripts/package.json b/packages/scripts/package.json index 35dae5d7d3dce..66620264aee79 100644 --- a/packages/scripts/package.json +++ b/packages/scripts/package.json @@ -44,6 +44,7 @@ "@wordpress/postcss-plugins-preset": "file:../postcss-plugins-preset", "@wordpress/prettier-config": "file:../prettier-config", "@wordpress/stylelint-config": "file:../stylelint-config", + "adm-zip": "^0.5.9", "babel-jest": "^26.6.3", "babel-loader": "^8.2.3", "browserslist": "^4.17.6", @@ -70,6 +71,7 @@ "mini-css-extract-plugin": "^2.1.0", "minimist": "^1.2.0", "npm-package-json-lint": "^5.0.0", + "npm-packlist": "^3.0.0", "postcss": "^8.2.15", "postcss-loader": "^6.1.1", "prettier": "npm:wp-prettier@2.2.1-beta-1", diff --git a/packages/scripts/scripts/plugin-zip.js b/packages/scripts/scripts/plugin-zip.js new file mode 100644 index 0000000000000..4bc66e50fa56c --- /dev/null +++ b/packages/scripts/scripts/plugin-zip.js @@ -0,0 +1,56 @@ +/** + * External dependencies + */ +const AdmZip = require( 'adm-zip' ); +const { sync: glob } = require( 'fast-glob' ); +const { sync: packlist } = require( 'npm-packlist' ); +const { dirname } = require( 'path' ); +const { stdout } = require( 'process' ); + +/** + * Internal dependencies + */ +const { hasPackageProp, getPackageProp } = require( '../utils' ); + +const name = getPackageProp( 'name' ); +stdout.write( `Creating archive for \`${ name }\` plugin... 🎁\n\n` ); +const zip = new AdmZip(); + +let files = []; +if ( hasPackageProp( 'files' ) ) { + stdout.write( + 'Using the `files` field from `package.json` to detect files:\n\n' + ); + files = packlist(); +} else { + stdout.write( + 'Using Plugin Handbook best practices to discover files:\n\n' + ); + // See https://developer.wordpress.org/plugins/plugin-basics/best-practices/#file-organization. + files = glob( + [ + 'admin/**', + 'build/**', + 'includes/**', + 'languages/**', + 'public/**', + `${ name }.php`, + 'uninstall.php', + 'block.json', + 'changelog.*', + 'license.*', + 'readme.*', + ], + { + caseSensitiveMatch: false, + } + ); +} + +files.forEach( ( file ) => { + stdout.write( ` Adding \`${ file }\`.\n` ); + zip.addLocalFile( file, dirname( file ) ); +} ); + +zip.writeZip( `./${ name }.zip` ); +stdout.write( `\nDone. \`${ name }.zip\` is ready! 🎉\n` );