Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Parse Gitolite config (for gitlist :)
<?php
class GitoliteConfigParser {
public function parse($config) {
$lines = explode("\n", $config);
// remove comments and spaces
$lines = array_filter(array_map(function ($line) {
$line = preg_replace('/#(.*)$/', '', $line);
return preg_replace('/^\s+/', '', $line);
}, $lines));
$groups = array();
$repos = array();
// all groups first
foreach ($lines as $i => $line) {
if (preg_match('/^(@[^=]+)=(.*)$/', $line, $match)) {
$groups[trim($match[1])] = array_filter(explode(' ', trim($match[2])));
unset($lines[$i]);
}
}
$currentRepo = '';
foreach ($lines as $line) {
if (preg_match('/^repo\s+(.*)$/', $line, $match)) {
$currentRepo = trim($match[1]);
} elseif (preg_match('/^(R|RW\\+)\s+=(.*)/', $line, $match)) {
if (!$currentRepo) throw new Exception('No current repository');
$list = array_map(function ($repoOrGroup) use ($groups) {
return isset($groups[$repoOrGroup]) ? $groups[$repoOrGroup] : $repoOrGroup;
}, array_filter(explode(' ', trim($match[2]))));
$list = array_unique(static::flattenArray($list));
$repos[$currentRepo][trim($match[1])] = $list;
}
}
foreach ($repos as $name => $repo) {
if (isset($groups[$name])) {
foreach ($groups[$name] as $entry)
$repos[$entry] = $repo;
unset($repos[$name]);
}
}
return $repos;
}
public static function flattenArray(array $array) {
$return = array();
array_walk_recursive($array, function($a) use (&$return) { $return[] = $a; });
return $return;
}
}
class VisibilityLimiter {
public function getVisible(array $repos, $user) {
$visible = array();
foreach ($repos as $name => $repo) {
foreach ($repo as $type => $users) {
if (strpos($type, 'R') === 0 && (in_array($user, $users) || in_array('@all', $users)))
$visible[] = $name;
}
}
return array_unique($visible);
}
}
$parser = new GitoliteConfigParser();
$repos = $parser->parse(file_get_contents('gitolite.conf'));
$limiter = new VisibilityLimiter();
$visible = $limiter->getVisible($repos, 'chris');
var_dump($visible);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment