From 767f1fae340eec88e0feb3129569ea86e2ac9f4b Mon Sep 17 00:00:00 2001 From: Ernst Vaarties Date: Wed, 7 Jan 2026 10:53:42 +0000 Subject: [PATCH] Ticket 180: allow the user to specify which files may be modified while releasing. --- README.md | 1 + .../RMT/Prerequisite/WorkingCopyCheck.php | 31 ++++++++++++++++--- .../Tests/Functional/PrerequisitesTest.php | 17 ++++++++++ 3 files changed, 44 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 4e66d004..92ac9378 100644 --- a/README.md +++ b/README.md @@ -163,6 +163,7 @@ Prerequisite actions are executed before the interactive part. * `working-copy-check`: check that you don't have any VCS local changes * Option `allow-ignore`: allow the user to skip the check when doing a release with `--ignore-check` + * Option `allowed-modifications`: allow the user to specify which files may be modified (does not support add, delete, rename, etc.) * `display-last-changes`: display your last changes * `tests-check`: run the project test suite * Option `command`: command to run (default: *phpunit*) diff --git a/src/Liip/RMT/Prerequisite/WorkingCopyCheck.php b/src/Liip/RMT/Prerequisite/WorkingCopyCheck.php index 9ad7895c..dc5e1f63 100644 --- a/src/Liip/RMT/Prerequisite/WorkingCopyCheck.php +++ b/src/Liip/RMT/Prerequisite/WorkingCopyCheck.php @@ -31,7 +31,13 @@ class WorkingCopyCheck extends BaseAction public function __construct($options = array()) { - parent::__construct(array_merge(array('allow-ignore' => false), $options)); + parent::__construct(array_merge( + array( + 'allow-ignore' => false, + 'allowed-modifications' => array(), + ), + $options + )); } public function getTitle() @@ -54,13 +60,14 @@ public function execute() ); } - $modCount = count(Context::get('vcs')->getLocalModifications()); + $modCount = $this->getModCount(); if ($modCount > 0) { throw new \Exception( 'Your working directory contains ' . $modCount . ' local modification' . ($modCount > 1 ? 's' : '') . - '. Use the --' . $this->ignoreCheckOptionName . ' option (along with the "allow-ignore" ' . - 'configuration key set to true) to bypass this check.' . "\n" . 'WARNING, if your release task ' . - 'include a commit action, the pending changes are going to be included in the release.', + '. Configure the "allowed-modifications" key or use the --' . $this->ignoreCheckOptionName . ' option ' . + '(along with the "allow-ignore" configuration key set to true) to bypass this check.' . "\n" . + 'WARNING, if your release task include a commit action, the pending changes are going ' . + 'to be included in the release.', self::EXCEPTION_CODE ); } @@ -68,6 +75,20 @@ public function execute() $this->confirmSuccess(); } + protected function getModCount(): int + { + $allowedModifications = $this->options['allowed-modifications']; + $localModifications = array_filter( + Context::get('vcs')->getLocalModifications(), + function($item) use ($allowedModifications) { + $filename = preg_replace('/^\s+M\s+/', '', $item); + return !in_array($filename, $allowedModifications); + } + ); + + return count($localModifications); + } + public function getInformationRequests() { return array( diff --git a/test/Liip/RMT/Tests/Functional/PrerequisitesTest.php b/test/Liip/RMT/Tests/Functional/PrerequisitesTest.php index e369d97a..d4bf8166 100644 --- a/test/Liip/RMT/Tests/Functional/PrerequisitesTest.php +++ b/test/Liip/RMT/Tests/Functional/PrerequisitesTest.php @@ -50,6 +50,23 @@ public function testWorkingCopyCheckFailsWithLocalModifications(): void self::assertStringContainsString('local modification', implode("\n", $consoleOutput)); } + public function testWorkingCopyContinuesWithAllowedModifications(): void + { + $this->createConfig('simple', 'vcs-tag', array( + 'prerequisites' => array('working-copy-check'=>array('allowed-modifications'=>array('CHANGELOG'))), + 'vcs' => 'git', + )); + $this->initGit(); + exec('git tag 1'); + + // Release should continue even though file CHANGELOG has been modified. + exec('echo toto >> CHANGELOG'); + exec('./RMT release -n 2>&1', $consoleOutput, $exitCode); + self::assertEquals(0, $exitCode, implode(PHP_EOL, $consoleOutput)); + exec('git tag', $tags2); + self::assertEquals(array('1', '2'), $tags2); + } + public function testWorkingCopyWithIgnoreCheck(): void { $this->createConfig('simple', 'vcs-tag', array(