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

Feature request: Configuration to ignore specific repositories (or repository hosts) #49

Open
GuySartorelli opened this issue Oct 1, 2020 · 4 comments · May be fixed by #56
Open

Feature request: Configuration to ignore specific repositories (or repository hosts) #49

GuySartorelli opened this issue Oct 1, 2020 · 4 comments · May be fixed by #56

Comments

@GuySartorelli
Copy link
Collaborator

GuySartorelli commented Oct 1, 2020

I have a situation where some private repositories are being hosted in-house, which are required for a project.
I'm not allowed to provide access to those repositories for this module to utilize, and we want to avoid clogging our internal logging whenever the repository tries to update the report for these repositories.

Ideally, we'd like to tell the module (through yaml configuration) to ignore these repositories - either on a per-repository basis or, preferably, on a per-host basis so we can just ignore all of the repositories we host internally.

I'd be happy to submit a pull request if someone can point me in the right direction of where I'd need to make changes.

Accepance criteria

  • PRs are re-targeted to CMS 5.
  • There's a way to bypass or ignore private repos.
  • Update note in Readme me to explain how to bypass private repos

PRs

@robbieaverill
Copy link
Contributor

@GuySartorelli
Copy link
Collaborator Author

Hey sorry it's been a while, I did take a crack at this but I ran into an issue I haven't been able to figure out. I'll put the diff for what I have put together below in case someone is able to see where I'm going wrong.

With the below, if the repository URL for a given package has a host which is added to the ignored_repository_hosts config array, that repository shouldn't be added to $packages and therefore shouldn't be returned by getPackages.
I can confirm that much is working - the correct repositories are excluded from the list returned by that method.

Unfortunately for some reason it's still trying to clone the repository, which if it can't access the repository means this is in the logs:
[DEBUG] Failed to execute git clone --mirror 'SOME_REPO_URL_HERE' '/tmp/cache/vcs/SOME_REPO_NAME.git/'

@@ -12,9 +12,30 @@ use Composer\Repository\CompositeRepository;
 use Composer\Repository\RepositoryInterface;
 use SilverStripe\Core\Environment;
 use SilverStripe\Core\Extension;
+use SilverStripe\Core\Config\Config;
 
 class ComposerLoaderExtension extends Extension
 {
+    /**
+     * For http repositories:
+     * Fully qualified domain names from which any repositories should not be checked.
+     *
+     * For ssh repositories:
+     * The portion of the ssh URI after @ but before :
+     *
+     * @example
+     * for https://github.com/some-account/some-repository.git:
+     * github.com
+     *
+     * @example
+     * for [email protected]:some-stack/some-repository.git:
+     * git.cwp.govt.nz
+     *
+     * @config
+     * @var array
+     */
+    private static $ignored_repository_hosts = [];
+
     /**
      * @var Composer
      */
@@ -57,6 +78,23 @@ class ComposerLoaderExtension extends Extension
                 continue;
             }
 
+            // Filter out packages from hosts which should be ignored
+            $ignoredHosts = (array) Config::inst()->get(self::class, 'ignored_repository_hosts');
+            $sourceURL = $package->getSourceUrl();
+            if ($host = parse_url($sourceURL, PHP_URL_HOST)) {
+                if (in_array($host, $ignoredHosts)) {
+                    continue;
+                }
+            } else {
+                // Some ssh URIs aren't parsed correctly by parse_url
+                foreach ($ignoredHosts as $host) {
+                    if (preg_match('/^.+?@' . $host . ':/', $sourceURL)) {
+                        // continue outer loop
+                        continue 2;
+                    }
+                }
+            }
+
             // Find the constraint used for installation
             $constraint = $this->getInstalledConstraint($repository, $package->getName());
             $packages[$package->getName()] = [

@GuySartorelli
Copy link
Collaborator Author

GuySartorelli commented Dec 13, 2021

I've gone really into the weeds trying to figure this out, and I've found it's a result of how the VersionSelector is initalised - ultimately it ends up cloning all of the vcs repositories mentioned in composer.json. I'm trying a way to cleanly remove the repositories we want to ignore from the list that the version selector gets a hold of to help resolve this.
If I manage it, I'll raise a PR.

Edit: Though due to the nature of how this is all laid out, and the fact that composer dependencies can be pretty deeply nested, my PR will probably only support ignoring direct dependencies - or maybe 1 level of nested dependencies.

@GuySartorelli
Copy link
Collaborator Author

Looks like I've uncovered an actual defect while looking into this. I'll raise a PR and explain more there.

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