summaryrefslogtreecommitdiff
path: root/vendor/guzzle/guzzle/phing/tasks/GuzzleSubSplitTask.php
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/guzzle/guzzle/phing/tasks/GuzzleSubSplitTask.php')
-rw-r--r--vendor/guzzle/guzzle/phing/tasks/GuzzleSubSplitTask.php385
1 files changed, 385 insertions, 0 deletions
diff --git a/vendor/guzzle/guzzle/phing/tasks/GuzzleSubSplitTask.php b/vendor/guzzle/guzzle/phing/tasks/GuzzleSubSplitTask.php
new file mode 100644
index 0000000..5d56a5b
--- /dev/null
+++ b/vendor/guzzle/guzzle/phing/tasks/GuzzleSubSplitTask.php
@@ -0,0 +1,385 @@
+<?php
+/**
+ * Phing wrapper around git subsplit.
+ *
+ * @see https://github.com/dflydev/git-subsplit
+ * @copyright 2012 Clay Loveless <clay@php.net>
+ * @license http://claylo.mit-license.org/2012/ MIT License
+ */
+
+require_once 'phing/tasks/ext/git/GitBaseTask.php';
+
+// base - base of tree to split out
+// subIndicatorFile - composer.json, package.xml?
+class GuzzleSubSplitTask extends GitBaseTask
+{
+ /**
+ * What git repository to pull from and publish to
+ */
+ protected $remote = null;
+
+ /**
+ * Publish for comma-separated heads instead of all heads
+ */
+ protected $heads = null;
+
+ /**
+ * Publish for comma-separated tags instead of all tags
+ */
+ protected $tags = null;
+
+ /**
+ * Base of the tree RELATIVE TO .subsplit working dir
+ */
+ protected $base = null;
+
+ /**
+ * The presence of this file will indicate that the directory it resides
+ * in is at the top level of a split.
+ */
+ protected $subIndicatorFile = 'composer.json';
+
+ /**
+ * Do everything except actually send the update.
+ */
+ protected $dryRun = null;
+
+ /**
+ * Do not sync any heads.
+ */
+ protected $noHeads = false;
+
+ /**
+ * Do not sync any tags.
+ */
+ protected $noTags = false;
+
+ /**
+ * The splits we found in the heads
+ */
+ protected $splits;
+
+ public function setRemote($str)
+ {
+ $this->remote = $str;
+ }
+
+ public function getRemote()
+ {
+ return $this->remote;
+ }
+
+ public function setHeads($str)
+ {
+ $this->heads = explode(',', $str);
+ }
+
+ public function getHeads()
+ {
+ return $this->heads;
+ }
+
+ public function setTags($str)
+ {
+ $this->tags = explode(',', $str);
+ }
+
+ public function getTags()
+ {
+ return $this->tags;
+ }
+
+ public function setBase($str)
+ {
+ $this->base = $str;
+ }
+
+ public function getBase()
+ {
+ return $this->base;
+ }
+
+ public function setSubIndicatorFile($str)
+ {
+ $this->subIndicatorFile = $str;
+ }
+
+ public function getSubIndicatorFile()
+ {
+ return $this->subIndicatorFile;
+ }
+
+ public function setDryRun($bool)
+ {
+ $this->dryRun = (bool) $bool;
+ }
+
+ public function getDryRun()
+ {
+ return $this->dryRun;
+ }
+
+ public function setNoHeads($bool)
+ {
+ $this->noHeads = (bool) $bool;
+ }
+
+ public function getNoHeads()
+ {
+ return $this->noHeads;
+ }
+
+ public function setNoTags($bool)
+ {
+ $this->noTags = (bool) $bool;
+ }
+
+ public function getNoTags()
+ {
+ return $this->noTags;
+ }
+
+ /**
+ * GitClient from VersionControl_Git
+ */
+ protected $client = null;
+
+ /**
+ * The main entry point
+ */
+ public function main()
+ {
+ $repo = $this->getRepository();
+ if (empty($repo)) {
+ throw new BuildException('"repository" is a required parameter');
+ }
+
+ $remote = $this->getRemote();
+ if (empty($remote)) {
+ throw new BuildException('"remote" is a required parameter');
+ }
+
+ chdir($repo);
+ $this->client = $this->getGitClient(false, $repo);
+
+ // initalized yet?
+ if (!is_dir('.subsplit')) {
+ $this->subsplitInit();
+ } else {
+ // update
+ $this->subsplitUpdate();
+ }
+
+ // find all splits based on heads requested
+ $this->findSplits();
+
+ // check that GitHub has the repos
+ $this->verifyRepos();
+
+ // execute the subsplits
+ $this->publish();
+ }
+
+ public function publish()
+ {
+ $this->log('DRY RUN ONLY FOR NOW');
+ $base = $this->getBase();
+ $base = rtrim($base, '/') . '/';
+ $org = $this->getOwningTarget()->getProject()->getProperty('github.org');
+
+ $splits = array();
+
+ $heads = $this->getHeads();
+ foreach ($heads as $head) {
+ foreach ($this->splits[$head] as $component => $meta) {
+ $splits[] = $base . $component . ':git@github.com:'. $org.'/'.$meta['repo'];
+ }
+
+ $cmd = 'git subsplit publish ';
+ $cmd .= escapeshellarg(implode(' ', $splits));
+
+ if ($this->getNoHeads()) {
+ $cmd .= ' --no-heads';
+ } else {
+ $cmd .= ' --heads='.$head;
+ }
+
+ if ($this->getNoTags()) {
+ $cmd .= ' --no-tags';
+ } else {
+ if ($this->getTags()) {
+ $cmd .= ' --tags=' . escapeshellarg(implode(' ', $this->getTags()));
+ }
+ }
+
+ passthru($cmd);
+ }
+ }
+
+ /**
+ * Runs `git subsplit update`
+ */
+ public function subsplitUpdate()
+ {
+ $repo = $this->getRepository();
+ $this->log('git-subsplit update...');
+ $cmd = $this->client->getCommand('subsplit');
+ $cmd->addArgument('update');
+ try {
+ $cmd->execute();
+ } catch (Exception $e) {
+ throw new BuildException('git subsplit update failed'. $e);
+ }
+ chdir($repo . '/.subsplit');
+ passthru('php ../composer.phar update --dev');
+ chdir($repo);
+ }
+
+ /**
+ * Runs `git subsplit init` based on the remote repository.
+ */
+ public function subsplitInit()
+ {
+ $remote = $this->getRemote();
+ $cmd = $this->client->getCommand('subsplit');
+ $this->log('running git-subsplit init ' . $remote);
+
+ $cmd->setArguments(array(
+ 'init',
+ $remote
+ ));
+
+ try {
+ $output = $cmd->execute();
+ } catch (Exception $e) {
+ throw new BuildException('git subsplit init failed'. $e);
+ }
+ $this->log(trim($output), Project::MSG_INFO);
+ $repo = $this->getRepository();
+ chdir($repo . '/.subsplit');
+ passthru('php ../composer.phar install --dev');
+ chdir($repo);
+ }
+
+ /**
+ * Find the composer.json files using Phing's directory scanner
+ *
+ * @return array
+ */
+ protected function findSplits()
+ {
+ $this->log("checking heads for subsplits");
+ $repo = $this->getRepository();
+ $base = $this->getBase();
+
+ $splits = array();
+ $heads = $this->getHeads();
+
+ if (!empty($base)) {
+ $base = '/' . ltrim($base, '/');
+ } else {
+ $base = '/';
+ }
+
+ chdir($repo . '/.subsplit');
+ foreach ($heads as $head) {
+ $splits[$head] = array();
+
+ // check each head requested *BEFORE* the actual subtree split command gets it
+ passthru("git checkout '$head'");
+ $ds = new DirectoryScanner();
+ $ds->setBasedir($repo . '/.subsplit' . $base);
+ $ds->setIncludes(array('**/'.$this->subIndicatorFile));
+ $ds->scan();
+ $files = $ds->getIncludedFiles();
+
+ // Process the files we found
+ foreach ($files as $file) {
+ $pkg = file_get_contents($repo . '/.subsplit' . $base .'/'. $file);
+ $pkg_json = json_decode($pkg, true);
+ $name = $pkg_json['name'];
+ $component = str_replace('/composer.json', '', $file);
+ // keep this for split cmd
+ $tmpreponame = explode('/', $name);
+ $reponame = $tmpreponame[1];
+ $splits[$head][$component]['repo'] = $reponame;
+ $nscomponent = str_replace('/', '\\', $component);
+ $splits[$head][$component]['desc'] = "[READ ONLY] Subtree split of $nscomponent: " . $pkg_json['description'];
+ }
+ }
+
+ // go back to how we found it
+ passthru("git checkout master");
+ chdir($repo);
+ $this->splits = $splits;
+ }
+
+ /**
+ * Based on list of repositories we determined we *should* have, talk
+ * to GitHub and make sure they're all there.
+ *
+ */
+ protected function verifyRepos()
+ {
+ $this->log('verifying GitHub target repos');
+ $github_org = $this->getOwningTarget()->getProject()->getProperty('github.org');
+ $github_creds = $this->getOwningTarget()->getProject()->getProperty('github.basicauth');
+
+ if ($github_creds == 'username:password') {
+ $this->log('Skipping GitHub repo checks. Update github.basicauth in build.properties to verify repos.', 1);
+ return;
+ }
+
+ $ch = curl_init('https://api.github.com/orgs/'.$github_org.'/repos?type=all');
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+ curl_setopt($ch, CURLOPT_USERPWD, $github_creds);
+ // change this when we know we can use our bundled CA bundle!
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+ $result = curl_exec($ch);
+ curl_close($ch);
+ $repos = json_decode($result, true);
+ $existing_repos = array();
+
+ // parse out the repos we found on GitHub
+ foreach ($repos as $repo) {
+ $tmpreponame = explode('/', $repo['full_name']);
+ $reponame = $tmpreponame[1];
+ $existing_repos[$reponame] = $repo['description'];
+ }
+
+ $heads = $this->getHeads();
+ foreach ($heads as $head) {
+ foreach ($this->splits[$head] as $component => $meta) {
+
+ $reponame = $meta['repo'];
+
+ if (!isset($existing_repos[$reponame])) {
+ $this->log("Creating missing repo $reponame");
+ $payload = array(
+ 'name' => $reponame,
+ 'description' => $meta['desc'],
+ 'homepage' => 'http://www.guzzlephp.org/',
+ 'private' => true,
+ 'has_issues' => false,
+ 'has_wiki' => false,
+ 'has_downloads' => true,
+ 'auto_init' => false
+ );
+ $ch = curl_init('https://api.github.com/orgs/'.$github_org.'/repos');
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+ curl_setopt($ch, CURLOPT_USERPWD, $github_creds);
+ curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
+ curl_setopt($ch, CURLOPT_POST, 1);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
+ // change this when we know we can use our bundled CA bundle!
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+ $result = curl_exec($ch);
+ echo "Response code: ".curl_getinfo($ch, CURLINFO_HTTP_CODE)."\n";
+ curl_close($ch);
+ } else {
+ $this->log("Repo $reponame exists", 2);
+ }
+ }
+ }
+ }
+}