'core'); if ($core_project != 'drupal') { $projects[$core_project]['custom_download'] = TRUE; $projects[$core_project]['type'] = 'core'; } else { // Drupal core - we can determine the version if required. if (_drush_generate_track_version("drupal", $version_options)) { $projects[$core_project]["version"] = drush_drupal_version(); } } $install_profile = drush_drupal_major_version() >= 7 ? drupal_get_profile() : variable_get('install_profile', ''); if (!in_array($install_profile, array('default', 'standard', 'minimal', 'testing')) && $install_profile != '') { $projects[$install_profile]['type'] = $projects[$install_profile]['_type'] = 'profile'; $request = array( 'name' => $install_profile, 'drupal_version' => $drupal_major_version, ); if (!$release_info->checkProject($request, 'profile')) { $projects[$install_profile]['custom_download'] = TRUE; } } // Iterate installed projects to build $projects array. $extensions = $all_extensions; $project_info = drush_get_projects($extensions); foreach ($project_info as $name => $project) { // Discard the extensions within this project. At the end $extensions will // contain only extensions part of custom projects (not from drupal.org or // other update service). foreach ($project['extensions'] as $ext) { unset($extensions[$ext]); } if ($name == 'drupal') { continue; } $type = $project['type']; // Discard projects with all modules disabled. if (($type == 'module') && (!$project['status'])) { continue; } $projects[$name] = array('_type' => $type); // Check the project is on drupal.org or its own update service. $request = array( 'name' => $name, 'drupal_version' => $drupal_major_version, ); if (isset($project['status url'])) { $request['status url'] = $project['status url']; $projects[$name]['location'] = $project['status url']; } if (!$release_info->checkProject($request, $type)) { // It is not a project on drupal.org neither an external update service. $projects[$name]['type'] = $type; $projects[$name]['custom_download'] = TRUE; } // Add 'subdir' if the project is installed in a non-default location. if (isset($project['path'])) { $projects[$name] += _drush_generate_makefile_check_path($project); } // Add version number if this project's version is to be tracked. if (_drush_generate_track_version($name, $version_options) && $project["version"]) { $version = preg_replace("/^" . drush_get_drupal_core_compatibility() . "-/", "", $project["version"]); // Strip out MINOR+GIT_COMMIT strings for dev releases. if (substr($version, -4) == '-dev' && strpos($version, '+')) { $version = substr($version, 0, strrpos($version, '.')) . '.x-dev'; } $projects[$name]['version'] = $version; } foreach ($project['extensions'] as $extension_name) { _drush_make_generate_add_patch_files($projects[$name], _drush_extension_get_path($all_extensions[$extension_name])); } } // Add a project for each unknown extension. foreach ($extensions as $name => $extension) { list($project_name, $project_data) = _drush_generate_custom_project($name, $extension, $version_options); $projects[$project_name] = $project_data; } // Add libraries. if (function_exists('libraries_get_libraries')) { $libraries = libraries_get_libraries(); foreach ($libraries as $library_name => $library_path) { $path = explode('/', $library_path); $project_libraries[$library_name] = array( 'directory_name' => $path[(count($path) - 1)], 'custom_download' => TRUE, 'type' => 'library', '_type' => 'librarie', // For plural. ); } } return array($projects, $project_libraries); } /** * Record any patches that were applied to this project * per information stored in PATCHES.txt. */ function _drush_make_generate_add_patch_files(&$project, $location) { $patchfile = DRUPAL_ROOT . '/' . $location . '/PATCHES.txt'; if (is_file($patchfile)) { foreach (file($patchfile) as $line) { if (substr($line, 0, 2) == '- ') { $project['patch'][] = trim(substr($line, 2)); } } } } /** * Create a project record for an extension not downloaded from drupal.org */ function _drush_generate_custom_project($name, $extension, $version_options) { $project['_type'] = drush_extension_get_type($extension); $project['type'] = drush_extension_get_type($extension); $location = drush_extension_get_path($extension); // To start off, we will presume that our custom extension is // stored in a folder named after its project, and there are // no subfolders between the .info file and the project root. $project_name = basename($location); drush_shell_cd_and_exec($location, 'git rev-parse --git-dir 2> ' . drush_bit_bucket()); $output = drush_shell_exec_output(); if (!empty($output)) { $git_dir = $output[0]; // Find the actual base of the git repository. $repo_root = $git_dir == ".git" ? $location : dirname($git_dir); // If the repository root is at the drupal root or some parent // of the drupal root, or some other location that could not // pausibly be a project, then there is nothing we can do. // (We can't tell Drush make to download some sub-part of a repo, // can we?) if ($repo_project_name = _drush_generate_validate_repo_location($repo_root)) { $project_name = $repo_project_name; drush_shell_cd_and_exec($repo_root, 'git remote show origin'); $output = drush_shell_exec_output(); foreach ($output as $line) { if (strpos($line, "Fetch URL:") !== FALSE) { $url = preg_replace('/ *Fetch URL: */', '', $line); if (!empty($url)) { // We use the unconventional-looking keys // `download][type` and `download][url` so that // we can produce output that appears to be two-dimensional // arrays from a single-dimensional array. $project['download][type'] = 'git'; $project['download][url'] = $url; // Fill in the branch as well. drush_shell_cd_and_exec($repo_root, 'git branch'); $output = drush_shell_exec_output(); foreach ($output as $line) { if ($line{0} == '*') { $branch = substr($line, 2); if ($branch != "master") { $project['download][branch'] = $branch; } } } // Put in the commit hash. drush_shell_cd_and_exec($repo_root, 'git log'); $output = drush_shell_exec_output(); if (substr($output[0], 0, 7) == "commit ") { $revision = substr($output[0], 7); if (_drush_generate_track_version($project_name, $version_options)) { $project['download][revision'] = $revision; } } // Add patch files, if any. _drush_make_generate_add_patch_files($project, $repo_root); } } } } } // If we could not figure out where the extension came from, then give up and // flag it as a "custom" download. if (!isset($project['download][type'])) { $project['custom_download'] = TRUE; } return array($project_name, $project); } /** * 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". */ function _drush_generate_validate_repo_location($repo_root) { $project_name = basename($repo_root); // The Drupal root, or any folder immediately inside the Drupal // root cannot be a project location. if ((strlen(DRUPAL_ROOT) >= strlen($repo_root)) || (dirname($repo_root) == DRUPAL_ROOT)) { return NULL; } // Also exclude sites/* and sites/*/{modules,themes} and profile/* and // profile/*/{modules,themes}. return $project_name; } /** * Helper function to determine if a given project is to have its version * tracked. */ function _drush_generate_track_version($project, $version_options) { // A. If --exclude-versions has been specified: // A.a. if it's a boolean, check the --include-versions option. if ($version_options["exclude"] === TRUE) { // A.a.1 if --include-versions has been specified, ensure it's an array. if (is_array($version_options["include"])) { return in_array($project, $version_options["include"]); } // A.a.2 If no include array, then we're excluding versions for ALL // projects. return FALSE; } // A.b. if --exclude-versions is an array with items, check this project is in // it: if so, then return FALSE. elseif (is_array($version_options["exclude"]) && count($version_options["exclude"])) { return !in_array($project, $version_options["exclude"]); } // B. If by now no --exclude-versions, but --include-versions is an array, // examine it for this project. if (is_array($version_options["include"]) && count($version_options["include"])) { return in_array($project, $version_options["include"]); } // If none of the above conditions match, include version number by default. return TRUE; } /** * Helper function to check for a non-default installation location. */ function _drush_generate_makefile_check_path($project) { $info = array(); $type = $project['type']; $path = dirname($project['path']); // Check to see if the path is in a subdir sites/all/modules or // profiles/profilename/modules if (preg_match('@^sites/[a-zA-Z0-9_]*/' . $type . 's/..*@', $path) || preg_match('@^sites/[a-zA-Z0-9_]*/' . $type . 's/..*@', $path)) { $subdir = preg_replace(array('@^[a-zA-Z0-9_]*/[a-zA-Z0-9_]*/' . $type . 's/*@', "@/$name" . '$@'), '', $path); if (!empty($subdir)) { $info['subdir'] = $subdir; } } return $info; }