Several problems that are somewhat interconnected and whose solutions are interdependent. Details below.

To reproduce:

  1. Install the latest Drupal 7.22, Chaos Tools, and the latest dev release of drush.
  2. Append the following to ctools.info: project status url = http://www.quietcompanymusic.com/drupal/release-history
  3. Run through each of the following commands and note expected output vs. actual.

drush pm-updatecode ctools

If a module contains submodules whose short names come before the primary module's short name alphabetically, the primary module's "project status url," defined in its .info file, will not be properly read/returned.

  • Expected output:
     Name                  Installed Version  Proposed version  Message          
     Chaos tools (ctools)  7.x-1.3            7.x-1.4           Update available
  • Actual output:
    No code updates available.

drush pm-releases ctools

This command doesn't even take into consideration the "project status url" defined in an installed module's .info file at all.

  • Expected output:
    ------- RELEASES FOR 'CTOOLS' PROJECT -------
     Release         Date         Status                 
     7.x-1.4         2013-Jul-05  Supported, Recommended 
     7.x-1.x-dev     2013-Jul-05  Development            
     7.x-1.3         2013-Apr-03  Installed
  • Actual output:
    ------- RELEASES FOR 'CTOOLS' PROJECT -------
     Release         Date         Status                                      
     7.x-1.x-dev     2013-Jul-05  Development                                 
     7.x-1.3         2013-Apr-03  Supported, Recommended, Security, Installed

drush pm-download ctools --select

This command doesn't even take into consideration the "project status url" defined in an installed module's .info file at all.

  • Expected output:
    Choose one of the available releases for ctools:
     [0]  :  Cancel                                                 
     [1]  :  7.x-1.4      -  2013-Jul-05  -  Supported, Recommended 
     [2]  :  7.x-1.x-dev  -  2013-Jul-05  -  Development            
     [3]  :  7.x-1.3      -  2013-Apr-03  -  Installed
  • Actual output:
    Choose one of the available releases for ctools:
     [0]  :  Cancel                                                                      
     [1]  :  7.x-1.x-dev  -  2013-Jul-05  -  Development                                 
     [2]  :  7.x-1.3      -  2013-Apr-03  -  Supported, Recommended, Security, Installed

drush make-generate

If a module contains a "project status url" definition in its .info file, it will not be properly reflected in the resulting projects[project_name][location] make file property.

  • Expected output:
    projects[ctools][location] = "http://www.quietcompanymusic.com/drupal/release-history"
    projects[ctools][version] = "1.3"
  • Actual output:
    projects[ctools][location] = ""
    projects[ctools][version] = "1.3"
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

iamEAP’s picture

Patches for both 6.x and 5.x.

iamEAP’s picture

+++ b/commands/pm/download.pm.incundefined
@@ -83,12 +83,13 @@ function drush_pm_download() {
-  $source = drush_get_option('source', RELEASE_INFO_DEFAULT_URL);
+  $extensions = drush_get_extensions();
   $restrict_to = drush_get_option('dev', FALSE) ? 'dev' : '';

Looks like calling this when drush isn't bootstrapped to a Drupal database causes fatals.

Adressing that in these patches. Again, 6.x and 5.x.

greg.1.anderson’s picture

Category: bug » feature

This patch doesn't make much sense to me. So, Drush will be able to correctly find the source for non-drupal.org projects that you are downloading -- but only if they have already been downloaded into the current site? drush_get_extensions() is really slow; it doesn't seem to be worth it.

iamEAP’s picture

Use-case here is for easier package management of custom modules / features that aren't suitable for distribution on drupal.org (e.g. at a large enterprise / university / other organization). If Drupal already has the info for the update URL, we should be taking advantage of it; especially since core provides this functionality in the Update module.

Some more context: https://drupal.org/project/project_src

I'm not terribly familiar with the drush codebase; is there anything more efficient at getting extension info than drush_get_extensions?

greg.1.anderson’s picture

This code is supposed to run at pm-update time? The concept seems good, but I'm not sure that the submitted patch does what it is intended to do.

Do you have any test data to run this with?

iamEAP’s picture

Status: Needs review » Needs work

Sure. I've created a private gitlab.com repo with a clone of ctools; in my private repo, I've tagged a 7.x-1.4 release, which you'll see reflected here: http://www.quietcompanymusic.com/drupal/release-history/ctools/7.x

To test functionality...

  1. Download ctools (from d.o),
  2. Add the following line to the end of ctools' .info file: project status url = http://www.quietcompanymusic.com/drupal/release-history
  3. Apply the patch in #2

You should see that drush dl ctools --select will show the custom 7.x-1.4 release.

I hadn't considered pm-update; tested it out and #2 indeed doesn't address it. I do think the end-solution should address both scenarios, though.

greg.1.anderson’s picture

I don't think the scenario in #6 is very useful, because we don't have the status url available unless the project already exists in the site. The pm-update use case would be very helpful, though; since you have updatexml for your releases, it should be possible for this to work.

You said this is supported in Drupal core, though; if the change in #6 is made, will Drupal's module update status page show new releases published at the custom project status url? I haven't tested, but it seems that if Drupal supports this, a lot of the operations required for Drush updates should already be handled.

iamEAP’s picture

Status: Needs work » Needs review

I and a few of my colleagues use drush dl to update/overwrite existing modules in place of pm-update/upc because, on sites with upwards of 50 modules, pm-update can take a minute or more to complete. I wouldn't be surprised if that behavior wasn't fairly common, regardless of codebase size.

Regardless, it would feel broken for drush dl and drush upc to affect a drupal installation differently. Imagine running upc, seeing an available update, then aborting the actual command to run drush dl instead, only to have the dl fail with a "no updates available" error (or worse, that it doesn't even think the module exists upstream).

Regarding your second point, I tested upc, and it nearly works, but I found a bug in drush_get_projects() that could break this in some situations. Opened a separate issue for that here: #2044487: drush_get_projects() does not properly load project status url in rare cases

Since upc more or less works (except that issue I noted), I'm flipping this back to needs review, since I still think making it work for dl is important, and the attached patch makes that happen / it's worth discussing.

greg.1.anderson’s picture

I think the patch presented here can be committed if pm-update also works. #2044487: drush_get_projects() does not properly load project status url in rare cases also looks good, so I am in favor of committing both of these, once they have been tested. I'll try to squeeze in time to do that, but maybe another maintainer will get to it first.

greg.1.anderson’s picture

Status: Needs review » Needs work

While I like the idea and direction here, I'm still reluctant to add the overhead of drush_get_extensions(), which loads information about all extensions, just to get some info on just one project. Also, note that this technique won't work if the project you are downloading is not enabled. Maybe that's not an issue for the use case, but I think that the performance hit is still too high.

pm-download already finds the destination where it is going to save the project. Perhaps you can use this directory to deterine if there is already an info file present, and if so, parse it with _drush_drupal_parse_info_file(). That would be much faster.

I didn't look at the code to see if this variable is available early enough, or if it would be easy enough to refactor the code so that it was, if necessary. I'd guess this should be possible, though.

iamEAP’s picture

Unfortunately, the code used to find the install destination in pm-download depends on $request['project_type'] being set (e.g. module, theme, core, profile, etc). The project type itself isn't determined until after loading the update XML.

iamEAP’s picture

Title: Drush should support "project status url" extension info property » Drush pm and make commands don't properly handle project status url
Category: feature » bug

Clarifying the title and, moving back to bugs. Update the issue summary with details shortly.

iamEAP’s picture

Issue summary: View changes

Clarifying the bugs.

iamEAP’s picture

Issue summary: View changes

Fixing markup error.

iamEAP’s picture

Status: Needs work » Needs review
FileSize
3.94 KB

Patch that takes care of all of the scenarios above. Does not take care of your performance concerns, @greg.1.anderson, but we can look at tackling that within the framework of this patch.

PS, really appreciate your quick responses and direction!

greg.1.anderson’s picture

Status: Needs review » Postponed

I think we need to commit #2044487: drush_get_projects() does not properly load project status url in rare cases first; then we can return here and see if there is a better way to find the .info file than drush_get_extensions().

greg.1.anderson’s picture

Status: Postponed » Needs review

I didn't notice that you merged these issues together. Re-opening.

greg.1.anderson’s picture

From https://drupal.org/node/2044487#comment-7658845:

I tried modifying ctools' .info file as instructed..., but could not see a 1.4 version, either on the Drupal modules page, or via pm-updatestatus with #1 applied. Clearing the cache and checking for updates manually (in the modules page in the web ui) did not help. Using Drupal 7.22. What else needs to be done?

I still need an answer to this before I can do any further testing here.

iamEAP’s picture

That should be it; I followed my instructions on a clean D7.22 install and am able to toggle back and forth by un/commenting the relevant line in the info file with no cache clears necessary.

Did you verify that you're updating the right ctools.info file (e.g. in a multisite environment)? Did you verify ctools is enabled? Did you verify drush is targeting the right site?

greg.1.anderson’s picture

Status: Needs review » Needs work

I tried again with #13. pm-download and pm-releases work fine, but I still cannot get pm-updatestatus or pm-updatecode to work.

greg.1.anderson’s picture

Status: Needs work » Reviewed & tested by the community

I tried again on another Drupal site, and pm-updatestatus / pm-updatecode worked fine.

This is all very excellent, except I still don't like the fact that pm-download will end up calling drush_get_extensions() via request_info_url(), and I don't really like that you stored this large structure into a static variable.

The later issue is minor, but is also easy to fix. Note that pm-enable does the following, at the end of its validate function:

  drush_set_context('PM_ENABLE_EXTENSION_INFO', $extension_info);
  drush_set_context('PM_ENABLE_MODULES', $modules);
  drush_set_context('PM_ENABLE_THEMES', $themes);

You could do something similar (with just the extensions) in request_info_url(), or perhaps better yet, make drush_get_extensions() cache in a context, so any client may repeatedly call drush_get_extensions(), and only take a performance hit on the first call. Note that by caching in a context instead of a static, clients can clear the cache by setting the context to an empty array. This is also sometimes done via a boolean parameter $refresh (e.g. in the case of an implementation that uses a static variable, to clear it).

I'm going to leave it up to another maintainer to decide whether any of this warrants further work, or if it should just be committed as-is, with additional performance enhancements to be handled in a future issue.

Good work on this.

moshe weitzman’s picture

Assigned: Unassigned » jonhattan

Assign to jonhattan for review

jonhattan’s picture

Status: Reviewed & tested by the community » Postponed

pm-download and other pm- commands accepts a non-drupal.org status url (or update xml) via --source option. So drush dl ctools --source=http://www.quietcompanymusic.com/drupal/release-history/ctools/7.x works, after applying the patch in #2044487: drush_get_projects() does not properly load project status url in rare cases.

Also, if a project has a custom "status url", pm-update uses it through drupal's update.module.

So the request here is to allow pm-download to use the status url of an already downloaded module.
I'm planning to introduce caching to drush_get_extensions() since I've found some problems while debugging #1989202: Infinite loop when trying to enable not available extensions and it doesn't work consistently across Drupal versions. #13 should wait till then.

An alternative to #13 would be to hook in pm-download and pass in source option if argument matches. It could be even a handy documentation example.

iamEAP’s picture

So the request here is to allow pm-download to use the status url of an already downloaded module.

This may be a slight mischaracterization; while that may be one net gain, the idea is to architect pm commands to take project status url into consideration the same way Core does:

  • Allow drush users to override anything with the --source option (already working),
  • If no explicit --source is provided, and we're in a context where project info is available, check for a status URL (what this issue is about),
  • If no status URL is set (or that info isn't available in the current context), assume the default updates.drupal.org location (already working).

In the meantime, I'll dive into the issue that this issue is waiting on.

minorOffense’s picture

Just to through one more step in that list, I'm working on #2004058: Allow default update URL to be configured in drush profile settings to match Drupal core update options and thought I'd get some feedback here (and some direction).

  • Allow drush users to override anything with the --source option (already working),
  • If no explicit --source is provided, and we're in a context where project info is available, check for a status URL (what this issue is about),
  • If no status URL is set (or that info isn't available in the current context), assume the default updates.drupal.org location (already working).

I'd propose to have a new third step where drush checks if an override for the default location has been set. Similarly to how you can change the update_fetch_url variable in drupal.

So we would have

  • Allow drush users to override anything with the --source option (already working),
  • If no explicit --source is provided, and we're in a context where project info is available, check for a status URL (what this issue is about),
  • If no status URL is set (or that info isn't available in the current context), check for an override to the default url (not yet working)
  • If no status URL is set (or that info isn't available in the current context), assume the default updates.drupal.org location (already working).

You can see in the referenced issue where I'm at, but I don't really know where it would be ideal to check for the override.

greg.1.anderson’s picture

Could #23 be done with a command-specific --source option?

$command_specific['pm-updatecode'] = array(
  'source' => 'http://my.custom.location/path',
);

Specifying --source on the commandline will override the command-specific option. You'd have to set both 'pm-updatecode' and 'pm-update'.

iamEAP’s picture

#24 seems plausible. I wonder if it would be easier to understand if we were to include @minorOffense's additional logic within the release_info_url() function from #13?

greg.1.anderson’s picture

Well, yes, but if I am understanding correctly, what we have (modified version from #13) is:

$request['status url'] = drush_get_option('source', release_info_url($name));

I think that in #24, you are suggesting that we add logic to release_info_url() to replace RELEASE_INFO_DEFAULT_URL with drush_get_option('update_fetch_url') if it is specified. However, I think that the result of this is that --source and --update_fetch_url (should be --update-fetch-url, I think) do exactly the same thing -- so I don't think that the later is actually necessary.

iamEAP’s picture

Status: Postponed » Closed (duplicate)
iamEAP’s picture

Issue summary: View changes

One more markup fix.

Nico Heulsen’s picture

Fixed issue in drush upc/up.

StatusInfoDrush.php:93

  $request = pm_parse_request($project_name, NULL, $project_name);

should be:

StatusInfoDrush.php:93

  $request = pm_parse_request($project_name, $project['status url'], $project_name);

Please review

Nico Heulsen’s picture