From 171f9c52ee8c587829c9a0c3a4d9c4eaa084254d Mon Sep 17 00:00:00 2001 From: James Nylen Date: Mon, 5 Jun 2017 13:08:57 -0400 Subject: [PATCH] Do not download vendor JS files in released plugin versions --- bin/build-plugin-zip.sh | 74 ++++++++++++++++++++++--- bin/generate-gutenberg-php.php | 62 +++++++++++++++++++++ bin/get-vendor-scripts.php | 24 +++++++++ gutenberg.php | 4 ++ lib/client-assets.php | 98 +++++++++++++++++++++------------- phpcs.xml | 6 +++ 6 files changed, 222 insertions(+), 46 deletions(-) create mode 100755 bin/generate-gutenberg-php.php create mode 100755 bin/get-vendor-scripts.php diff --git a/bin/build-plugin-zip.sh b/bin/build-plugin-zip.sh index 0b5b51fd7633c..7117760ae3dbc 100755 --- a/bin/build-plugin-zip.sh +++ b/bin/build-plugin-zip.sh @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash # Exit if any command fails set -e @@ -7,6 +7,50 @@ set -e cd "$(dirname "$0")" cd .. +# Make sure there are no changes in the working tree. Release builds should be +# traceable to a particular commit and reliably reproducible. (This is not +# totally true at the moment because we download nightly vendor scripts). +changed= +if ! git diff --exit-code > /dev/null; then + changed="file(s) modified" +elif ! git diff --cached --exit-code > /dev/null; then + changed="file(s) staged" +fi +if [ ! -z "$changed" ]; then + git status + echo "ERROR: Cannot build plugin zip with dirty working tree." + echo " Commit your changes and try again." + exit 1 +fi + +branch="$(git rev-parse --abbrev-ref HEAD)" +if [ "$branch" != 'master' ]; then + echo "WARNING: You should probably be running this script against the" + echo " 'master' branch (current: '$branch')" + echo + sleep 2 +fi + +# Download all vendor scripts +vendor_scripts="" +# Using `command | while read...` is more typical, but the inside of the while +# loop will run under a separate process this way, meaning that it cannot +# modify $vendor_scripts. See: https://stackoverflow.com/a/16855194 +exec 3< <( + # minified versions of vendor scripts + php bin/get-vendor-scripts.php + # non-minified versions of vendor scripts (for SCRIPT_DEBUG) + php bin/get-vendor-scripts.php debug +) +while IFS='|' read -u 3 url filename; do + echo "$url" + echo -n " > vendor/$filename ... " + curl --location --silent "$url" --output "vendor/_download.tmp.js" + mv -f "vendor/_download.tmp.js" "vendor/$filename" + echo "done!" + vendor_scripts="$vendor_scripts vendor/$filename" +done + # Run the build npm install npm run build @@ -14,17 +58,31 @@ npm run build # Remove any existing zip file rm -f gutenberg.zip +# Temporarily modify `gutenberg.php` with production constants defined. Use a +# temp file because `bin/generate-gutenberg-php.php` reads from `gutenberg.php` +# so we need to avoid writing to that file at the same time. +php bin/generate-gutenberg-php.php > gutenberg.tmp.php +mv gutenberg.tmp.php gutenberg.php + # Generate the plugin zip file zip -r gutenberg.zip \ gutenberg.php \ + index.php \ lib/*.php \ lib/blocks/*.php \ post-content.js \ - blocks/build \ - components/build \ - date/build \ - editor/build \ - element/build \ - i18n/build \ - utils/build \ + $vendor_scripts \ + blocks/build/*.{js,map} \ + components/build/*.{js,map} \ + date/build/*.{js,map} \ + editor/build/*.{js,map} \ + element/build/*.{js,map} \ + i18n/build/*.{js,map} \ + utils/build/*.{js,map} \ + blocks/build/*.css \ + components/build/*.css \ + editor/build/*.css \ README.md + +# Reset `gutenberg.php` +git checkout gutenberg.php diff --git a/bin/generate-gutenberg-php.php b/bin/generate-gutenberg-php.php new file mode 100755 index 0000000000000..fc9bf51ef3cab --- /dev/null +++ b/bin/generate-gutenberg-php.php @@ -0,0 +1,62 @@ +#!/usr/bin/env php + 1 && 'debug' === strtolower( $argv[1] ) ); + +// Hacks to get lib/client-assets.php to load. +define( 'ABSPATH', dirname( dirname( __FILE__ ) ) ); +/** + * Hi, phpcs + */ +function add_action() {} + +// Instead of loading script files, just show how they need to be loaded. +define( 'GUTENBERG_LIST_VENDOR_ASSETS', true ); + +require_once dirname( dirname( __FILE__ ) ) . '/lib/client-assets.php'; + +gutenberg_register_vendor_scripts(); diff --git a/gutenberg.php b/gutenberg.php index 3436e1f6bfae8..dc89d835355a0 100644 --- a/gutenberg.php +++ b/gutenberg.php @@ -9,6 +9,10 @@ * @package gutenberg */ +### BEGIN AUTO-GENERATED DEFINES +define( 'GUTENBERG_DEVELOPMENT_MODE', true ); +### END AUTO-GENERATED DEFINES + // Load API functions. require_once dirname( __FILE__ ) . '/lib/blocks.php'; require_once dirname( __FILE__ ) . '/lib/client-assets.php'; diff --git a/lib/client-assets.php b/lib/client-assets.php index a4b0ed4bba2dc..a7e4fe579c935 100644 --- a/lib/client-assets.php +++ b/lib/client-assets.php @@ -35,44 +35,13 @@ function gutenberg_url( $path ) { } /** - * Registers common scripts to be used as dependencies of the editor and plugins. + * Registers common scripts and styles to be used as dependencies of the editor + * and plugins. * * @since 0.1.0 */ -function gutenberg_register_scripts() { - $suffix = SCRIPT_DEBUG ? '' : '.min'; - - // Vendor Scripts. - $react_suffix = ( SCRIPT_DEBUG ? '.development' : '.production' ) . $suffix; - gutenberg_register_vendor_script( - 'react', - 'https://unpkg.com/react@next/umd/react' . $react_suffix . '.js' - ); - gutenberg_register_vendor_script( - 'react-dom', - 'https://unpkg.com/react-dom@next/umd/react-dom' . $react_suffix . '.js', - array( 'react' ) - ); - gutenberg_register_vendor_script( - 'react-dom-server', - 'https://unpkg.com/react-dom@next/umd/react-dom-server' . $react_suffix . '.js', - array( 'react' ) - ); - $moment_script = SCRIPT_DEBUG ? 'moment.js' : 'min/moment.min.js'; - gutenberg_register_vendor_script( - 'moment', - 'https://unpkg.com/moment@2.18.1/' . $moment_script, - array( 'react' ) - ); - gutenberg_register_vendor_script( - 'tinymce-nightly', - 'https://fiddle.azurewebsites.net/tinymce/nightly/tinymce' . $suffix . '.js' - ); - gutenberg_register_vendor_script( - 'tinymce-nightly-lists', - 'https://fiddle.azurewebsites.net/tinymce/nightly/plugins/lists/plugin' . $suffix . '.js', - array( 'tinymce-nightly' ) - ); +function gutenberg_register_scripts_and_styles() { + gutenberg_register_vendor_scripts(); // Editor Scripts. wp_register_script( @@ -152,7 +121,52 @@ function gutenberg_register_scripts() { filemtime( gutenberg_dir_path() . 'blocks/build/style.css' ) ); } -add_action( 'init', 'gutenberg_register_scripts' ); +add_action( 'init', 'gutenberg_register_scripts_and_styles' ); + +/** + * Registers vendor JavaScript files to be used as dependencies of the editor + * and plugins. + * + * This function is called from a script during the plugin build process, so it + * should not call any WordPress PHP functions. + * + * @since 0.1.0 + */ +function gutenberg_register_vendor_scripts() { + $suffix = SCRIPT_DEBUG ? '' : '.min'; + + // Vendor Scripts. + $react_suffix = ( SCRIPT_DEBUG ? '.development' : '.production' ) . $suffix; + gutenberg_register_vendor_script( + 'react', + 'https://unpkg.com/react@next/umd/react' . $react_suffix . '.js' + ); + gutenberg_register_vendor_script( + 'react-dom', + 'https://unpkg.com/react-dom@next/umd/react-dom' . $react_suffix . '.js', + array( 'react' ) + ); + gutenberg_register_vendor_script( + 'react-dom-server', + 'https://unpkg.com/react-dom@next/umd/react-dom-server' . $react_suffix . '.js', + array( 'react' ) + ); + $moment_script = SCRIPT_DEBUG ? 'moment.js' : 'min/moment.min.js'; + gutenberg_register_vendor_script( + 'moment', + 'https://unpkg.com/moment@2.18.1/' . $moment_script, + array( 'react' ) + ); + gutenberg_register_vendor_script( + 'tinymce-nightly', + 'https://fiddle.azurewebsites.net/tinymce/nightly/tinymce' . $suffix . '.js' + ); + gutenberg_register_vendor_script( + 'tinymce-nightly-lists', + 'https://fiddle.azurewebsites.net/tinymce/nightly/plugins/lists/plugin' . $suffix . '.js', + array( 'tinymce-nightly' ) + ); +} /** * Retrieves a unique and reasonably short and human-friendly filename for a @@ -216,11 +230,19 @@ function gutenberg_register_vendor_script( $handle, $src, $deps = array() ) { } $filename = gutenberg_vendor_script_filename( $src ); + + if ( defined( 'GUTENBERG_LIST_VENDOR_ASSETS' ) && GUTENBERG_LIST_VENDOR_ASSETS ) { + echo "$src|$filename\n"; + return; + } + $full_path = gutenberg_dir_path() . 'vendor/' . $filename; $needs_fetch = ( - ! file_exists( $full_path ) || - time() - filemtime( $full_path ) >= DAY_IN_SECONDS + defined( 'GUTENBERG_DEVELOPMENT_MODE' ) && GUTENBERG_DEVELOPMENT_MODE && ( + ! file_exists( $full_path ) || + time() - filemtime( $full_path ) >= DAY_IN_SECONDS + ) ); if ( $needs_fetch ) { diff --git a/phpcs.xml b/phpcs.xml index 5dbac182d815b..5f8324685949f 100644 --- a/phpcs.xml +++ b/phpcs.xml @@ -10,12 +10,18 @@ gutenberg.php ./phpunit + ./bin gutenberg.php + + + gutenberg.php + + phpunit/*