#!/usr/bin/env php 'start', 'p' => 'patch', 'r' => 'revert', 'u' => 'update', 'x' => 'kill', ); if ( $argv[1] ) { run( $argv[1] ); } else { echo "Hi! Do you have a command for me?\n"; echo "\n"; foreach ( $COMMANDS_INFO as $key => $value ) { echo " ($key) $value\n"; } echo " "; $opt = listen_char(); echo "\n\n"; run( $commands[ $opt ] ); } function run( $command ) { global $argv; if ( function_exists( 'command_' . $command ) ) { call_user_func_array( 'command_' . $command, $argv ); echo "\n"; } } // ******************************************************************************** // Commands function command_start() { global $INSTALL_FOLDER_NAME; $install_done = true; echo "Checking Apache... \n"; $install_done = $install_done & install_osx_apache(); echo "Checking MySQL... \n"; $install_done = $install_done & install_osx_mysql(); echo "Checking SVN... \n"; $install_done = $install_done & install_osx_svn(); echo "Checking WordPress... \n"; $install_done = $install_done & install_osx_wordpress( $INSTALL_FOLDER_NAME ); // Launch! if ( $install_done == true ) { run_servers(); } } function command_kill() { global $INSTALL_FOLDER_NAME; if ( file_exists( 'wp-blog-header.php' ) ) { echo "To uninstall, go in the '" . $INSTALL_FOLDER_NAME . "' parent directory first."; } else { echo "Uninstalling '$INSTALL_FOLDER_NAME'...\n"; if ( file_exists( $INSTALL_FOLDER_NAME . '/wp-blog-header.php' ) ) { exec_simple( 'rm -rf ' . $INSTALL_FOLDER_NAME, 'Uninstall complete', 'Uninstall failed' ); } else { echo " * Nothing to uninstall. All already clear."; } } } function command_revert() { global $PATCH_FILE_NAME; echo "Reverting to original...\n"; // Remove patch if present if ( file_exists( $PATCH_FILE_NAME ) ) { @exec_simple( 'rm ' . $PATCH_FILE_NAME, 'Patch cleared', 'Failing removing patch' ); } // Revert SVN if ( exec_simple( 'svn revert -R .', 'WordPress TRUNK reverted to original', 'WordPress TRUNK revert failed, please reinstall (kill+start)' ) ) { @exec( 'svn info | grep Revision\:', $exec_output_array, $exec_return ); echo " " . $exec_output_array[0]; echo "\n"; // Ask for unversioned files $unversioned_files = get_modified_files( '?' ); if ( ! ($unversioned_files === "") ) { echo "\nDetected these unversioned files:\n"; echo $unversioned_files; echo " (y) to cleanup unversioned files, press any other key to keep them\n "; $opt = listen_char(); echo "\n"; if ( $opt == 'y' ) { if ( exec_simple( 'svn cleanup --remove-unversioned', 'Removed unversioned files (marked with "?")', 'Failed to remove unversioned files' ) ) { return true; } } } else { return true; } } return false; } function command_update() { echo "Updating trunk...\n"; $ret = exec_simple( 'svn up', 'WordPress TRUNK updated to latest version', 'WordPress TRUNK update failed' ); if ( $ret ) { @exec( 'svn info | grep Revision\:', $exec_output_array, $exec_return ); echo " " . $exec_output_array[0]; return true; } else { return false; } } function command_patch() { global $argv, $PATCH_FILE_NAME; if ( $argv[2] ) { // Path should be: // https://core.trac.wordpress.org/raw-attachment/ticket/00000/00000.diff $url = $argv[2]; $ticket_number = ''; $patch_file = ''; $matches = []; // If parameter is just the ticket number // i.e. 00000 or 00000.2 if ( preg_match( '#^([0-9]+)(\.([0-9]+))?$#', $url, $matches ) ) { $ticket_number = $matches[1]; $patch_file = $ticket_number; if ( sizeof( $matches ) >= 4 ) $patch_file += '.' . $matches[3]; $url = "https://core.trac.wordpress.org/raw-attachment/ticket/$ticket_number/$patch_file.diff"; } // If parameter is the full URL of the ticket // i.e. https://core.trac.wordpress.org/ticket/00000 if ( preg_match( '#^https://core\.trac\.wordpress\.org/ticket/([0-9]+)#', $url, $matches ) ) { $ticket_number = $matches[1]; $patch_file = $ticket_number; // Defaults to the first one, as we can't know from the base URL $url = "https://core.trac.wordpress.org/raw-attachment/ticket/$ticket_number/$patch_file.diff"; } // If parameter is Trac attachment page // i.e. https://core.trac.wordpress.org/attachment/ticket/00000/00000.2.diff if ( preg_match( '#^https://core\.trac\.wordpress\.org/attachment/ticket/([0-9]+)/(.+)\.diff$#', $url, $matches ) ) { $ticket_number = $matches[1]; $patch_file = $matches[2]; $url = "https://core.trac.wordpress.org/raw-attachment/ticket/$ticket_number/$patch_file.diff"; } echo "Retrieving patch '$ticket_number/$patch_file.diff'...\n"; echo "$url\n"; if ( exec_simple( 'curl -o ' . $PATCH_FILE_NAME . ' ' . $url . ' 2>&1', 'Download complete', 'Download failed' ) ) { // Detect if patch is from develop repository (with 'src/') or normal core repository $path_level = '0'; if( strpos( file_get_contents( $PATCH_FILE_NAME ), '+++ src/') !== false ) { $path_level = '1'; } if ( exec_simple( 'patch -p' . $path_level . ' < ' . $PATCH_FILE_NAME, 'Patch succeeded', 'Patch failed' ) ) { // Let's show which files were changed echo get_modified_files(); } else { echo "\n"; echo "To see the error, try to run: patch -p$path_level <$PATCH_FILE_NAME"; } } } else { echo "No patch to install. Please execute on command line: wpdo patch [URL]"; } } function command_prepare() { echo "#TODO: prepare patch for upload."; // svn diff > 00000.patch } // ******************************************************************************** // Script Installation function command_install() { global $SYSTEM_INSTALLED_NAME; global $SYSTEM_INSTALL_PATH; global $COMMANDS_INFO; if ( __FILE__ != $SYSTEM_INSTALL_PATH ) { if ( file_exists( $SYSTEM_INSTALL_PATH ) ) { echo "File already exists at '" . $SYSTEM_INSTALL_PATH ."'\n"; echo "The file shouldn't be present for this script to continue.\n"; } else { if ( copy( __FILE__, $SYSTEM_INSTALL_PATH ) ) { if ( chmod( $SYSTEM_INSTALL_PATH, 0755 ) ) { echo "Script installed.\n"; echo "\n"; echo "Now you can run wpdo from command line, for example:\n"; foreach ( $COMMANDS_INFO as $key => $value ) { echo " wpdo $value\n"; } // Extra cleanup if ( ( basename( __FILE__ ) != $SYSTEM_INSTALLED_NAME ) && !unlink( __FILE__ ) ) { echo "Unable to delete after installation '" . __FILE__ . "'\n"; } } else { echo "Script was copied to '" . $SYSTEM_INSTALL_PATH . "'\n"; echo "However it wasn't possible to set it executable.\n"; } } else { echo "Unable to install script to '" . $SYSTEM_INSTALL_PATH ."'\n"; echo "Check if path exists and try again.\n"; } } } else { echo "Script already running from install location.\n"; } } function command_uninstall() { global $SYSTEM_INSTALL_PATH; if ( unlink( $SYSTEM_INSTALL_PATH ) ) { echo "Script fully uninstalled.\n"; } else { echo "Unable to uninstall '" . $SYSTEM_INSTALL_PATH . "'\n"; } } // ******************************************************************************** // Support functions function install_osx_apache() { return exec_simple( 'httpd -v 2>&1 2>&1', 'Apache installed', 'Needs to install Apache' ); } function install_osx_mysql() { return exec_simple( 'mysql --version 2>&1', 'MySQL installed', 'You need to install MySQL: http://dev.mysql.com/downloads/' ); } function install_osx_svn() { return exec_simple( 'svn --version 2>&1', 'SVN installed', 'You need to install SVN. Install XCode from the Mac App Store (big) then run `xcode-select --install`.' ); } function install_osx_wordpress( $install_path ) { // Requires SVN @exec( 'svn --version 2>&1', $exec_output_array, $exec_return ); if ( $exec_return == 0 ) { // Safety check from inside existing WP if ( file_exists( './wp-blog-header.php' ) ) { echo " - You're already inside a WordPress installation. Skipping.\n"; return true; } // Create folder if it doesn't exist if ( !file_exists( $install_path ) ) { echo " + Folder '" . $install_path . "' created.\n"; mkdir( $install_path, 0777, true ); } // Install WP from SVN if ( !file_exists( $install_path . '/wp-blog-header.php' ) ) { echo " > Downloading WordPress TRUNK.\n"; return exec_simple( 'svn co https://core.svn.wordpress.org/trunk/ ' . $install_path, 'Download complete', 'Download failed' ); } else { echo " + WordPress already installed at '" . $install_path . "'.\n"; return true; } } } function run_servers() { echo "Starting servers... \n"; $ret = exec_simple( 'sudo apachectl start 2>&1', 'Apache running', 'Apache failed' ); if ( $ret ) { $url = 'http://localhost/'; exec_simple( 'open ' . $url, 'Opened ' . $url . ' in your browser', 'Failed to open ' . $url . ' in your browser' ); } } function get_modified_files( $filter_flags = 'ADMRC?!~' ) { $out = ""; @exec( 'svn status', $exec_output_array, $exec_return ); foreach ( $exec_output_array as $line ) { if ( preg_match( '#[' . $filter_flags . ']+\s{2,7}#', $line ) && ( strpos( $line, '_wpdo_downloaded.patch' ) === false ) ) { $out .= "$line\n"; } } return $out; } // ******************************************************************************** // Tools function listen_char() { readline_callback_handler_install('', function() { }); while (true) { $r = array(STDIN); $w = NULL; $e = NULL; $n = stream_select($r, $w, $e, null); if ($n && in_array(STDIN, $r)) { $c = stream_get_contents(STDIN, 1); echo $c; return $c; } } } function exec_simple( $bash_command, $msg_ok = 'Ok', $msg_no = 'Nope' ) { @exec( $bash_command, $exec_output_array, $exec_return ); if ( $exec_return == 0 ) { echo " + $msg_ok\n"; return true; } else { echo " - $msg_no\n"; return false; } }