generate.contents.make.inc

  1. 8.0.x commands/make/generate.contents.make.inc
  2. 7.x commands/make/generate.contents.make.inc
  3. master commands/make/generate.contents.make.inc

Functions for the generate makefile command.

Functions

Namesort descending Description
drush_make_resolve_git_branch Resolve branch for a git-based project.
drush_make_resolve_git_refs Resolve branches and revisions for git-based projects.
drush_make_resolve_git_revision Resolve revision for a git-based project.
make_generate_from_makefile Write a makefile based on data parsed from a previous makefile.
make_generate_makefile_contents Generate makefile contents in the appropriate format.
make_generate_makefile_contents_ini Generate makefile contents in (legacy) INI format.
make_generate_makefile_contents_yaml Generate makefile contents in YAML format.
make_generate_print Print the generated makefile to the terminal, or write it to a file.
_drush_make_generate_defaults
_drush_make_generate_lines Utility function to generate the line or lines for a key/value pair in the make file.
_drush_make_generate_makefile_body
_drush_make_generate_makefile_contents Generate the actual contents of the .make file.
_make_generate_array_filter Helper function to recursively remove empty values from an array (but not '0'!).
_make_generate_array_filter_key Helper function to recursively remove elements matching a specific key from an array.

File

commands/make/generate.contents.make.inc
View source
  1. <?php
  2. /**
  3. * @file
  4. * Functions for the generate makefile command.
  5. */
  6. use Drush\Log\LogLevel;
  7. /**
  8. * Generate the actual contents of the .make file.
  9. */
  10. function _drush_make_generate_makefile_contents($projects, $libraries = array(), $core_version = NULL, $defaults = array()) {
  11. if (is_null($core_version)) {
  12. $core_version = drush_get_drupal_core_compatibility();
  13. }
  14. $header = array();
  15. $header[] = '; This file was auto-generated by drush make';
  16. $header['core'] = $core_version;
  17. $header['api'] = MAKE_API;
  18. $header[] = '';
  19. if (!empty($defaults)) {
  20. _drush_make_generate_defaults($defaults, $header);
  21. $header[] = '';
  22. }
  23. $header[] = '; Core';
  24. return _drush_make_generate_makefile_body($projects, $header) . _drush_make_generate_makefile_body($libraries);
  25. }
  26. function _drush_make_generate_makefile_body($projects, $output = array()) {
  27. $custom = FALSE;
  28. $previous_type = 'core';
  29. if (isset($projects)) {
  30. foreach ($projects as $name => $project) {
  31. $type = (isset($project['type']) && ($project['type'] == 'library')) ? 'libraries' : 'projects';
  32. if ($previous_type != $project['_type']) {
  33. $previous_type = $project['_type'];
  34. $output[] = '; ' . ucfirst($previous_type) . 's';
  35. }
  36. unset($project['_type']);
  37. if (!$project && is_string($name)) {
  38. $output[] = $type . '[] = "' . $name . '"';
  39. continue;
  40. }
  41. $base = $type . '[' . $name . ']';
  42. if (isset($project['custom_download'])) {
  43. $custom = TRUE;
  44. $output[] = '; Please fill the following out. Type may be one of get, git, bzr or svn,';
  45. $output[] = '; and url is the url of the download.';
  46. $output[$base . '[download][type]'] = '""';
  47. $output[$base . '[download][url]'] = '""';
  48. unset($project['custom_download']);
  49. }
  50. $output = array_merge($output, _drush_make_generate_lines($base, $project));
  51. $output[] = '';
  52. }
  53. }
  54. $string = '';
  55. foreach ($output as $k => $v) {
  56. if (!is_numeric($k)) {
  57. $string .= $k . ' = ' . $v;
  58. }
  59. else {
  60. $string .= $v;
  61. }
  62. $string .= "\n";
  63. }
  64. if ($custom) {
  65. drush_log(dt('Some of the properties in your makefile will have to be manually edited. Please do that now.'), LogLevel::WARNING);
  66. }
  67. return $string;
  68. }
  69. /**
  70. * Write a makefile based on data parsed from a previous makefile.
  71. *
  72. * @param $file
  73. * The path to the file to write our generated makefile to, or TRUE to
  74. * print to the terminal.
  75. * @param $makefile
  76. * A makefile on which to base our generated one.
  77. */
  78. function make_generate_from_makefile($file, $makefile) {
  79. if (!$info = make_parse_info_file($makefile)) {
  80. return drush_set_error('MAKE_GENERATE_FAILED_PARSE', dt('Failed to parse makefile :makefile.', array(':makefile' => $makefile)));
  81. }
  82. $projects = drush_get_option('DRUSH_MAKE_PROJECTS', FALSE);
  83. if ($projects === FALSE) {
  84. $projects = make_prepare_projects(FALSE, $info);
  85. if (isset($projects['contrib'])) {
  86. $projects = array_merge($projects['core'], $projects['contrib']);
  87. }
  88. }
  89. $defaults = isset($info['defaults']) ? $info['defaults'] : array();
  90. $core = current($projects);
  91. $core = $core['core'];
  92. foreach ($projects as $name => $project) {
  93. // If a specific revision was requested, do not set the version.
  94. if (!isset($project['revision'])) {
  95. $projects[$name]['version'] = isset($project['download']['full_version']) ? $project['download']['full_version'] : '';
  96. if ($project['type'] != 'core' && strpos($projects[$name]['version'], $project['core']) === 0) {
  97. $projects[$name]['version'] = substr($projects[$name]['version'], strlen($project['core'] . '-'));
  98. }
  99. }
  100. else {
  101. unset($projects[$name]['version']);
  102. }
  103. $projects[$name]['_type'] = $project['type'];
  104. if ($project['download']['type'] == 'git') {
  105. drush_make_resolve_git_refs($projects[$name]);
  106. }
  107. // Don't clutter the makefile with defaults
  108. if (is_array($defaults)) {
  109. foreach ($defaults as $type => $defs) {
  110. if ($type == 'projects') {
  111. foreach ($defs as $key => $value) {
  112. if (isset($project[$key]) && $project[$key] == $value) {
  113. unset($projects[$name][$key]);
  114. }
  115. }
  116. }
  117. }
  118. }
  119. if ($project['name'] == $name) {
  120. unset($projects[$name]['name']);
  121. }
  122. if ($project['type'] == 'module' && !isset($info[$name]['type'])) {
  123. unset($projects[$name]['type']); // Module is the default
  124. }
  125. if (!(isset($project['download']['type'])) || ($project['download']['type'] == 'pm')) {
  126. unset($projects[$name]['download']); // PM is the default
  127. }
  128. $ignore = array('build_path', 'contrib_destination', 'core', 'make_directory', 'l10n_url', 'download_type');
  129. foreach ($ignore as $key) {
  130. unset($projects[$name][$key]);
  131. }
  132. // Remove the location if it's the default.
  133. if ($projects[$name]['location'] == 'https://updates.drupal.org/release-history') {
  134. unset($projects[$name]['location']);
  135. }
  136. // Remove empty entries (e.g. 'directory_name')
  137. $projects[$name] = _make_generate_array_filter($projects[$name]);
  138. }
  139. $libraries = drush_get_option('DRUSH_MAKE_LIBRARIES', FALSE);
  140. if ($libraries === FALSE) {
  141. $libraries = isset($info['libraries']) ? $info['libraries'] : array();
  142. }
  143. if (is_array($libraries)) {
  144. foreach ($libraries as $name => $library) {
  145. $libraries[$name]['type'] = 'library';
  146. $libraries[$name]['_type'] = 'librarie';
  147. if ($library['download']['type'] == 'git') {
  148. drush_make_resolve_git_refs($libraries[$name]);
  149. }
  150. }
  151. }
  152. $contents = make_generate_makefile_contents($projects, $libraries, $core, $defaults);
  153. // Write or print our makefile.
  154. $file = $file !== TRUE ? $file : NULL;
  155. make_generate_print($contents, $file);
  156. }
  157. /**
  158. * Resolve branches and revisions for git-based projects.
  159. */
  160. function drush_make_resolve_git_refs(&$project) {
  161. if (!isset($project['download']['branch'])) {
  162. $project['download']['branch'] = drush_make_resolve_git_branch($project);
  163. }
  164. if (!isset($project['download']['revision'])) {
  165. $project['download']['revision'] = drush_make_resolve_git_revision($project);
  166. }
  167. }
  168. /**
  169. * Resolve branch for a git-based project.
  170. */
  171. function drush_make_resolve_git_branch($project) {
  172. drush_log(dt('Resolving default branch for repo at: :repo', array(':repo' => $project['download']['url'])));
  173. if (drush_shell_exec("git ls-remote %s HEAD", $project['download']['url'])) {
  174. $head_output = drush_shell_exec_output();
  175. list($head_commit) = explode("\t", $head_output[0]);
  176. drush_log(dt('Scanning branches in repo at: :repo', array(':repo' => $project['download']['url'])));
  177. drush_shell_exec("git ls-remote --heads %s", $project['download']['url']);
  178. $heads_output = drush_shell_exec_output();
  179. $branches = array();
  180. foreach ($heads_output as $key => $head) {
  181. list($commit, $ref) = explode("\t", $head);
  182. $branches[$commit] = explode("/", $ref)[2];
  183. }
  184. $branch = $branches[$head_commit];
  185. drush_log(dt('Resolved git branch to: :branch', array(':branch' => $branch)));
  186. return $branch;
  187. }
  188. else {
  189. drush_log(dt('Could not resolve branch for `:project` using git repo at :repo', array(':project' => $project['name'], ':repo' => $project['download']['url'])), 'warning');
  190. }
  191. }
  192. /**
  193. * Resolve revision for a git-based project.
  194. */
  195. function drush_make_resolve_git_revision($project) {
  196. drush_log(dt('Resolving head commit on `:branch` branch for repo at: :repo', array(':branch' => $project['download']['branch'], ':repo' => $project['download']['url'])));
  197. if (drush_shell_exec("git ls-remote %s %s", $project['download']['url'], $project['download']['branch'])) {
  198. $head_output = drush_shell_exec_output();
  199. list($revision) = explode("\t", $head_output[0]);
  200. drush_log(dt('Resolved git revision to: :revision', array(':revision' => $revision)));
  201. return $revision;
  202. }
  203. else {
  204. drush_log(dt('Could not resolve head commit for `:project` using git repo at :repo', array(':project' => $project['name'], ':repo' => $project['download']['url'])), 'warning');
  205. }
  206. }
  207. /**
  208. * Generate makefile contents in the appropriate format.
  209. */
  210. function make_generate_makefile_contents($projects, $libraries = array(), $core = NULL, $defaults = array()) {
  211. $format = drush_get_option('format', 'yaml');
  212. $func = "make_generate_makefile_contents_$format";
  213. if (function_exists($func)) {
  214. $contents = call_user_func($func, $projects, $libraries, $core, $defaults);
  215. }
  216. else {
  217. return drush_set_error('MAKE_UNKNOWN_OUTPUT_FORMAT', dt('Generating makefiles in the :format output format is not yet supported. Implement :func() to add such support.', array(':format' => $format, ':func' => $func)));
  218. }
  219. return $contents;
  220. }
  221. /**
  222. * Generate makefile contents in (legacy) INI format.
  223. */
  224. function make_generate_makefile_contents_ini($projects, $libraries, $core, $defaults) {
  225. return _drush_make_generate_makefile_contents($projects, $libraries, $core, $defaults);
  226. }
  227. /**
  228. * Generate makefile contents in YAML format.
  229. */
  230. function make_generate_makefile_contents_yaml($projects, $libraries, $core, $defaults) {
  231. $info = array(
  232. 'core' => $core,
  233. 'api' => MAKE_API,
  234. 'defaults' => $defaults,
  235. 'projects' => $projects,
  236. 'libraries' => $libraries,
  237. );
  238. $info = _make_generate_array_filter($info);
  239. $info = _make_generate_array_filter_key('_type', $info);
  240. $dumper = drush_load_engine('outputformat', 'yaml');
  241. $yaml = $dumper->format($info, array());
  242. return $yaml;
  243. }
  244. /**
  245. * Helper function to recursively remove empty values from an array (but not
  246. * '0'!).
  247. */
  248. function _make_generate_array_filter($haystack) {
  249. foreach ($haystack as $key => $value) {
  250. if (is_array($value)) {
  251. $haystack[$key] = _make_generate_array_filter($haystack[$key]);
  252. }
  253. if (empty($value) && $value !== '0') {
  254. unset($haystack[$key]);
  255. }
  256. }
  257. return $haystack;
  258. }
  259. /**
  260. * Helper function to recursively remove elements matching a specific key from an array.
  261. */
  262. function _make_generate_array_filter_key($needle, $haystack) {
  263. foreach ($haystack as $key => $value) {
  264. if ($key === $needle) {
  265. unset($haystack[$key]);
  266. }
  267. elseif (is_array($value)) {
  268. $haystack[$key] = _make_generate_array_filter_key($needle, $haystack[$key]);
  269. }
  270. }
  271. return $haystack;
  272. }
  273. /**
  274. * Print the generated makefile to the terminal, or write it to a file.
  275. *
  276. * @param $contents
  277. * The formatted contents of a makefile.
  278. * @param $file
  279. * (optional) The path to write the makefile.
  280. */
  281. function make_generate_print($contents, $file = NULL) {
  282. if (!$file) {
  283. drush_print($contents);
  284. }
  285. elseif (file_put_contents($file, $contents)) {
  286. drush_log(dt("Wrote .make file @file", array('@file' => $file)), LogLevel::OK);
  287. }
  288. else {
  289. make_error('FILE_ERROR', dt("Unable to write .make file !file", array('!file' => $file)));
  290. }
  291. }
  292. /**
  293. * Utility function to generate the line or lines for a key/value pair in the
  294. * make file.
  295. *
  296. * @param $base
  297. * The base for the configuration lines. Values will be appended to it as
  298. * [$key] = $value, or if value is an array itself it will expand into as many
  299. * lines as required.
  300. * @param $values
  301. * May be a single value or an array.
  302. * @return
  303. * An array of strings that represent lines for the make file.
  304. */
  305. function _drush_make_generate_lines($base, $values) {
  306. $output = array();
  307. if (is_array($values)) {
  308. foreach ($values as $key => $value) {
  309. $newbase = $base . '[' . $key . ']';
  310. $output = array_merge($output, _drush_make_generate_lines($newbase, $value));
  311. }
  312. }
  313. else {
  314. $output[$base] = '"' . $values . '"';
  315. }
  316. return $output;
  317. }
  318. function _drush_make_generate_defaults($defaults, &$output = array()) {
  319. $output[] = '; Defaults';
  320. foreach ($defaults as $name => $project) {
  321. $type = 'defaults';
  322. if (!$project && is_string($name)) {
  323. $output[] = $type . '[] = "' . $name . '"';
  324. continue;
  325. }
  326. $base = $type . '[' . $name . ']';
  327. $output = array_merge($output, _drush_make_generate_lines($base, $project));
  328. }
  329. }