Index: helpinject.drush.inc
===================================================================
RCS file: helpinject.drush.inc
diff -N helpinject.drush.inc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ helpinject.drush.inc	19 Sep 2010 22:37:22 -0000
@@ -0,0 +1,187 @@
+<?php
+// $Id: $
+
+/**
+ * Implementation of hook_drush_help().
+ */
+function helpinject_drush_help($section) {
+  switch ($section) {
+    case 'drush:helpinject':
+      return dt('Generate Advanced Help files and contextual icons based on data in books.');
+  }
+}
+
+/**
+ * Implementation of hook_drush_command().
+ */
+function helpinject_drush_command() {
+  $items = array();
+
+  $items['helpinject'] = array(
+    'description' => "Generate Advanced Help files and contextual icons based on data in books.",
+    'examples' => array(
+      'drush helpinject example' => 'Add help from the book with the same human readable name to the example module.',
+      'drush helpinject --human_readable_name=Example --package_name=Examples example 21' => 'Generate a new help module from the book with nid 21.',
+      'drush helpinject --human_readable_name=Example_two --package_name=Examples --languages=fr,es example_two 22' => 'Generate a new help module from the book with nid 21, exporting French and Spanish Translations.',
+    ),
+    'arguments' => array(
+      'module' => 'Machine name of the module to generate help for. If a module by this name is installed locally, help will be added to that module. Otherwise, help will be generated as a new module.',
+      'book_ids' => 'A space delimited list of one or more book IDs to be used for help. If no book_ids are given, if there is a book with the same name as the human-readable name of the designated module, that book will be used. Otherwise, a list of available books will be returned.',
+    ),
+    'options' => array(
+      '--module_readable_name' => "The human readable name of a new module that will be generated.",
+      '--package_name' => "The package name that groups modules on the admin/build/modules page.",
+      '--languages' => "Comma delimited list of languages to be exported.",
+      '--destination' => "Directory that new module should be written into.",
+      '--backup-dir' => "Directory that existing .module and .info files should be backed up into.",
+    ),
+    'drupal dependencies' => array('helpinject'),
+    'aliases' => array('hi'),
+  );
+
+  return $items;
+}
+
+
+/**
+ * Export help and contextual links into an existing or new module.
+ */
+function drush_helpinject() {
+  if ($book_ids = func_get_args()) {
+    $module_info = array('module_base_name' => array_shift($book_ids));
+    $drupal_root = drush_get_context('DRUSH_DRUPAL_ROOT');
+ 
+    // Determine if module exists.
+    if ($filename = drush_db_result(drush_db_select('system', array('filename'), "name = :name AND type = 'module'", array(':name' => $module_info['module_base_name'])))) {
+      $directory = $drupal_root . '/' . dirname($filename);
+      $info = drupal_parse_info_file($directory . '/' . $module_info['module_base_name'] . '.info');
+      $module_info['module_readable_name'] = $info['name'];
+
+      // Back up existing module before making changes.
+      // We can't call drush_pm_version_control_backup::pre_update because
+      // that moves and we want to copy. So this code is adapted from pre_update.
+
+      // Save the date to be used in the backup directory's path name.
+      $date = date('YmdHis', $_SERVER['REQUEST_TIME']);
+
+      $backup_dir = drush_get_option('backup-dir', $drupal_root  . '/backup');
+      $backup_dir = rtrim($backup_dir, '/');
+      @drush_op('mkdir', $backup_dir, 0777);
+      $backup_dir .= '/modules';
+      @drush_op('mkdir', $backup_dir, 0777);
+      $backup_dir .= "/$date";
+      @drush_op('mkdir', $backup_dir, 0777);
+
+      $backup_dir .= '/' . $module_info['module_base_name'];
+      $exec = 'cp -r ' . $directory . ' '  . $backup_dir;
+      $copy_result = drush_op('system', $exec);
+
+      if ($copy_result === FALSE) {
+        return drush_set_error('DRUSH_PM_BACKUP_FAILED', dt('Failed to backup directory !directory to !backup_dir', array('!directory' => $directory, '!backup_dir' => $backup_dir)));
+      }
+    }
+    else {
+      $directory = pm_dl_destination('module') . $module_info['module_base_name'];
+      $module_info['module_readable_name'] = drush_get_option('module_readable_name');
+      $module_info['package_name'] = drush_get_option('package_name');
+    }
+    $languages = explode(',', drush_get_option('languages'));
+    if (empty($book_ids)) {
+      // Look for a book with the same title as the module readable name.
+      if (!empty($module_info['module_readable_name']) && $node = node_load(array('type' => 'book', 'title' => $module_info['module_readable_name']))) {
+        $book_ids[] = $node->nid;
+      }
+      else {
+        $rows = array(array(dt('Book ID'), dt('Title')));
+        $books = book_get_books();
+        foreach ($books as $nid => $book) {
+          $rows[] = array($nid, $book['title']);
+        }
+        drush_print(dt('Available books'));
+        drush_print_table($rows, TRUE);
+        return;
+      }
+    }
+    // If there is no readable name set, use the title of the first book.
+    if (empty($module_info['module_readable_name'])) {
+      $book = node_load($book_ids[0]);
+      $module_info['module_readable_name'] = strip_tags($book->title);
+    }
+    // Confirm before overwriting existing help.
+    if (is_dir($directory . '/help')) {
+      drush_print(dt('Help appears to already exist in !dir', array('!dir' => $directory)));
+      if (!drush_confirm(dt('Do you really want to continue?'))) {
+        drush_die('Aborting.');
+      }
+      else {
+        drush_delete_dir($directory . '/help');
+      }
+    }
+    // Create the module directory if necessary.
+    _drush_helpinject_create($directory);
+    $return = helpinject_get_files_data($module_info, $book_ids, $languages, $directory);
+    foreach ($return['files'] as $file) {
+      $file_directory = $directory;
+      if (isset($file['directory'])) {
+        foreach ($file['directory'] as $dir) {
+          $file_directory .= '/' . $dir;
+          _drush_helpinject_create($file_directory);
+        }
+      }
+      // The readme file is only for manual file editing, which we're automating.
+      if (!(isset($file['filename']) && $file['filename'] == 'helpinject.readme.txt')) {
+        _drush_helpinject_create($file_directory, $file);
+      }
+    }
+
+    drush_print(dt('Help information written to !directory', array('!directory' => $directory)));
+  }
+}
+
+/**
+ * Helper function to create a single file or directory.
+ *
+ * &@param $return
+ *   Array with key 'messages' for messages to be displayed.
+ * @param $directory
+ *   A directory for the file to be created in.
+ * @return
+ *   Boolean TRUE for success, FALSE for failure.
+ */
+function _drush_helpinject_create($directory, $file = NULL) {
+  if (is_null($file)) {
+    // Create the directory. Set error on failure.
+    if (!file_exists($directory)) {
+      @drush_op('mkdir', $directory);
+    }
+  }
+  else {
+    $flags = 0;
+    if (isset($file['filename'])) {
+      if ($position = strpos($file['filename'], '.additions')) {
+        $file['filename'] = substr($file['filename'], 0, $position);
+        $contents = file_get_contents($directory . '/' . $file['filename']);
+        // If the contents were added previously, skip.
+        if (strpos($contents, $file['contents'])) {
+          return;
+        }
+        // Try to add the dependency information in a suitable place in the .info file.
+        if (strpos($file['filename'], '.info')) {
+          foreach (array('dependencies', 'description') as $key) {
+            if (($position = strpos($contents, $key)) !== FALSE) {
+              $file['contents'] = substr_replace($contents, $file['contents'], $position, 0);
+            }
+          }
+        }
+        // For the .module file, append.
+        else {
+          $flags = FILE_APPEND;
+        }   
+      }
+      drush_op('file_put_contents', $directory . '/' . $file['filename'], $file['contents'], $flags);
+    }
+    elseif (isset($file['source'])) {
+      drush_op('copy', $file['source'], $directory);
+    }
+  }
+}
