generate.make.inc

  1. 8.0.x commands/make/generate.make.inc
  2. 6.x commands/make/generate.make.inc
  3. 7.x commands/make/generate.make.inc
  4. 5.x commands/make/generate.make.inc
  5. master commands/make/generate.make.inc

Functions for the generate makefile command.

Functions

Namesort descending Description
drush_make_generate Drush callback; generate makefile from the current build.
_drush_generate_custom_project Create a project record for an extension not downloaded from drupal.org
_drush_generate_makefile_check_path Helper function to check for a non-default installation location.
_drush_generate_track_version Helper function to determine if a given project is to have its version tracked.
_drush_generate_validate_repo_location If the user has checked in the Drupal root, or the 'sites/all/modules' folder into a git repository, then we do not want to confuse that location with a "project".
_drush_make_generate_add_patch_files Record any patches that were applied to this project per information stored in PATCHES.txt.
_drush_make_generate_get_version_options Create the $version_options array from the --include-versions and --exclude-versions command line options.
_drush_make_generate_projects Generate the $projects makefile array for the current site.

File

commands/make/generate.make.inc
View source
  1. <?php
  2. /**
  3. * @file
  4. * Functions for the generate makefile command.
  5. */
  6. include_once DRUSH_DRUPAL_CORE . '/includes/install.inc';
  7. include_once drupal_get_path('module', 'system') . '/system.install';
  8. include_once 'generate.contents.make.inc';
  9. /**
  10. * Drush callback; generate makefile from the current build.
  11. */
  12. function drush_make_generate($file = NULL) {
  13. $version_options = _drush_make_generate_get_version_options();
  14. $all_extensions = drush_get_extensions();
  15. list($projects, $libraries) = _drush_make_generate_projects($all_extensions, $version_options);
  16. $contents = _drush_make_generate_makefile_contents($projects, $libraries);
  17. // Write or print our makefile.
  18. make_generate_print($contents, $file);
  19. }
  20. /**
  21. * Create the $version_options array from the --include-versions and
  22. * --exclude-versions command line options.
  23. */
  24. function _drush_make_generate_get_version_options() {
  25. // What projects should we pin the versions for?
  26. // Check the command-line options for details.
  27. foreach (array("include", "exclude") as $option) {
  28. $version_options[$option] = drush_get_option("$option-versions");
  29. if ($version_options[$option] !== TRUE) {
  30. $version_options[$option] = array_filter(explode(",", $version_options[$option]));
  31. }
  32. }
  33. return $version_options;
  34. }
  35. /**
  36. * Generate the $projects makefile array for the current site.
  37. */
  38. function _drush_make_generate_projects($all_extensions, $version_options) {
  39. $release_info = drush_get_engine('release_info');
  40. $projects = array();
  41. $project_libraries = array();
  42. $system_requirements = system_requirements('runtime');
  43. // Update xml expects the drupal version to be expressed as "7.x" or "8.x"
  44. // We used to check $system_requirements['drupal']['value'], but this now
  45. // contains values such as "7.10-dev".
  46. $drupal_major_version = drush_drupal_major_version() . '.x';
  47. $core_project = strtolower($system_requirements['drupal']['title']);
  48. $projects[$core_project] = array('_type' => 'core');
  49. if ($core_project != 'drupal') {
  50. $projects[$core_project]['custom_download'] = TRUE;
  51. $projects[$core_project]['type'] = 'core';
  52. }
  53. else {
  54. // Drupal core - we can determine the version if required.
  55. if (_drush_generate_track_version("drupal", $version_options)) {
  56. $projects[$core_project]["version"] = drush_drupal_version();
  57. }
  58. }
  59. $install_profile = drush_drupal_major_version() >= 7 ? drupal_get_profile() : variable_get('install_profile', '');
  60. if (!in_array($install_profile, array('default', 'standard', 'minimal', 'testing')) && $install_profile != '') {
  61. $projects[$install_profile]['type']
  62. = $projects[$install_profile]['_type'] = 'profile';
  63. $request = array(
  64. 'name' => $install_profile,
  65. 'drupal_version' => $drupal_major_version,
  66. );
  67. if (!$release_info->checkProject($request, 'profile')) {
  68. $projects[$install_profile]['custom_download'] = TRUE;
  69. }
  70. }
  71. // Iterate installed projects to build $projects array.
  72. $extensions = $all_extensions;
  73. $project_info = drush_get_projects($extensions);
  74. foreach ($project_info as $name => $project) {
  75. // Discard the extensions within this project. At the end $extensions will
  76. // contain only extensions part of custom projects (not from drupal.org or
  77. // other update service).
  78. foreach ($project['extensions'] as $ext) {
  79. unset($extensions[$ext]);
  80. }
  81. if ($name == 'drupal') {
  82. continue;
  83. }
  84. $type = $project['type'];
  85. // Discard projects with all modules disabled.
  86. if (($type == 'module') && (!$project['status'])) {
  87. continue;
  88. }
  89. $projects[$name] = array('_type' => $type);
  90. // Check the project is on drupal.org or its own update service.
  91. $request = array(
  92. 'name' => $name,
  93. 'drupal_version' => $drupal_major_version,
  94. );
  95. if (isset($project['status url'])) {
  96. $request['status url'] = $project['status url'];
  97. $projects[$name]['location'] = $project['status url'];
  98. }
  99. if (!$release_info->checkProject($request, $type)) {
  100. // It is not a project on drupal.org neither an external update service.
  101. $projects[$name]['type'] = $type;
  102. $projects[$name]['custom_download'] = TRUE;
  103. }
  104. // Add 'subdir' if the project is installed in a non-default location.
  105. if (isset($project['path'])) {
  106. $projects[$name] += _drush_generate_makefile_check_path($project);
  107. }
  108. // Add version number if this project's version is to be tracked.
  109. if (_drush_generate_track_version($name, $version_options) && $project["version"]) {
  110. $version = preg_replace("/^" . drush_get_drupal_core_compatibility() . "-/", "", $project["version"]);
  111. // Strip out MINOR+GIT_COMMIT strings for dev releases.
  112. if (substr($version, -4) == '-dev' && strpos($version, '+')) {
  113. $version = substr($version, 0, strrpos($version, '.')) . '.x-dev';
  114. }
  115. $projects[$name]['version'] = $version;
  116. }
  117. foreach ($project['extensions'] as $extension_name) {
  118. _drush_make_generate_add_patch_files($projects[$name], _drush_extension_get_path($all_extensions[$extension_name]));
  119. }
  120. }
  121. // Add a project for each unknown extension.
  122. foreach ($extensions as $name => $extension) {
  123. list($project_name, $project_data) = _drush_generate_custom_project($name, $extension, $version_options);
  124. $projects[$project_name] = $project_data;
  125. }
  126. // Add libraries.
  127. if (function_exists('libraries_get_libraries')) {
  128. $libraries = libraries_get_libraries();
  129. foreach ($libraries as $library_name => $library_path) {
  130. $path = explode('/', $library_path);
  131. $project_libraries[$library_name] = array(
  132. 'directory_name' => $path[(count($path) - 1)],
  133. 'custom_download' => TRUE,
  134. 'type' => 'library',
  135. '_type' => 'librarie', // For plural.
  136. );
  137. }
  138. }
  139. return array($projects, $project_libraries);
  140. }
  141. /**
  142. * Record any patches that were applied to this project
  143. * per information stored in PATCHES.txt.
  144. */
  145. function _drush_make_generate_add_patch_files(&$project, $location) {
  146. $patchfile = DRUPAL_ROOT . '/' . $location . '/PATCHES.txt';
  147. if (is_file($patchfile)) {
  148. foreach (file($patchfile) as $line) {
  149. if (substr($line, 0, 2) == '- ') {
  150. $project['patches'][] = trim(substr($line, 2));
  151. }
  152. }
  153. }
  154. }
  155. /**
  156. * Create a project record for an extension not downloaded from drupal.org
  157. */
  158. function _drush_generate_custom_project($name, $extension, $version_options) {
  159. $project['_type'] = drush_extension_get_type($extension);
  160. $project['type'] = drush_extension_get_type($extension);
  161. $location = drush_extension_get_path($extension);
  162. // To start off, we will presume that our custom extension is
  163. // stored in a folder named after its project, and there are
  164. // no subfolders between the .info file and the project root.
  165. $project_name = basename($location);
  166. drush_shell_cd_and_exec($location, 'git rev-parse --git-dir 2> ' . drush_bit_bucket());
  167. $output = drush_shell_exec_output();
  168. if (!empty($output)) {
  169. $git_dir = $output[0];
  170. // Find the actual base of the git repository.
  171. $repo_root = $git_dir == ".git" ? $location : dirname($git_dir);
  172. // If the repository root is at the drupal root or some parent
  173. // of the drupal root, or some other location that could not
  174. // pausibly be a project, then there is nothing we can do.
  175. // (We can't tell Drush make to download some sub-part of a repo,
  176. // can we?)
  177. if ($repo_project_name = _drush_generate_validate_repo_location($repo_root)) {
  178. $project_name = $repo_project_name;
  179. drush_shell_cd_and_exec($repo_root, 'git remote show origin');
  180. $output = drush_shell_exec_output();
  181. foreach ($output as $line) {
  182. if (strpos($line, "Fetch URL:") !== FALSE) {
  183. $url = preg_replace('/ *Fetch URL: */', '', $line);
  184. if (!empty($url)) {
  185. // We use the unconventional-looking keys
  186. // `download][type` and `download][url` so that
  187. // we can produce output that appears to be two-dimensional
  188. // arrays from a single-dimensional array.
  189. $project['download][type'] = 'git';
  190. $project['download][url'] = $url;
  191. // Fill in the branch as well.
  192. drush_shell_cd_and_exec($repo_root, 'git branch');
  193. $output = drush_shell_exec_output();
  194. foreach ($output as $line) {
  195. if ($line{0} == '*') {
  196. $branch = substr($line, 2);
  197. if ($branch != "master") {
  198. $project['download][branch'] = $branch;
  199. }
  200. }
  201. }
  202. // Put in the commit hash.
  203. drush_shell_cd_and_exec($repo_root, 'git log');
  204. $output = drush_shell_exec_output();
  205. if (substr($output[0], 0, 7) == "commit ") {
  206. $revision = substr($output[0], 7);
  207. if (_drush_generate_track_version($project_name, $version_options)) {
  208. $project['download][revision'] = $revision;
  209. }
  210. }
  211. // Add patch files, if any.
  212. _drush_make_generate_add_patch_files($project, $repo_root);
  213. }
  214. }
  215. }
  216. }
  217. }
  218. // If we could not figure out where the extension came from, then give up and
  219. // flag it as a "custom" download.
  220. if (!isset($project['download][type'])) {
  221. $project['custom_download'] = TRUE;
  222. }
  223. return array($project_name, $project);
  224. }
  225. /**
  226. * If the user has checked in the Drupal root, or the 'sites/all/modules'
  227. * folder into a git repository, then we do not want to confuse that location
  228. * with a "project".
  229. */
  230. function _drush_generate_validate_repo_location($repo_root) {
  231. $project_name = basename($repo_root);
  232. // The Drupal root, or any folder immediately inside the Drupal
  233. // root cannot be a project location.
  234. if ((strlen(DRUPAL_ROOT) >= strlen($repo_root)) || (dirname($repo_root) == DRUPAL_ROOT)) {
  235. return NULL;
  236. }
  237. // Also exclude sites/* and sites/*/{modules,themes} and profile/* and
  238. // profile/*/{modules,themes}.
  239. return $project_name;
  240. }
  241. /**
  242. * Helper function to determine if a given project is to have its version
  243. * tracked.
  244. */
  245. function _drush_generate_track_version($project, $version_options) {
  246. // A. If --exclude-versions has been specified:
  247. // A.a. if it's a boolean, check the --include-versions option.
  248. if ($version_options["exclude"] === TRUE) {
  249. // A.a.1 if --include-versions has been specified, ensure it's an array.
  250. if (is_array($version_options["include"])) {
  251. return in_array($project, $version_options["include"]);
  252. }
  253. // A.a.2 If no include array, then we're excluding versions for ALL
  254. // projects.
  255. return FALSE;
  256. }
  257. // A.b. if --exclude-versions is an array with items, check this project is in
  258. // it: if so, then return FALSE.
  259. elseif (is_array($version_options["exclude"]) && count($version_options["exclude"])) {
  260. return !in_array($project, $version_options["exclude"]);
  261. }
  262. // B. If by now no --exclude-versions, but --include-versions is an array,
  263. // examine it for this project.
  264. if (is_array($version_options["include"]) && count($version_options["include"])) {
  265. return in_array($project, $version_options["include"]);
  266. }
  267. // If none of the above conditions match, include version number by default.
  268. return TRUE;
  269. }
  270. /**
  271. * Helper function to check for a non-default installation location.
  272. */
  273. function _drush_generate_makefile_check_path($project) {
  274. $info = array();
  275. $type = $project['type'];
  276. $path = dirname($project['path']);
  277. // Check to see if the path is in a subdir sites/all/modules or
  278. // profiles/profilename/modules
  279. if (preg_match('@^sites/[a-zA-Z0-9_]*/' . $type . 's/..*@', $path) || preg_match('@^sites/[a-zA-Z0-9_]*/' . $type . 's/..*@', $path)) {
  280. $subdir = preg_replace(array('@^[a-zA-Z0-9_]*/[a-zA-Z0-9_]*/' . $type . 's/*@', "@/$name" . '$@'), '', $path);
  281. if (!empty($subdir)) {
  282. $info['subdir'] = $subdir;
  283. }
  284. }
  285. return $info;
  286. }