mirror of
https://we.phorge.it/source/arcanist.git
synced 2024-12-01 19:22:41 +01:00
0b45ec30be
Summary: - `kill_init.php` - Manually change library map. - Manually rename `/data/` test dirs. - [src/lint/linter] `git mv base/ArcanistLinterTestCase.php __tests__/` - `arc liberate` Test Plan: Browse around to make sure I like it better, especially `repository/api`, and `workflow`. Reviewers: epriestley Reviewed By: epriestley CC: aran, Koolvin Maniphest Tasks: T1103 Differential Revision: https://secure.phabricator.com/D2637
177 lines
5.4 KiB
PHP
177 lines
5.4 KiB
PHP
<?php
|
|
|
|
/*
|
|
* Copyright 2012 Facebook, Inc.
|
|
*
|
|
* 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.
|
|
*/
|
|
|
|
/**
|
|
* Explicitly closes Differential revisions.
|
|
*
|
|
* @group workflow
|
|
*/
|
|
final class ArcanistCloseRevisionWorkflow extends ArcanistBaseWorkflow {
|
|
|
|
public function getCommandSynopses() {
|
|
return phutil_console_format(<<<EOTEXT
|
|
**close-revision** [__options__] __revision__
|
|
EOTEXT
|
|
);
|
|
}
|
|
|
|
public function getCommandHelp() {
|
|
return phutil_console_format(<<<EOTEXT
|
|
Supports: git, hg, svn
|
|
Close a revision which has been committed (svn) or pushed (git, hg).
|
|
You should not normally need to do this: arc commit (svn), arc amend
|
|
(git), arc land (git), or repository tracking on the master remote
|
|
repository should do it for you. However, if these mechanisms have
|
|
failed for some reason you can use this command to manually change a
|
|
revision status from "Accepted" to "Closed".
|
|
EOTEXT
|
|
);
|
|
}
|
|
|
|
public function getArguments() {
|
|
return array(
|
|
'finalize' => array(
|
|
'help' =>
|
|
"Close only if the repository is untracked and the revision is ".
|
|
"accepted. Continue even if the close can't happen. This is a soft ".
|
|
"version of 'close-revision' used by other workflows.",
|
|
),
|
|
'quiet' => array(
|
|
'help' => 'Do not print a success message.',
|
|
),
|
|
'*' => 'revision',
|
|
);
|
|
}
|
|
|
|
public function requiresConduit() {
|
|
return true;
|
|
}
|
|
|
|
public function requiresAuthentication() {
|
|
return true;
|
|
}
|
|
|
|
public function requiresRepositoryAPI() {
|
|
// NOTE: Technically we only use this to generate the right message at
|
|
// the end, and you can even get the wrong message (e.g., if you run
|
|
// "arc close-revision D123" from a git repository, but D123 is an SVN
|
|
// revision). We could be smarter about this, but it's just display fluff.
|
|
return true;
|
|
}
|
|
|
|
public function run() {
|
|
$is_finalize = $this->getArgument('finalize');
|
|
|
|
$conduit = $this->getConduit();
|
|
|
|
$revision_list = $this->getArgument('revision', array());
|
|
if (!$revision_list) {
|
|
throw new ArcanistUsageException(
|
|
"close-revision requires a revision number.");
|
|
}
|
|
if (count($revision_list) != 1) {
|
|
throw new ArcanistUsageException(
|
|
"close-revision requires exactly one revision.");
|
|
}
|
|
$revision_id = reset($revision_list);
|
|
$revision_id = $this->normalizeRevisionID($revision_id);
|
|
|
|
$revision = null;
|
|
try {
|
|
$revision = $conduit->callMethodSynchronous(
|
|
'differential.getrevision',
|
|
array(
|
|
'revision_id' => $revision_id,
|
|
)
|
|
);
|
|
} catch (Exception $ex) {
|
|
if (!$is_finalize) {
|
|
throw new ArcanistUsageException(
|
|
"Revision D{$revision_id} does not exist."
|
|
);
|
|
}
|
|
}
|
|
|
|
$status_accepted = ArcanistDifferentialRevisionStatus::ACCEPTED;
|
|
$status_closed = ArcanistDifferentialRevisionStatus::CLOSED;
|
|
|
|
if (!$is_finalize && $revision['status'] != $status_accepted) {
|
|
throw new ArcanistUsageException(
|
|
"Revision D{$revision_id} can not be closed. You can only close ".
|
|
"revisions which have been 'accepted'.");
|
|
}
|
|
|
|
if ($revision) {
|
|
if (!$is_finalize && $revision['authorPHID'] != $this->getUserPHID()) {
|
|
$prompt = "You are not the author of revision D{$revision_id}, ".
|
|
'are you sure you want to close it?';
|
|
if (!phutil_console_confirm($prompt)) {
|
|
throw new ArcanistUserAbortException();
|
|
}
|
|
}
|
|
|
|
$actually_close = true;
|
|
if ($is_finalize) {
|
|
$project_id = $this->getWorkingCopy()->getProjectID();
|
|
if ($project_id) {
|
|
$project_info = $conduit->callMethodSynchronous(
|
|
'arcanist.projectinfo',
|
|
array(
|
|
'name' => $project_id,
|
|
));
|
|
if ($project_info['tracked'] ||
|
|
$revision['status'] != $status_accepted) {
|
|
$actually_close = false;
|
|
}
|
|
}
|
|
}
|
|
if ($actually_close) {
|
|
$revision_name = $revision['title'];
|
|
|
|
echo "Closing revision D{$revision_id} '{$revision_name}'...\n";
|
|
|
|
$conduit->callMethodSynchronous(
|
|
'differential.close',
|
|
array(
|
|
'revisionID' => $revision_id,
|
|
));
|
|
}
|
|
}
|
|
|
|
$status = $revision['status'];
|
|
if ($status == $status_accepted || $status == $status_closed) {
|
|
// If this has already been attached to commits, don't show the
|
|
// "you can push this commit" message since we know it's been pushed
|
|
// already.
|
|
$is_finalized = empty($revision['commits']);
|
|
} else {
|
|
$is_finalized = false;
|
|
}
|
|
|
|
if (!$this->getArgument('quiet')) {
|
|
if ($is_finalized) {
|
|
$message = $this->getRepositoryAPI()->getFinalizedRevisionMessage();
|
|
echo phutil_console_wrap($message)."\n";
|
|
} else {
|
|
echo "Done.\n";
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
}
|