1
0
Fork 0
mirror of https://we.phorge.it/source/arcanist.git synced 2024-10-24 17:48:50 +02:00
phorge-arcanist/src/workflow/git-hook-pre-receive/ArcanistGitHookPreReceiveWorkflow.php

129 lines
3.4 KiB
PHP
Raw Normal View History

2011-01-10 00:22:25 +01:00
<?php
/*
* Copyright 2012 Facebook, Inc.
2011-01-10 00:22:25 +01:00
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Installable as a git pre-receive hook.
*
* @group workflow
*/
final class ArcanistGitHookPreReceiveWorkflow extends ArcanistBaseWorkflow {
2011-01-10 00:22:25 +01:00
public function getCommandHelp() {
return phutil_console_format(<<<EOTEXT
**git-hook-pre-receive**
Supports: git
You can install this as a git pre-receive hook.
2011-01-10 00:22:25 +01:00
EOTEXT
);
}
public function getArguments() {
return array(
);
}
public function requiresConduit() {
return true;
}
public function requiresWorkingCopy() {
return true;
}
public function shouldShellComplete() {
return false;
}
2011-01-10 00:22:25 +01:00
public function run() {
$working_copy = $this->getWorkingCopy();
if (!$working_copy->getProjectID()) {
throw new ArcanistUsageException(
"You have installed a git pre-receive hook in a remote without an ".
".arcconfig.");
}
// Git repositories have special rules in pre-receive hooks. We need to
// construct the API against the .git directory instead of the project
// root or commands don't work properly.
$repository_api = ArcanistGitAPI::newHookAPI($_SERVER['PWD']);
$root = $working_copy->getProjectRoot();
$parser = new ArcanistDiffParser();
$mark_revisions = array();
$stdin = file_get_contents('php://stdin');
$commits = array_filter(explode("\n", $stdin));
foreach ($commits as $commit) {
list($old_ref, $new_ref, $refname) = explode(' ', $commit);
list($log) = execx(
'(cd %s && git log -n1 %s)',
$repository_api->getPath(),
$new_ref);
$message_log = reset($parser->parseDiff($log));
$message = ArcanistDifferentialCommitMessage::newFromRawCorpus(
$message_log->getMetadata('message'));
$revision_id = $message->getRevisionID();
if ($revision_id) {
$mark_revisions[] = $revision_id;
}
// TODO: Do commit message junk.
$info = $repository_api->getPreReceiveHookStatus($old_ref, $new_ref);
$paths = ipull($info, 'mask');
$frefs = ipull($info, 'ref');
$data = array();
foreach ($paths as $path => $mask) {
list($stdout) = execx(
'(cd %s && git cat-file blob %s)',
$repository_api->getPath(),
$frefs[$path]);
$data[$path] = $stdout;
}
// TODO: Do commit content junk.
$commit_name = $new_ref;
if ($revision_id) {
$commit_name = 'D'.$revision_id.' ('.$commit_name.')';
}
echo "[arc pre-receive] {$commit_name} OK...\n";
}
$conduit = $this->getConduit();
$futures = array();
foreach ($mark_revisions as $revision_id) {
$futures[] = $conduit->callMethod(
'differential.markcommitted',
array(
'revision_id' => $revision_id,
));
}
Futures($futures)->resolveAll();
return 0;
}
}