Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes #3277: Site-specific drush.yml file not loaded. #3278

Closed
wants to merge 10 commits into from

Conversation

grasmash
Copy link
Contributor

No description provided.

@greg-1-anderson
Copy link
Member

uri is often https://example.com rather than a directory name. Not sure how many existing places in Drush already make the assumption that uri is the directory name, but some modules need uri to be set to an fqdn in order to work correctly. Drush allows Drupal to do the conversion from fqdn to directory name during bootstrapping, but we may need to do some level of transformation ourselves prior to that point to support features such as this.

I don't fully remember what Drush 8 does, but I think that sitealias.inc had some provision for this.

@grasmash
Copy link
Contributor Author

@greg-1-anderson
Copy link
Member

Yeah, that's pretty minimal.

}

// We might have already processed this site.
if (in_array($uri, $this->siteUris)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should cache the directory rather than the uri?

}

// There might not be a site directory.
$site_dir = "$drupalRoot/sites/$uri";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe site dir lookup should be a method of the alias record class (bring along convertUriToHostname, lookupSiteDirFromHostname).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

n.b. I'm not sure about this - considering it. Maybe factoring out into a utility class would be better. I don't think that I want the alias record code to know about Drupal site directory conventions. Ideally the site alias classes will be factored out into a separate consolidation project.

$this->configLocator->addSitewideConfig($root);
$this->configLocator->addDrupalConfig($root);
// Set multisite config using uri from alias.
$this->configLocator->addSiteConfig($root, $selfAliasRecord);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it necessary to pass in $root here? i.e. will $root ever be different than the value held by the self alias record? If it is, wouldn't the value in the self alias be more correct?

* @return $drupalRoot
* The directory associated with that hostname.
*/
public function lookupSiteDirFromHostname($hostname, $drupalRoot) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure where this belongs. I can move to StringUtils, though it's not strictly doing string manipulation.

@grasmash grasmash force-pushed the issue-3277-site-config branch 3 times, most recently from d8c7f65 to 6292e13 Compare December 29, 2017 19:56
@@ -276,7 +276,7 @@ public function pre(CommandData $commandData)
// a fallback name when '--sites-subdir' is not specified, but
// only if the uri and the folder name match, and only if
// the sites directory has already been created.
$dir = $this->getSitesSubdirFromUri($root, $aliasRecord->get('uri'));
$dir = StringUtils::lookupSiteDirFromUri($aliasRecord->get('uri'), $root);
Copy link
Contributor Author

@grasmash grasmash Dec 29, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we fall back to 'default' if the URI does not have a matching entry in sites.php?

If I have a single site in sites/default and I have drush.yml file that sets options.uri: http://example.com, I expect drush si to install the site even if I don't have a sites.php file.

@weitzman
Copy link
Member

weitzman commented Dec 29, 2017 via email

@grasmash
Copy link
Contributor Author

Yes, I agree. My previous comment referred to setting the site directory value to default, not the URI.

Here is what I am proposing. If someone passes a fully qualified domain name as the URI value and that value does not have a corresponding directory mapping in sites.php, drush will assume that the site directory that it refers to is “default”.

@grasmash
Copy link
Contributor Author

Tbh, this detail is incidental. I’m fine with leaving that as is.

Any issues with the PR as it is?

@@ -249,7 +249,7 @@ public function preflight($argv)
// Extend configuration and alias files to include files in
// target site.
$root = $this->findSelectedSite();
$this->configLocator->addSitewideConfig($root);
$this->configLocator->addDrupalConfig($root);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In Drush8, we don't load any site specific config until the Site phase of the bootstrap. I'd like to keep consistent with that in Drush9. Since this change is in Preflight (i.e. happens before bootstrap), I dont think its properly placed.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that moving all config processing to preflight is an improvement. When config was php, delaying loading site-specific config until site bootstrap has the benefit of allowing folks to use Drupal APIs in their config code. With yaml config, I'm not sure that there is a benefit to postponing config loading. Loading config in preflight might allow folks to use --uri=foo and set URI to https://foo.example.com in their drush.yml file, to give one example.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is exactly my use case.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we are working around the problem that config is static after its loaded. It would be preferable IMO if uri were discovered during SITE phase and then used for link building and such during command execution.

We already do ROOT discovery during Preflight. This PR effectively moves SITE discovery there too. It begs the question of how much do we need the progressive Bootstrap that we do. Maybe NONE and FULL is all we need? We don't need to figure this out now but it would be good to get some clarity on future directions.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that site selection is already happening in preflight. Note the comment removed in this PR: "// not implemented yet (multisite)" (see my comment #3278 (review)). I think this PR is essentially implementing a TODO. I still don't see any practical benefit to postponing uri discovery to the SITE phase, and as previously mentioned, there are some disadvantages to doing that.

Regarding progressive bootstrap, for command discovery we only need NONE (built-in and global commands) and FULL (module commands). Built-in and global commands can also declare the bootstrap level they want, but it is not possible for them to declare their bootstrap level, because we already have to bootstrap to FULL in order to find them.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By the current design, the config locator is not available during bootstrap.

Does it not currently work to set $options['uri'] from a site-specific drushrc.php file in Drush 8 with Drupal 8?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I dont know. If so, we just accept that as a regression with known workarounds (use an alias, use site-set, specify uri on the request, ...).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I agree. While I'd like to see this feature work, I think it's enough of an edge case that I'd like the solution to be clean (keep Drupal-specific code in the bootstrap phase).

Copy link
Member

@weitzman weitzman Feb 8, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have found one more workaround. If you set the environment variable DRUSH_OPTIONS_URI=http://example.com then your custom uri will be used. No need to fuss with Drush config or aliases. For Docker/Vagrant sites, this is an easy solution.

So, how to set that env variable? If you have many sites on same host, or don't control the server, this can be challenging.

  1. Anyone used direnv?
  2. I'm using PHPEnv successfully on Drupal projects but at this time there is no way to load custom code early enough in a Drush request for 'uri' to take effect. That happens at end of Runtime https://github.com/drush-ops/drush/blob/master/src/Runtime/Runtime.php#L88-L93

I will now writeup docs for #3009 as I now understand that system.

Copy link
Member

@weitzman weitzman Mar 12, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As a follow-up, the drupal-project will soon support .env files and documents how to set DRUSH_OPTIONS_URI so that site specific works. See drupal-composer/drupal-project#351. You can implement that in your composer project even before this PR is merged.

@@ -101,7 +104,7 @@ public function __construct($envPrefix = '')
}
$this->config->addPlaceholder(self::USER_CONTEXT);
$this->config->addPlaceholder(self::DRUPAL_CONTEXT);
$this->config->addPlaceholder(self::SITE_CONTEXT); // not implemented yet (multisite)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

n.b. "not implemented yet (mulitsite)" comment.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was removed intentionally, as this PR adds site support.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I made that note for @weitzman to point out that this PR is implementing a TODO. Then I forgot to save the comment that referenced it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, it did get saved; see above.

@weitzman
Copy link
Member

So, the recommended way to get site specific config files to load is set an environment variable See #3278 (comment) and follow its links. This is now documented at https://github.com/drush-ops/drush/blob/master/examples/example.drush.yml#L26-L35

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants