Skip to content

Commit

Permalink
Allow mismatches in package names. Fixes #30
Browse files Browse the repository at this point in the history
Requiring the vendor/package to be the same as the group/project is a good
default to help prevent copy-paste errors and such.
However, in situations where the GitLab structure is simply different from
the vendor/package names, it should be possible to overwrite this behavior.
  • Loading branch information
jorygeerts authored and lemoinem committed Mar 1, 2018
1 parent 4dc995a commit 94a4a53
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 22 deletions.
5 changes: 3 additions & 2 deletions README.md
Expand Up @@ -20,9 +20,10 @@ See [example](examples/packages.json).
Simply include a composer.json in your project, all branches and tags respecting
the [formats for versions](http://getcomposer.org/doc/04-schema.md#version) will be detected.

Only requirement is that the package `name` must be equal to the path of the project. i.e.: `my-group/my-project`.
By default, the package `name` must be equal to the path of the project. i.e.: `my-group/my-project`.
This is not a design requirement, it is mostly to prevent common errors when you copy a `composer.json`
from another project without changing its name.
from another project without changing its name. To enable support for differences between package names and project
paths, set `allow_package_name_mismatch` to `true` in `confs/gitlab.ini`.

Then, to use your repository, add this in the `composer.json` of your project:
```json
Expand Down
4 changes: 4 additions & 0 deletions confs/samples/gitlab.ini
Expand Up @@ -5,6 +5,10 @@
endpoint="http://gitlab.example.com/api/v4/"
api_key="ASDFGHJKL12345678"
method="ssh"

; You can restrict to some gitlab groups:
;groups[]="one_group"
;groups[]="other_group"

; Allow package names to differ from their group/project names in GitLab
;allow_package_name_mismatch=true
65 changes: 45 additions & 20 deletions htdocs/packages.php
Expand Up @@ -48,14 +48,16 @@
define('method', 'ssh');
}

$allow_package_name_mismatches = !empty($confs['allow_package_name_mismatch']);

/**
* Retrieves some information about a project's composer.json
*
* @param array $project
* @param string $ref commit id
* @return array|false
*/
$fetch_composer = function($project, $ref) use ($repos) {
$fetch_composer = function($project, $ref) use ($repos, $allow_package_name_mismatches) {
try {
$c = $repos->getFile($project['id'], 'composer.json', $ref);

Expand All @@ -65,7 +67,7 @@

$composer = json_decode(base64_decode($c['content']), true);

if (empty($composer['name']) || strcasecmp($composer['name'], $project['path_with_namespace']) !== 0) {
if (empty($composer['name']) || (!$allow_package_name_mismatches && strcasecmp($composer['name'], $project['path_with_namespace']) !== 0)) {
return false; // packages must have a name and must match
}

Expand All @@ -83,24 +85,33 @@
* @return array [$version => ['name' => $name, 'version' => $version, 'source' => [...]]]
*/
$fetch_ref = function($project, $ref) use ($fetch_composer) {
if (preg_match('/^v?\d+\.\d+(\.\d+)*(\-(dev|patch|alpha|beta|RC)\d*)?$/', $ref['name'])) {
$version = $ref['name'];
} else {
$version = 'dev-' . $ref['name'];
}

if (($data = $fetch_composer($project, $ref['commit']['id'])) !== false) {
$data['version'] = $version;
$data['source'] = array(
'url' => $project[method . '_url_to_repo'],
'type' => 'git',
'reference' => $ref['commit']['id'],
);
static $ref_cache = [];

return array($version => $data);
} else {
return array();
$ref_key = md5(serialize($project) . serialize($ref));

if (!isset($ref_cache[$ref_key])) {
if (preg_match('/^v?\d+\.\d+(\.\d+)*(\-(dev|patch|alpha|beta|RC)\d*)?$/', $ref['name'])) {
$version = $ref['name'];
} else {
$version = 'dev-' . $ref['name'];
}

if (($data = $fetch_composer($project, $ref['commit']['id'])) !== false) {
$data['version'] = $version;
$data['source'] = [
'url' => $project[method . '_url_to_repo'],
'type' => 'git',
'reference' => $ref['commit']['id'],
];

$ref_cache[$ref_key] = [$version => $data];
} else {
$ref_cache[$ref_key] = [];
}
}

return $ref_cache[$ref_key];
};

/**
Expand All @@ -110,7 +121,6 @@
*/
$fetch_refs = function($project) use ($fetch_ref, $repos) {
$datas = array();

try {
foreach (array_merge($repos->branches($project['id']), $repos->tags($project['id'])) as $ref) {
foreach ($fetch_ref($project, $ref) as $version => $data) {
Expand Down Expand Up @@ -159,6 +169,21 @@
}
};

/**
* Determine the name to use for the package.
*
* @param array $project
* @return string The name of the project
*/
$get_package_name = function($project) use ($allow_package_name_mismatches, $fetch_ref, $repos) {
if ($allow_package_name_mismatches) {
$ref = $fetch_ref($project, $repos->branch($project['id'], $project['default_branch']));
return reset($ref)['name'];
}

return $project['path_with_namespace'];
};

// Load projects
$all_projects = array();
$mtime = 0;
Expand Down Expand Up @@ -190,8 +215,8 @@
if (!file_exists($packages_file) || filemtime($packages_file) < $mtime) {
$packages = array();
foreach ($all_projects as $project) {
if ($package = $load_data($project)) {
$packages[$project['path_with_namespace']] = $package;
if (($package = $load_data($project)) && ($package_name = $get_package_name($project))) {
$packages[$package_name] = $package;
}
}
if ( file_exists( $static_file ) ) {
Expand Down

0 comments on commit 94a4a53

Please sign in to comment.