From 53b33966d7d3fba607ebeaadd76cfd9d9ac3a954 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Wed, 11 Dec 2013 23:14:11 -0800 Subject: [PATCH 1/5] Squashed 'bin/' changes from 5614813..cc5a003 cc5a003 Reference master branch in TravisCI build badge 2e82c85 Merge commit '85f0b269038cb772d9353f7236a28757c10295af' 234a146 Merge pull request #25 from GaryJones/patch-1 5c6fae7 Remove smarttabs option from .jshintrc 9fcac99 Add Generic.ControlStructures.InlineControlStructure 218f007 Merge commit '6a9b2c7f6a8044f337152fb406ebe58f1c26b5ac' into develop 894d120 Merge pull request #18 from x-team/issue-16 de1db88 Remove wordpress- from url 5581e97 Get latest trunk file from github 256b0a0 Embed YouTube demo video in readme; add markdown support 9d1d025 Add base phpcs ruleset for plugins 5de1b8e Update .jshintrc to match new in core ab7b9cd Update .tavis.yml to check against master and latest. This closes #16 and #15 9aa3e33 Merge pull request #17 from jonathanbardo/master 63a11a4 Correct small typo 8e3bab1 Merge pull request #15 from jonathanbardo/master ed0b379 Update WP version to latest stable release 6956ba1 Merge pull request #13 from jonathanbardo/master a864385 Update WP_VERSION to 3.7 0c545c3 Merge commit '4cd538fd0b8e6fcbe68cd4e4a8e39206103023b2' into develop 4cd538f Merge branch 'master' of github.com:x-team/wp-plugin-dev-lib 258cdf9 Fix reference from jshint to phpcs c9f45eb Add formatting 7d26511 Add git-subtree instructions 528bd0e Only apply jshint to staged JS files 9c1e6ea Update svn-push to work with svn repo out of git repo 86d46a9 Explicitly reference bash (not dash) for pre-commit hook 64a6d09 Move WordPress.org SVN checkout outside of Git root a4aa443 Fix symlinked dirs for Travis; remove PHP 5.2 for Travis fd97d04 Finish with 5.2 compat; exclude bin from syntax check ff49315 Improve relative paths for phpunit; update install-wp-tests.sh c213c44 Run Travis tests on PHP 5.2 4eaa28e Account for renamed files in pre-commit hook 8001c36 Eliminate PHP 5.3 requirement, replacing namespaces and closures 774bdc3 Check modified files, pass select JS to jshint, run phpunit in vagrant bc955c7 Fix pre-commit detection of staged_php_files d0194bb Add PHP syntax checks for travis-ci and pre-commit hook c98d9c4 Merge branch 'master' of github.com:x-team/wp-plugin-dev-lib 2e1b928 Remove dependency on WP_CLI 0e07a75 Note how add .travis.yml and .jshintrc to host plugin via symlinks da3555c Also check for presence of phpunit.xml.dist 0ae29af Update pre-commit hook so PHPCS only looks at staged PHP files 00d36fb Merge commit '7ef48bd5aa6680d02589a9f5697b35cd9a9520ca' into develop f5f2c1c Update pre-commit hook to look for staged php files 3ddac64 Revamp pre-commit hook, adding jshint 9f7df05 Rename .jshint => .jshintrc 817f4c2 Add travis-ci with support for jshint, phpcs, phpunit a3a984d Add jshint and fix warnings 730cf4f Merge commit '32585ea10effb3de33aa7136424364359c199969' 1095520 Apply phpcs fixes git-subtree-dir: bin git-subtree-split: cc5a003aca81eb3af6c01f556446168e3e71263d --- .jshintrc | 20 ++++++++ .travis.yml | 33 ++++++++++++ class-wordpress-readme-parser.php | 81 +++++++++++++++++++----------- install-wp-tests.sh | 49 +++++++++++++++--- phpcs.ruleset.xml | 27 ++++++++++ pre-commit | 83 ++++++++++++++++++++++++------- readme.md | 38 +++++++++++++- svn-push | 21 +++++--- 8 files changed, 288 insertions(+), 64 deletions(-) create mode 100644 .jshintrc create mode 100644 .travis.yml create mode 100644 phpcs.ruleset.xml diff --git a/.jshintrc b/.jshintrc new file mode 100644 index 0000000..bf11264 --- /dev/null +++ b/.jshintrc @@ -0,0 +1,20 @@ +{ + "boss": true, + "curly": true, + "eqeqeq": true, + "eqnull": true, + "expr": true, + "immed": true, + "noarg": true, + "quotmark": "single", + "trailing": true, + "undef": true, + "unused": true, + + "browser": true, + + "globals": { + "jQuery": false, + "wp": false + } +} diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..ae1da44 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,33 @@ +language: + - php + - node_js + +php: + - 5.3 + - 5.4 + +node_js: + - 0.10 + +env: + - WP_VERSION=master WP_MULTISITE=0 + - WP_VERSION=master WP_MULTISITE=1 + - WP_VERSION=latest WP_MULTISITE=0 + - WP_VERSION=latest WP_MULTISITE=1 + +before_script: + - export WP_TESTS_DIR=/tmp/wordpress-tests/ + - export PLUGIN_DIR=$(pwd) + - export PLUGIN_SLUG=$(basename $(pwd) | sed 's/^wp-//') + - if [ -e phpunit.xml ] || [ -e phpunit.xml.dist ]; then bash bin/install-wp-tests.sh wordpress_test root '' localhost $WP_VERSION; cd /tmp/wordpress/wp-content/plugins; ln -s $PLUGIN_DIR $PLUGIN_SLUG; cd $PLUGIN_DIR; fi + - pear config-set auto_discover 1 + - pear install PHP_CodeSniffer + - git clone git://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards.git $(pear config-get php_dir)/PHP/CodeSniffer/Standards/WordPress + - phpenv rehash + - npm install -g jshint + +script: + - find . -path ./bin -prune -o \( -name '*.php' -o -name '*.inc' \) -exec php -lf {} \; + - if [ -e phpunit.xml ] || [ -e phpunit.xml.dist ]; then phpunit; fi + - phpcs --standard=$(if [ -e ruleset.xml ]; then echo ruleset.xml; else echo WordPress; fi) $(find . -name '*.php') + - jshint . diff --git a/class-wordpress-readme-parser.php b/class-wordpress-readme-parser.php index 6918dd7..784b219 100644 --- a/class-wordpress-readme-parser.php +++ b/class-wordpress-readme-parser.php @@ -19,27 +19,29 @@ class WordPress_Readme_Parser { function __construct( $args = array() ) { $args = array_merge( get_object_vars( $this ), $args ); - foreach ($args as $key => $value) { + foreach ( $args as $key => $value ) { $this->$key = $value; } $this->source = file_get_contents( $this->path ); if ( ! $this->source ) { - throw new \Exception( 'readme.txt was empty or unreadable' ); + throw new Exception( 'readme.txt was empty or unreadable' ); } // Parse metadata $syntax_ok = preg_match( '/^=== (.+?) ===\n(.+?)\n\n(.+?)\n(.+)/s', $this->source, $matches ); if ( ! $syntax_ok ) { - throw new \Exception( 'Malformed metadata block' ); + throw new Exception( 'Malformed metadata block' ); } $this->title = $matches[1]; $this->short_description = $matches[3]; $readme_txt_rest = $matches[4]; $this->metadata = array_fill_keys( array( 'Contributors', 'Tags', 'Requires at least', 'Tested up to', 'Stable tag', 'License', 'License URI' ), null ); - foreach( explode( "\n", $matches[2] ) as $metadatum ) { - preg_match( '/^(.+?):\s+(.+)$/', $metadatum, $metadataum_matches ) || \WP_CLI::error( "Parse error in $metadatum" ); - list( $name, $value ) = array_slice( $metadataum_matches, 1, 2 ); + foreach ( explode( "\n", $matches[2] ) as $metadatum ) { + if ( ! preg_match( '/^(.+?):\s+(.+)$/', $metadatum, $metadataum_matches ) ) { + throw new Exception( "Parse error in $metadatum" ); + } + list( $name, $value ) = array_slice( $metadataum_matches, 1, 2 ); $this->metadata[$name] = $value; } $this->metadata['Contributors'] = preg_split( '/\s*,\s*/', $this->metadata['Contributors'] ); @@ -47,13 +49,13 @@ function __construct( $args = array() ) { $syntax_ok = preg_match_all( '/(?:^|\n)== (.+?) ==\n(.+?)(?=\n== |$)/s', $readme_txt_rest, $section_matches, PREG_SET_ORDER ); if ( ! $syntax_ok ) { - throw new \Exception( 'Failed to parse sections from readme.txt' ); + throw new Exception( 'Failed to parse sections from readme.txt' ); } foreach ( $section_matches as $section_match ) { array_shift( $section_match ); - $heading = array_shift( $section_match ); - $body = trim( array_shift( $section_match ) ); + $heading = array_shift( $section_match ); + $body = trim( array_shift( $section_match ) ); $subsections = array(); // @todo Parse out front matter /(.+?)(\n=\s+.+$)/s @@ -76,25 +78,37 @@ function __construct( $args = array() ) { /** * Convert the parsed readme.txt into Markdown + * @param array|string [$params] * @return string */ function to_markdown( $params = array() ) { + $general_section_formatter = function ( $body ) use ( $params ) { + $body = preg_replace( + '#\[youtube\s+(?:http://www\.youtube\.com/watch\?v=|http://youtu\.be/)(.+?)\]#', + '[![Play video on YouTube](http://i1.ytimg.com/vi/$1/hqdefault.jpg)](http://www.youtube.com/watch?v=$1)', + $body + ); + return $body; + }; + // Parse sections $section_formatters = array( 'Description' => function ( $body ) use ( $params ) { if ( isset( $params['travis_ci_url'] ) ) { - $body .= sprintf( "\n\n[![Build Status](%s.png)](%s)", $params['travis_ci_url'], $params['travis_ci_url'] ); + $body .= sprintf( "\n\n[![Build Status](%s.png?branch=master)](%s)", $params['travis_ci_url'], $params['travis_ci_url'] ); } return $body; }, 'Screenshots' => function ( $body ) { $body = trim( $body ); $new_body = ''; - $screenshots = array(); - preg_match_all( '/^\d+\. (.+?)$/m', $body, $screenshot_matches, PREG_SET_ORDER ) || \WP_CLI::error( 'Malformed screenshot section' ); + if ( ! preg_match_all( '/^\d+\. (.+?)$/m', $body, $screenshot_matches, PREG_SET_ORDER ) ) { + throw new Exception( 'Malformed screenshot section' ); + } foreach ( $screenshot_matches as $i => $screenshot_match ) { - foreach ( array( 'jpg', 'gif', 'png' ) as $ext ) { + $img_extensions = array( 'jpg', 'gif', 'png' ); + foreach ( $img_extensions as $ext ) { $filepath = sprintf( 'assets/screenshot-%d.%s', $i + 1, $ext ); if ( file_exists( dirname( $this->path ) . DIRECTORY_SEPARATOR . $filepath ) ) { break; @@ -119,20 +133,26 @@ function to_markdown( $params = array() ) { // Format metadata $formatted_metadata = $this->metadata; - $formatted_metadata['Contributors'] = join(', ', array_map( - function ( $contributor ) { - $contributor = strtolower( $contributor ); - // @todo Map to GitHub account - return sprintf( '[%1$s](http://profiles.wordpress.org/%1$s)', $contributor ); - }, - $this->metadata['Contributors'] - )); - $formatted_metadata['Tags'] = join(', ', array_map( - function ( $tag ) { - return sprintf( '[%1$s](http://wordpress.org/plugins/tags/%1$s)', $tag ); - }, - $this->metadata['Tags'] - )); + $formatted_metadata['Contributors'] = join( + ', ', + array_map( + function ( $contributor ) { + $contributor = strtolower( $contributor ); + // @todo Map to GitHub account + return sprintf( '[%1$s](http://profiles.wordpress.org/%1$s)', $contributor ); + }, + $this->metadata['Contributors'] + ) + ); + $formatted_metadata['Tags'] = join( + ', ', + array_map( + function ( $tag ) { + return sprintf( '[%1$s](http://wordpress.org/plugins/tags/%1$s)', $tag ); + }, + $this->metadata['Tags'] + ) + ); $formatted_metadata['License'] = sprintf( '[%s](%s)', $formatted_metadata['License'], $formatted_metadata['License URI'] ); unset( $formatted_metadata['License URI'] ); if ( $this->metadata['Stable tag'] === 'trunk' ) { @@ -140,7 +160,7 @@ function ( $tag ) { } // Render metadata - $markdown = "\n"; + $markdown = "\n"; $markdown .= sprintf( "# %s\n", $this->title ); $markdown .= "\n"; if ( file_exists( 'assets/banner-1544x500.png' ) ) { @@ -159,9 +179,12 @@ function ( $tag ) { $markdown .= "\n"; $body = $section['body']; + + $body = call_user_func( $general_section_formatter, $body ); if ( isset( $section_formatters[$section['heading']] ) ) { - $body = trim(call_user_func( $section_formatters[$section['heading']], $body )); + $body = trim( call_user_func( $section_formatters[$section['heading']], $body ) ); } + if ( $body ) { $markdown .= sprintf( "%s\n", $body ); } diff --git a/install-wp-tests.sh b/install-wp-tests.sh index a93a900..464772b 100755 --- a/install-wp-tests.sh +++ b/install-wp-tests.sh @@ -1,32 +1,65 @@ #!/usr/bin/env bash if [ $# -lt 3 ]; then - echo "usage: $0 [wp-version]" + echo "usage: $0 [db-host] [wp-version]" exit 1 fi DB_NAME=$1 DB_USER=$2 DB_PASS=$3 -WP_VERSION=${4-master} +DB_HOST=${4-localhost} +WP_VERSION=${5-master} set -ex # set up a WP install WP_CORE_DIR=/tmp/wordpress/ mkdir -p $WP_CORE_DIR -wget -nv -O /tmp/wordpress.tar.gz https://github.com/WordPress/WordPress/tarball/$WP_VERSION + +if [ $WP_VERSION == 'latest' ]; then + ARCHIVE_URL='http://wordpress.org/latest.tar.gz' +else + ARCHIVE_URL="https://github.com/WordPress/WordPress/tarball/$WP_VERSION" +fi + +wget -nv -O /tmp/wordpress.tar.gz $ARCHIVE_URL tar --strip-components=1 -zxmf /tmp/wordpress.tar.gz -C $WP_CORE_DIR # set up testing suite svn co --ignore-externals --quiet http://unit-tests.svn.wordpress.org/trunk/ $WP_TESTS_DIR +# portable in-place argument for both GNU sed and Mac OSX sed +if [[ $(uname -s) == 'Darwin' ]]; then + ioption='-i ""' +else + ioption='-i' +fi + +# generate testing config file cd $WP_TESTS_DIR cp wp-tests-config-sample.php wp-tests-config.php -sed -i "s:dirname( __FILE__ ) . '/wordpress/':'$WP_CORE_DIR':" wp-tests-config.php -sed -i "s/yourdbnamehere/$DB_NAME/" wp-tests-config.php -sed -i "s/yourusernamehere/$DB_USER/" wp-tests-config.php -sed -i "s/yourpasswordhere/$DB_PASS/" wp-tests-config.php +sed $ioption "s:dirname( __FILE__ ) . '/wordpress/':'$WP_CORE_DIR':" wp-tests-config.php +sed $ioption "s/yourdbnamehere/$DB_NAME/" wp-tests-config.php +sed $ioption "s/yourusernamehere/$DB_USER/" wp-tests-config.php +sed $ioption "s/yourpasswordhere/$DB_PASS/" wp-tests-config.php +sed $ioption "s|localhost|${DB_HOST}|" wp-tests-config.php + +# parse DB_HOST for port or socket references +PARTS=(${DB_HOST//\:/ }) +DB_HOSTNAME=${PARTS[0]}; +DB_SOCK_OR_PORT=${PARTS[1]}; +EXTRA="" + +if ! [ -z $DB_HOSTNAME ] ; then + if [[ "$DB_SOCK_OR_PORT" =~ ^[0-9]+$ ]] ; then + EXTRA=" --host=$DB_HOSTNAME --port=$DB_SOCK_OR_PORT --protocol=tcp" + elif ! [ -z $DB_SOCK_OR_PORT ] ; then + EXTRA=" --socket=$DB_SOCK_OR_PORT" + elif ! [ -z $DB_HOSTNAME ] ; then + EXTRA=" --host=$DB_HOSTNAME --protocol=tcp" + fi +fi # create database -mysqladmin create $DB_NAME --user="$DB_USER" --password="$DB_PASS" +mysqladmin create $DB_NAME --user="$DB_USER" --password="$DB_PASS"$EXTRA diff --git a/phpcs.ruleset.xml b/phpcs.ruleset.xml new file mode 100644 index 0000000..aeb1d34 --- /dev/null +++ b/phpcs.ruleset.xml @@ -0,0 +1,27 @@ + + + Generally-applicable sniffs for WordPress plugins + + + + + + + + /tests/* + + + + + + + + + + + + + + + + diff --git a/pre-commit b/pre-commit index 17d9685..b755ec1 100755 --- a/pre-commit +++ b/pre-commit @@ -1,27 +1,74 @@ -#!/bin/sh -# An example pre-commit hook for WordPress +#!/bin/bash +# WordPress Plugin pre-commit hook set -e +message="Checking staged changes..." +git_status_egrep='^[MARC].+' + +for i; do + case "$i" + in + -m) + message="Checking any uncommitted changes..." + git_status_egrep='^.?[MARC].+' + shift;; + esac +done + +echo $message + +# Check for staged JS files +IFS=$'\n' staged_js_files=( $(git status --porcelain | sed 's/[^ ]* -> *//g' | egrep $git_status_egrep'\.js$' | cut -c4-) ) +if [ ${#staged_js_files[@]} != 0 ]; then + # JSHint + if [ -e .jshintrc ]; then + echo "## jslint" + if command -v jshint >/dev/null 2>&1; then + jshint "${staged_js_files[@]}" + else + echo "Skipping jshint since not installed" + fi + fi + +fi + +# Check for staged PHP files +IFS=$'\n' staged_php_files=( $(git status --porcelain | sed 's/[^ ]* -> *//g' | egrep $git_status_egrep'\.php$' | cut -c4-) ) +if [ ${#staged_php_files[@]} != 0 ]; then + # PHP Syntax Check + for php_file in "${staged_php_files[@]}"; do + php -lf $php_file + done + + # PHPUnit + if [ -e phpunit.xml ] || [ -e phpunit.xml.dist ]; then + echo "## phpunit" + if [ "$USER" != 'vagrant' ] && command -v vagrant >/dev/null 2>&1 && command -v vassh >/dev/null 2>&1; then + echo "Running phpunit in vagrant..." + vassh phpunit + elif ! command -v phpunit >/dev/null 2>&1;then + echo "Skipping phpunit since not installed" + elif [ -z "$WP_TESTS_DIR" ]; then + echo "Skipping phpunit since WP_TESTS_DIR env missing" + else + phpunit + fi + fi + + # PHP_CodeSniffer WordPress Coding Standards + echo "## phpcs" + if command -v phpcs >/dev/null 2>&1; then + phpcs_standard=$(if [ -e ruleset.xml ]; then echo ruleset.xml; else echo WordPress; fi) + phpcs -p -s -v --standard=$phpcs_standard "${staged_php_files[@]}" + else + echo "Skipping phpcs since not installed" + fi +fi + # Make sure the readme.md never gets out of sync with the readme.txt generate_markdown_readme=$(find . -name generate-markdown-readme -print -quit) if [ -n "$generate_markdown_readme" ]; then markdown_readme_path=$($generate_markdown_readme) git add $markdown_readme_path fi - -if [ -e phpunit.xml.dist ]; then - # @todo Check to see if phpunit is even installed - # @todo Check if WP_TESTS_DIR is not set - phpunit -fi - -if [ -e .jshintrc ]; then - # @todo Check to see if jshint is even installed - jshint -fi - -# Run through PHP_CodeSniffer rules for WordPress Coding Standards -# @todo Check if phpcs is installed -# @todo Check if WordPress standard sniffs are installed -phpcs -p -s -v --standard=WordPress $(git status --porcelain | egrep '^[MARC]' | cut -c4- | egrep '.php$') diff --git a/readme.md b/readme.md index 9d48e48..38c5812 100644 --- a/readme.md +++ b/readme.md @@ -5,9 +5,43 @@ wp-plugin-dev-lib It is intended that this repo be included in plugin repo via git-subtree/submodule in a `bin/` directory. -Symlink to `pre-commit` from your project's `.git/hooks/pre-commit` +To **add** it to your repo, do: -Includes a WordPress README [parser](class-wordpress-readme-parser.php) and [converter](generate-markdown-readme) to Markdown, +```bash +git subtree add --prefix bin \ + git@github.com:x-team/wp-plugin-dev-lib.git master --squash +``` + +To **update** the library with the latest changes: + +```bash +git subtree pull --prefix bin \ + git@github.com:x-team/wp-plugin-dev-lib.git master --squash +``` + +And if you have changes you want to **upstream**, do: + +```bash +git subtree push --prefix bin \ + git@github.com:x-team/wp-plugin-dev-lib.git master +``` + +Symlink to the `.travis.yml`, `.jshintrc`, and `phpcs.ruleset.xml` inside of the `bin/` directory you added: + +```bash +ln -s bin/.travis.yml . && git add .travis.yml +ln -s bin/.jshintrc . && git add .jshintrc +ln -s bin/phpcs.ruleset.xml . && git add phpcs.ruleset.xml +``` + +Symlink to `pre-commit` from your project's `.git/hooks/pre-commit`: + +```bash +cd .git/hooks +ln -s ../../bin/pre-commit . +``` + +The library includes a WordPress README [parser](class-wordpress-readme-parser.php) and [converter](generate-markdown-readme) to Markdown, so you don't have to manually keep your `readme.txt` on WordPress.org in sync with the `readme.md` you have on GitHub. The converter will also automatically recognize the presence of projects with Travis CI and include the status image in the markdown. Screenshots and banner images for WordPress.org are also automatically incorporated into the `readme.md`. diff --git a/svn-push b/svn-push index bd324c4..c573756 100755 --- a/svn-push +++ b/svn-push @@ -1,6 +1,6 @@ #!/bin/bash # Given a svn-url file one directory up, export the latest git commits to the specified SVN repo. -# Create a git release tag from the verison specified in the plugin file. +# Create a git release tag from the version specified in the plugin file. # Author: Weston Ruter (@westonruter) set -e @@ -44,7 +44,7 @@ fi git pull origin master git push origin master svn_url=$(cat svn-url) -svn_repo_dir=$git_root/svn +svn_repo_dir=/tmp/svn-$(basename $git_root)-$(md5sum <<< $git_root | cut -c1-32) for php in *.php; do if grep -q 'Plugin Name:' $php && grep -q 'Version:' $php; then @@ -79,6 +79,9 @@ else echo "Skipping plugin tag $plugin_version since already exists" fi +if [ -e $svn_repo_dir ] && [ ! -e $svn_repo_dir/.svn ]; then + rm -rf $svn_repo_dir +fi if [ ! -e $svn_repo_dir ]; then svn checkout $svn_url $svn_repo_dir cd $svn_repo_dir @@ -87,15 +90,16 @@ else svn up fi - -cd trunk +cd $git_root # rsync all cached files and their directories cat <( git ls-files --cached --full-name $git_root \ & git ls-files --cached --full-name $git_root | xargs -I {} dirname {} | sort | uniq -) | sort | rsync -avz --delete --delete-excluded --include-from=- --exclude='*' $git_root/ ./ +) | sort | rsync -avz --delete --delete-excluded --include-from=- --exclude='*' ./ $svn_repo_dir/trunk/ + +cd $svn_repo_dir/trunk # move assets directory to proper location in SVN if [ -d assets ]; then @@ -123,6 +127,9 @@ svn add --force trunk # Do SVN commit svn_commit_file=$svn_repo_dir/COMMIT_MSG +last_pushed_commit=$(svn log -l 1 | grep -E -o '^commit ([0-9a-f]{5,})' | head -n 1 | cut -c8-) + +cd $git_root git log -1 --format="Update to commit %h from $(git config --get remote.origin.url)" > $svn_commit_file echo >> $svn_commit_file @@ -131,7 +138,6 @@ echo >> $svn_commit_file echo -n 'Obtaining last commit pushed to SVN...' git_log_args='--pretty=short --name-status --color=never' -last_pushed_commit=$(svn log -l 1 | grep -E -o '^commit ([0-9a-f]{5,})' | head -n 1 | cut -c8-) if [ -z "$last_pushed_commit" ]; then echo "none; starting from beginning" git log $git_log_args >> $svn_commit_file @@ -140,6 +146,7 @@ else git log $git_log_args $last_pushed_commit..HEAD >> $svn_commit_file fi +cd $svn_repo_dir svn commit -F $svn_commit_file rm $svn_commit_file @@ -147,4 +154,4 @@ rm $svn_commit_file # Restore branch if [ $current_branch != 'master' ]; then git checkout $current_branch -fi \ No newline at end of file +fi From 09b07e82557bbb0f032394fbe3b1c9a42666aa54 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Thu, 12 Dec 2013 00:55:30 -0800 Subject: [PATCH 2/5] Update minify libs and add script for updating --- minify/JS/ClosureCompiler.php | 14 +++++++++--- minify/JS/JSMin.php | 40 +++++++++++++++++++++++------------ minify/update | 25 ++++++++++++++++++++++ 3 files changed, 62 insertions(+), 17 deletions(-) create mode 100755 minify/update diff --git a/minify/JS/ClosureCompiler.php b/minify/JS/ClosureCompiler.php index 51f7cd1..d4358a0 100644 --- a/minify/JS/ClosureCompiler.php +++ b/minify/JS/ClosureCompiler.php @@ -14,7 +14,10 @@ * @todo can use a stream wrapper to unit test this? */ class Minify_JS_ClosureCompiler { - const URL = 'http://closure-compiler.appspot.com/compile'; + /** + * @var $url URL to compiler server. defaults to google server + */ + protected $url = 'http://closure-compiler.appspot.com/compile'; /** * Minify Javascript code via HTTP request to the Closure Compiler API @@ -34,12 +37,17 @@ public static function minify($js, array $options = array()) * @param array $options * * fallbackFunc : default array($this, 'fallback'); + * compilerUrl : URL to closure compiler server */ public function __construct(array $options = array()) { $this->_fallbackFunc = isset($options['fallbackMinifier']) ? $options['fallbackMinifier'] : array($this, '_fallback'); + + if (isset($options['compilerUrl'])) { + $this->url = $options['compilerUrl']; + } } public function min($js) @@ -76,7 +84,7 @@ protected function _getResponse($postBody) { $allowUrlFopen = preg_match('/1|yes|on|true/i', ini_get('allow_url_fopen')); if ($allowUrlFopen) { - $contents = file_get_contents(self::URL, false, stream_context_create(array( + $contents = file_get_contents($this->url, false, stream_context_create(array( 'http' => array( 'method' => 'POST', 'header' => "Content-type: application/x-www-form-urlencoded\r\nConnection: close\r\n", @@ -86,7 +94,7 @@ protected function _getResponse($postBody) ) ))); } elseif (defined('CURLOPT_POST')) { - $ch = curl_init(self::URL); + $ch = curl_init($this->url); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-type: application/x-www-form-urlencoded')); diff --git a/minify/JS/JSMin.php b/minify/JS/JSMin.php index c84dd84..9840d8b 100644 --- a/minify/JS/JSMin.php +++ b/minify/JS/JSMin.php @@ -200,8 +200,9 @@ protected function action($command) break; } if ($this->isEOF($this->a)) { + $byte = $this->inputIndex - 1; throw new JSMin_UnterminatedStringException( - "JSMin: Unterminated String at byte {$this->inputIndex}: {$str}"); + "JSMin: Unterminated String at byte {$byte}: {$str}"); } $str .= $this->a; if ($this->a === '\\') { @@ -251,8 +252,9 @@ protected function action($command) $this->a = $this->get(); $pattern .= $this->a; } elseif ($this->isEOF($this->a)) { + $byte = $this->inputIndex - 1; throw new JSMin_UnterminatedRegExpException( - "JSMin: Unterminated RegExp at byte {$this->inputIndex}: {$pattern}"); + "JSMin: Unterminated RegExp at byte {$byte}: {$pattern}"); } $this->output .= $this->a; $this->lastByteOut = $this->a; @@ -272,23 +274,33 @@ protected function isRegexpLiteral() // we obviously aren't dividing return true; } - if ($this->a === ' ' || $this->a === "\n") { - $length = strlen($this->output); - if ($length < 2) { // weird edge case - return true; + + // we have to check for a preceding keyword, and we don't need to pattern + // match over the whole output. + $recentOutput = substr($this->output, -10); + + // check if return/typeof directly precede a pattern without a space + foreach (array('return', 'typeof') as $keyword) { + if ($this->a !== substr($keyword, -1)) { + // certainly wasn't keyword + continue; } - // you can't divide a keyword - if (preg_match('/(?:case|else|in|return|typeof)$/', $this->output, $m)) { - if ($this->output === $m[0]) { // odd but could happen - return true; - } - // make sure it's a keyword, not end of an identifier - $charBeforeKeyword = substr($this->output, $length - strlen($m[0]) - 1, 1); - if (! $this->isAlphaNum($charBeforeKeyword)) { + if (preg_match("~(^|[\\s\\S])" . substr($keyword, 0, -1) . "$~", $recentOutput, $m)) { + if ($m[1] === '' || !$this->isAlphaNum($m[1])) { return true; } } } + + // check all keywords + if ($this->a === ' ' || $this->a === "\n") { + if (preg_match('~(^|[\\s\\S])(?:case|else|in|return|typeof)$~', $recentOutput, $m)) { + if ($m[1] === '' || !$this->isAlphaNum($m[1])) { + return true; + } + } + } + return false; } diff --git a/minify/update b/minify/update new file mode 100755 index 0000000..289175d --- /dev/null +++ b/minify/update @@ -0,0 +1,25 @@ +#!/usr/bin/env php + "https://raw.github.com/mrclay/minify/master/min/lib/Minify/JS/ClosureCompiler.php", + "JS/JSMin.php" => "https://raw.github.com/mrclay/minify/master/min/lib/JSMin.php", + "JS/JSMinPlus.php" => "https://raw.github.com/mrclay/minify/master/min/lib/JSMinPlus.php", + "CSS/Compressor.php" => "https://raw.github.com/mrclay/minify/master/min/lib/Minify/CSS/Compressor.php", + "CSS/UriRewriter.php" => "https://raw.github.com/mrclay/minify/master/min/lib/Minify/CSS/UriRewriter.php", + "CommentPreserver.php" => "https://raw.github.com/mrclay/minify/master/min/lib/Minify/CommentPreserver.php", +); + +foreach( $sources as $path => $url ) { + echo "$path => $url\n"; + $contents = file_get_contents( $url ); + file_put_contents( $path, $contents ) || exit( 1 ); + system( sprintf( 'git add %s', escapeshellarg( $path ) ) ); +} From 4fbe1b1bc387117701e138fd5d435e7b6de6e0bc Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Thu, 12 Dec 2013 01:20:20 -0800 Subject: [PATCH 3/5] Fix expire and purge links The add_query_arg() function strips out [] from params --- dependency-minification.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dependency-minification.php b/dependency-minification.php index cd2bbf1..73f679d 100644 --- a/dependency-minification.php +++ b/dependency-minification.php @@ -398,7 +398,7 @@ static function admin_page() { $_link_params = $link_params; $_link_params['depmin_task'] = 'purge'; ?> - + @@ -413,14 +413,14 @@ static function admin_page() { $_link_params = $link_params; $_link_params['depmin_task'] = 'expire'; ?> - | + | - | + | @@ -431,7 +431,7 @@ static function admin_page() { $_link_params = $link_params; $_link_params['depmin_task'] = 'purge'; ?> - + From c579d699e9ba9facdeee721675e51930c0c6f839 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Thu, 12 Dec 2013 01:41:22 -0800 Subject: [PATCH 4/5] Bump version to 0.9.8 --- dependency-minification.php | 2 +- readme.md | 10 ++++++++-- readme.txt | 8 +++++++- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/dependency-minification.php b/dependency-minification.php index 73f679d..bd2e385 100644 --- a/dependency-minification.php +++ b/dependency-minification.php @@ -2,7 +2,7 @@ /** * Plugin Name: Dependency Minification * Description: Concatenates and minifies scripts and stylesheets. Please install and activate scribu's Proper Network Activation plugin before activating this plugin network-wide. - * Version: 0.9.7 + * Version: 0.9.8 * Author: X-Team * Author URI: http://x-team.com/wordpress/ * Text Domain: dependency-minification diff --git a/readme.md b/readme.md index e4b4591..52d467d 100644 --- a/readme.md +++ b/readme.md @@ -6,7 +6,7 @@ Automatically concatenates and minifies any scripts and stylesheets enqueued usi **Contributors:** [x-team](http://profiles.wordpress.org/x-team), [westonruter](http://profiles.wordpress.org/westonruter), [fjarrett](http://profiles.wordpress.org/fjarrett), [kucrut](http://profiles.wordpress.org/kucrut), [shadyvb](http://profiles.wordpress.org/shadyvb), [alex-ye](http://profiles.wordpress.org/alex-ye), [c3mdigital](http://profiles.wordpress.org/c3mdigital), [lkraav](http://profiles.wordpress.org/lkraav) **Tags:** [performance](http://wordpress.org/plugins/tags/performance), [dependencies](http://wordpress.org/plugins/tags/dependencies), [minify](http://wordpress.org/plugins/tags/minify), [concatenate](http://wordpress.org/plugins/tags/concatenate), [compress](http://wordpress.org/plugins/tags/compress), [js](http://wordpress.org/plugins/tags/js), [javascript](http://wordpress.org/plugins/tags/javascript), [scripts](http://wordpress.org/plugins/tags/scripts), [css](http://wordpress.org/plugins/tags/css), [styles](http://wordpress.org/plugins/tags/styles), [stylesheets](http://wordpress.org/plugins/tags/stylesheets), [gzip](http://wordpress.org/plugins/tags/gzip), [yslow](http://wordpress.org/plugins/tags/yslow), [pagespeed](http://wordpress.org/plugins/tags/pagespeed), [caching](http://wordpress.org/plugins/tags/caching) **Requires at least:** 3.5 -**Tested up to:** 3.6.1 +**Tested up to:** 3.8 **Stable tag:** trunk (master) **License:** [GPLv2 or later](http://www.gnu.org/licenses/gpl-2.0.html) @@ -50,10 +50,16 @@ If you are using Nginx with the default Varying Vagrant Vagrants config, you'll log_not_found off; } -[![Build Status](https://travis-ci.org/x-team/wp-dependency-minification.png)](https://travis-ci.org/x-team/wp-dependency-minification) +[![Build Status](https://travis-ci.org/x-team/wp-dependency-minification.png?branch=master)](https://travis-ci.org/x-team/wp-dependency-minification) ## Changelog ## +### 0.9.8 ### +* Fix rewrite rule broken by filtering home_url ([#49](https://github.com/x-team/wp-dependency-minification/pull/49)). Props [c3mdigital](http://profiles.wordpress.org/c3mdigital/). + * Switch from JSMin to JSMinPlus due to repeated issues with JSMin causing execution timeouts. + * Update plugin to indicate WordPress 3.8 compatibility. + * Fix expire and purge links. + ### 0.9.7 ### Improve how the plugin guesses the sources' absolute paths ([#34](https://github.com/x-team/wp-dependency-minification/pull/34)). Props [alex-ye](http://profiles.wordpress.org/alex-ye/). diff --git a/readme.txt b/readme.txt index 2b3752a..c7a394b 100644 --- a/readme.txt +++ b/readme.txt @@ -1,7 +1,7 @@ === Dependency Minification === Contributors: X-team, westonruter, fjarrett, kucrut, shadyvb, alex-ye, c3mdigital, lkraav Tags: performance, dependencies, minify, concatenate, compress, js, javascript, scripts, css, styles, stylesheets, gzip, yslow, pagespeed, caching -Tested up to: 3.6.1 +Tested up to: 3.8 Requires at least: 3.5 Stable tag: trunk License: GPLv2 or later @@ -52,6 +52,12 @@ If you are using Nginx with the default Varying Vagrant Vagrants config, you'll == Changelog == += 0.9.8 = + * Fix rewrite rule broken by filtering home_url ([#49](https://github.com/x-team/wp-dependency-minification/pull/49)). Props [c3mdigital](http://profiles.wordpress.org/c3mdigital/). + * Switch from JSMin to JSMinPlus due to repeated issues with JSMin causing execution timeouts. + * Update plugin to indicate WordPress 3.8 compatibility. + * Fix expire and purge links. + = 0.9.7 = Improve how the plugin guesses the sources' absolute paths ([#34](https://github.com/x-team/wp-dependency-minification/pull/34)). Props [alex-ye](http://profiles.wordpress.org/alex-ye/). From af44719cab5fcb9e00355a352fbd6e6dd9c5ada0 Mon Sep 17 00:00:00 2001 From: rusutaku Date: Thu, 6 Feb 2014 09:59:22 +0900 Subject: [PATCH 5/5] Add 'print_manifest' option. default: true. --- dependency-minification.php | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/dependency-minification.php b/dependency-minification.php index bd2e385..21966d5 100644 --- a/dependency-minification.php +++ b/dependency-minification.php @@ -59,6 +59,7 @@ static function setup() { 'admin_page_capability' => 'edit_theme_options', 'show_error_messages' => ( defined( 'WP_DEBUG' ) && WP_DEBUG ), 'disable_if_wp_debug' => true, + 'print_manifest' => true, ), self::$options ) ); @@ -866,13 +867,15 @@ static function minify( $cached ) { $contents = ''; // Print a manifest of the dependencies - $contents .= sprintf("/*! This minified dependency bundle includes:\n"); - $i = 0; - foreach ( $srcs as $src ) { - $i += 1; - $contents .= sprintf( " * %02d. %s\n", $i, $src ); + if ( self::$options['print_manifest'] ) { + $contents .= sprintf("/*! This minified dependency bundle includes:\n"); + $i = 0; + foreach ( $srcs as $src ) { + $i += 1; + $contents .= sprintf( " * %02d. %s\n", $i, $src ); + } + $contents .= sprintf(" */\n\n"); } - $contents .= sprintf(" */\n\n"); // Minify // Note: semicolon needed in case a file lacks trailing semicolon