示例#1
0
文件: Plugin.php 项目: dxw/whippet
 public function upgrade($upgrade_plugin = '')
 {
     $this->deprecationNotice(true);
     $this->whippet_init();
     $this->load_plugins_manifest();
     $this->load_plugins_lock();
     //
     //  1. Find the plugin we're going to update.
     //  2. Check it out
     //  3. Update the lockfile
     //
     foreach ($this->plugins_manifest as $dir => $plugin) {
         // Upgrade the plugin if:
         //  - It is the plugin they asked for
         //  - They didn't specify a plugin, and this plugin is in the manifest.
         if ($dir == $upgrade_plugin || $upgrade_plugin == '' && isset($this->plugins_manifest->{$dir})) {
             $git = new \Dxw\Whippet\Git\Git("{$this->plugin_dir}/{$dir}");
             // Find the specified revision.
             echo "[Checking {$dir}] ";
             $git->fetch();
             // Check it out
             if (!$git->checkout($git->remote_revision_commit($plugin->revision))) {
                 die;
             }
             if (!$git->submodule_update()) {
                 die;
             }
             // If we were upgrading a specific plugin, bail now
             if ($upgrade_plugin != '') {
                 break;
             }
         }
     }
     $this->update_plugins_lock();
 }
示例#2
0
文件: generate.php 项目: dxw/whippet
 function generate()
 {
     $old = $this->options->old;
     $new = $this->options->new;
     if (!file_exists($old)) {
         echo "Unable to find directory: {$old}\n";
     }
     if (!file_exists($new)) {
         echo "Unable to find directory: {$new}\n";
     }
     // TODO: sanity checks
     //  Does $old look like a wp-content?
     //  Does $new look like a whippet app?
     //  Are they both git repos?
     $git = new \Dxw\Whippet\Git\Git($old);
     //
     // 1.   Get a list of all the submodules. Add entries for any that are wordpress-plugins/whatever.
     // 2. Copy over all the themes
     // 3.   Copy over all plugins that aren't submodules
     //      * Ignore index.php
     //      * Warn about plugin files that are not in a directory
     //      * List all plugins copied into the app.
     // 4.   Ignoring plugins, are there any other submodules? If so, recreated them (in the right place)
     // 5. Copy over whippet-wp-config.php, if it exists
     // 6. List all files that are not dealt with by the above, and prompt user to deal with them.
     //    Don't worry about:
     //      * uploads
     //      * DS_Store
     //      * ...?
     // 7. Summarise what happened to the plugins. For each:
     //    * Was it put in Plugins or copied directly?
     //    * Was it in its own directory? (can we do that automagically?)
     //    * If it's copied directly, does a similar-looking repo exist?
     //    * Is there an inspection for the plugin, and if so, what's the result?
     //
     //
     // Check that all submodules are well formed
     //
     echo "Loading submodules\n";
     $submodules = $git->submodule_status();
     foreach ($submodules as $submodule_dir => $submodule) {
         if (!empty($submodule->status)) {
             echo "Submodule {$submodule->dir} has unmerged changes, is uninitialised, or is not on the index commit. Aborting.\n";
             exit(1);
         }
     }
     //
     // Fetch all the files, plugins and themes from the old project, and work out which are submoduled
     //
     echo "Loading plugins\n";
     $plugins = $this->get_plugins("{$old}/plugins");
     echo "Loading themes\n";
     $themes = $this->get_themes("{$old}/themes");
     echo "Loading everything else\n";
     $other_files = $this->get_rogue_files($old, $plugins, $themes);
     // Find out which ones are submoduled
     // No need to worry about themes here, because they're not whippet managed. They're dealt with below.
     echo "Looking for Whippet manageable plugins\n";
     foreach ($plugins as $plugin_file => $plugin_data) {
         foreach ($submodules as $submodule_dir => $submodule) {
             // If it looks like a theme, make a note of that for later
             if (dirname($submodule->dir) == "themes") {
                 $submodule->theme_dir = basename($submodule->dir);
             }
             // From this point on, we only want plugins
             if (dirname($submodule->dir) != 'plugins' || dirname($plugin_file) != basename($submodule->dir)) {
                 continue;
             }
             $plugins[$plugin_file]['is_submodule'] = isset($submodule->remotes['origin']) && preg_match('/^git@git\\.dxw\\.net:wordpress-plugins\\//', $submodule->remotes['origin']);
             $submodules[$submodule_dir]->plugin_file = $plugin_file;
         }
     }
     //
     // Add submoduled plugins to Plugins file. Remove those submodule & plugin entries.
     //
     // Always start with a fresh file
     // Whippet init adds akismet (as it is part of the WP distro) but we only want it now if it's in $old
     file_put_contents("{$new}/plugins", "source = \"git@git.dxw.net:wordpress-plugins/\"\n");
     echo "Updating Plugins file\n";
     foreach ($plugins as $plugin_file => $plugin_data) {
         if (!isset($plugin_data['is_submodule']) || !$plugin_data['is_submodule']) {
             continue;
         }
         $plugin_dir = dirname($plugin_file);
         file_put_contents("{$new}/plugins", "{$plugin_dir}=\n", FILE_APPEND);
         unset($plugins[$plugin_file]);
         unset($submodules["plugins/{$plugin_dir}"]);
         $this->automatic_fixes[] = "Added plugin {$plugin_dir} to the Plugins file";
     }
     //
     // Check non-Whippet-managed plugins so we can warn if they are on directory or in auto-wordpress
     //
     $available_plugins = file(dirname(__FILE__) . "/share/available-plugins");
     echo "Sanity-checking left over plugins\n";
     foreach ($plugins as $plugin_file => $plugin_data) {
         if (array_search(dirname($plugin_file) . "\n", $available_plugins) !== false) {
             $this->manual_fixes[] = "Non-whippet-managed plugin is available in git: {$plugin_file}. Should it be Whippet-managed?";
         } else {
             $plugin_slug = dirname($plugin_file);
             if ($plugin_slug == '.') {
                 $plugin_slug = preg_replace("/\\.php\$/", '', $plugin_file);
             }
             $directory_headers = get_headers("http://www.wordpress.org/plugins/{$plugin_slug}/");
             if (preg_match('/200 OK/', $directory_headers[0])) {
                 $this->manual_fixes[] = "Non-whippet-managed plugin might be available on the Directory: " . dirname($plugin_file);
             }
         }
     }
     //
     // Re-add submodules that are left-over, and if any are plugins, remove the matching plugin entry
     //
     echo "Adding submodules\n";
     foreach ($submodules as $dir => $submodule) {
         if (count($submodule->remotes['origin']) != 1) {
             $this->manual_fixes[] = "Skipped submodule {$submodule->dir}, because it does not have exactly 1 remote. You'll need to manually add the one you want.";
             unset($submodules[$dir]);
             continue;
         }
         $remote = array_pop($submodule->remotes);
         if (!empty($submodule->theme_dir)) {
             if (!$this->is_parent_theme($themes[$submodule->theme_dir]) && array_search($submodule->theme_dir, array("twentyten", "twentyeleven", "twentytwelve", "twentythirteen", "twentyfourteen")) !== false) {
                 $this->manual_fixes[] = "Refusing to submodule a default theme from {$remote} at wp-content/{$submodule->dir}. Add a submodule for this theme manually if it is required.";
                 unset($submodules[$dir]);
                 unset($themes[$submodule->theme_dir]);
                 continue;
             } else {
                 if ($this->is_parent_theme($themes[$submodule->theme_dir])) {
                     $this->manual_fixes[] = "Submoduled a default theme from {$remote} at wp-content/{$submodule->dir}, because it is a parent of: " . implode(', ', $themes[$submodule->theme_dir]['children']);
                 }
             }
         }
         $git = new \Dxw\Whippet\Git\Git($new);
         if (!$git->submodule_add($remote, "wp-content/" . $submodule->dir)) {
             // This error will be added to manual fixes later, by seeing if anything is left over in $submodules.
             continue;
         }
         if (strpos($remote, "*****@*****.**") === false) {
             $this->manual_fixes[] = "Non-dxw git repo submoduled: {$remote} at {$submodule->dir}";
         }
         if (isset($submodule->plugin_file)) {
             unset($plugins[$submodule->plugin_file]);
             $this->automatic_fixes[] = "Submoduled plugin from {$remote} at: wp-content/" . $submodule->dir;
         } else {
             if (isset($submodule->theme_dir)) {
                 unset($themes[$submodule->theme_dir]);
                 $this->automatic_fixes[] = "Submoduled theme from {$remote} at: wp-content/" . $submodule->dir;
             } else {
                 $this->automatic_fixes[] = "Submodule added at: wp-content/" . $submodule->dir;
             }
         }
         unset($submodules[$dir]);
     }
     //
     // Copy over any plugins that are left over
     //
     echo "Copying project plugins\n";
     foreach ($plugins as $plugin_file => $plugin_data) {
         if (dirname($plugin_file) != '.') {
             $this->recurse_copy("{$old}/plugins/" . dirname($plugin_file), "{$new}/wp-content/plugins/" . dirname($plugin_file));
             $this->automatic_fixes[] = "Copied plugin directory " . dirname($plugin_file) . " into the project";
         } else {
             $this->recurse_copy("{$old}/plugins/{$plugin_file}", "{$new}/wp-content/plugins");
             $this->automatic_fixes[] = "Copied plugin file {$plugin_file} into the project";
         }
         unset($plugins[$plugin_file]);
     }
     //
     // Copy over any themes that are left over
     //
     echo "Copying project themes\n";
     foreach ($themes as $theme_dir => $theme_data) {
         if (!$this->is_parent_theme($theme_data) && array_search($theme_dir, array("twentyten", "twentyeleven", "twentytwelve", "twentythirteen", "twentyfourteen")) !== false) {
             $this->manual_fixes[] = "Refusing to copy a default theme into the project: {$theme_dir}. Copy it manually if you need it.";
             unset($themes[$theme_dir]);
             continue;
         } else {
             if ($this->is_parent_theme($theme_data)) {
                 $this->manual_fixes[] = "Copied theme directory {$theme_dir} into the project, because it is a parent of: " . implode(', ', $theme_data['children']);
             }
         }
         $new_theme_dir = "{$new}/wp-content/themes/" . dirname($theme_dir);
         if (!file_exists($new_theme_dir)) {
             mkdir("{$new_theme_dir}", 0755, true);
             // For themes within subdirs
         }
         $this->recurse_copy("{$old}/themes/{$theme_dir}", "{$new_theme_dir}/{$theme_dir}");
         $this->automatic_fixes[] = "Copied theme directory {$theme_dir} into the project";
         unset($themes[$theme_dir]);
     }
     //
     // Check that we don't have any themes, plugins or submodules left over.
     //
     echo "Checking for unhandled plugins, themes and submodules\n";
     // Make sure there's nothing left
     foreach ($plugins as $plugin_file => $plugin_data) {
         $this->manual_fixes[] = "Plugin {$plugin_file} was not migrated";
     }
     foreach ($themes as $theme_dir => $theme_data) {
         $this->manual_fixes[] = "Plugin {$theme_dir} was not migrated";
     }
     foreach ($submodules as $submodule_dir => $submodule) {
         $this->manual_fixes[] = "Submodule {$submodule_dir} was not migrated";
     }
     //
     // If there are language files, copy them
     //
     if (file_exists("{$old}/languages")) {
         echo "Copying language files\n";
         mkdir("{$new}/wp-content/languages/");
         foreach (glob("{$old}/languages/*.mo") as $file) {
             copy($file, "{$new}/wp-content/languages/{$file}");
         }
         $this->automatic_fixes[] = "Copied language directory into the project";
     }
     //
     // What happened?
     //
     $results = "";
     $results .= "\n\nApplied these automatic fixes:\n";
     $results .= "==============================\n";
     foreach ($this->automatic_fixes as $fix) {
         $results .= "  {$fix}\n";
     }
     $results .= "\n\nNotices/possible manual fixes:\n";
     $results .= "==============================\n";
     if (!count($this->manual_fixes)) {
         $results .= "  None.\n";
     } else {
         foreach ($this->manual_fixes as $fix) {
             $results .= "  {$fix}\n";
         }
     }
     $results .= "\n\nLeft-over files:\n";
     $results .= "================\n";
     if (!count($other_files)) {
         $results .= "  None.\n";
     } else {
         foreach ($other_files as $file) {
             $results .= "  {$file}\n";
         }
     }
     file_put_contents("{$new}/migration.log", $results);
     echo $results;
 }
示例#3
0
 /**
  * Updates plugins.lock based on the contents of the current plugins manifest.
  *
  * This method works because $this->plugins_manifest is updated as Whippet carries out plugin installations, updates and deletions.
  */
 private function update_plugins_lock()
 {
     if (!empty($this->plugins_locked)) {
         $this->old_plugins_locked = $this->plugins_locked;
     }
     $this->plugins_lock_file = "{$this->project_dir}/plugins.lock";
     $this->plugins_locked = new \stdClass();
     foreach (scandir($this->plugin_dir) as $dir) {
         if ($dir[0] == '.') {
             continue;
         }
         if (!isset($this->plugins_manifest->{$dir})) {
             continue;
         }
         $git = new \Dxw\Whippet\Git\Git("{$this->plugin_dir}/{$dir}");
         if (!($commit = $git->current_commit())) {
             echo "Unable to determine current commit; aborting\n";
             exit(1);
         }
         $this->plugins_locked->{$dir} = new \stdClass();
         $this->plugins_locked->{$dir}->repository = $this->plugins_manifest->{$dir}->repository;
         $this->plugins_locked->{$dir}->revision = $this->plugins_manifest->{$dir}->revision;
         $this->plugins_locked->{$dir}->commit = $commit;
     }
     return file_put_contents($this->plugins_lock_file, json_encode($this->plugins_locked, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES));
 }
示例#4
0
文件: Release.php 项目: dxw/whippet
 public function create(&$force)
 {
     //
     // Does this commit have a release directory already? If so, do nothing
     //
     if (!$force && file_exists($this->release_dir)) {
         return false;
     }
     // there's no point in forcing a non-existant release
     if ($force && !file_exists($this->release_dir)) {
         $force = false;
     }
     // Got whippet.{json,lock} or plugins.lock?
     if (is_file($this->project_dir . '/whippet.json') && is_file($this->project_dir . '/whippet.lock')) {
         $factory = new \Dxw\Whippet\Factory();
         $installer = new \Dxw\Whippet\Dependencies\Installer($factory, new \Dxw\Whippet\ProjectDirectory($this->project_dir));
     } elseif ($this->plugins_lock_file && file_exists($this->plugins_lock_file)) {
         $installer = new Plugin();
     } else {
         echo "Couldn't find plugins.lock in the project directory. (Did you run whippet plugins install?)\n";
         die(1);
     }
     //
     // If we're here, we must deploy
     //
     //    1. Clone WP
     //    2. Delete wp-content etc
     //    3. Make sure wp-content is up to date
     //    4. Copy our wp-content, omitting gitfoo
     //    5. ?? Theme/plugin build steps ?? (Makefile-esque thing?)
     //    6. Symlink required files from shared dir
     // Assuming we're not forcing, create a new directory for this release, or use only an empty existing dir
     if (!$force) {
         $this->check_and_create_dir($this->release_dir, true);
     } else {
         $this->release_dir = dirname($this->release_dir) . '/forced_release_tmp_' . sha1(microtime());
     }
     // Clone WP and remove things we don't want
     $wp = new \Dxw\Whippet\Git\Git($this->release_dir);
     $wp->clone_repo($this->application_config->wordpress->repository);
     $wp->checkout($this->application_config->wordpress->revision);
     foreach (['wp-content', '.git', 'readme.html', 'wp-config-sample.php'] as $delete) {
         if (is_dir("{$this->release_dir}/{$delete}")) {
             $this->recurse_rmdir("{$this->release_dir}/{$delete}");
         } else {
             unlink("{$this->release_dir}/{$delete}");
         }
     }
     // Make sure wp-content is up to date
     $result = $installer->install(true);
     if ($result->isErr()) {
         echo sprintf("ERROR: %s\n", $result->getErr());
         exit(1);
     }
     // Copy over wp-content
     $this->recurse_copy("{$this->project_dir}/wp-content", "{$this->release_dir}/wp-content");
     if (file_exists("{$this->release_dir}/wp-content/uploads")) {
         $this->recurse_rm("{$this->release_dir}/wp-content/uploads");
     }
     //
     // Remove unwanted git/test foo
     //
     $plugins = scandir("{$this->release_dir}/wp-content/plugins");
     foreach ($plugins as $dir) {
         $path = "{$this->release_dir}/wp-content/plugins/{$dir}";
         if ($dir === '.' || $dir === '..' || !is_dir($path)) {
             continue;
         }
         // Remove git files from all plugins
         foreach (['.git', '.gitmodules', '.gitignore'] as $delete) {
             $this->recurse_rm("{$this->release_dir}/wp-content/plugins/{$dir}/{$delete}");
         }
         // Remove test files from whippet plugins
         if ($this->is_whippet_plugin($path)) {
             foreach (['tests', 'Makefile', '.drone.yml'] as $delete) {
                 $this->recurse_rm("{$this->release_dir}/wp-content/plugins/{$dir}/{$delete}");
             }
         }
     }
     //
     // Copy public assets
     //
     if (is_dir("{$this->project_dir}/public")) {
         $this->recurse_copy("{$this->project_dir}/public", "{$this->release_dir}");
     }
     //
     // TODO: theme and plugin build steps
     //
     // Symlinkery
     symlink(realpath("{$this->release_dir}/../../shared/wp-config.php"), "{$this->release_dir}/wp-config.php");
     symlink(realpath("{$this->release_dir}/../../shared/uploads"), "{$this->release_dir}/wp-content/uploads");
     // FIN
 }