Skip to content

Commit

Permalink
bug #460 Improve sync-recipes --force (nicolas-grekas)
Browse files Browse the repository at this point in the history
This PR was merged into the 1.1-dev branch.

Discussion
----------

Improve sync-recipes --force

Fixes #456

Commits
-------

d3adcac Improve sync-recipes --force
  • Loading branch information
nicolas-grekas committed Dec 20, 2018
2 parents e09ce05 + d3adcac commit 5745527
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 19 deletions.
57 changes: 56 additions & 1 deletion src/Command/SyncRecipesCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
use Composer\Command\BaseCommand;
use Composer\DependencyResolver\Operation\InstallOperation;
use Composer\Factory;
use Symfony\Component\Console\Exception\RuntimeException;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
Expand All @@ -23,10 +24,12 @@
class SyncRecipesCommand extends BaseCommand
{
private $flex;
private $rootDir;

public function __construct(/* cannot be type-hinted */ $flex)
public function __construct(/* cannot be type-hinted */ $flex, string $rootDir)
{
$this->flex = $flex;
$this->rootDir = $rootDir;

parent::__construct();
}
Expand All @@ -42,8 +45,13 @@ protected function configure()

protected function execute(InputInterface $input, OutputInterface $output)
{
$win = '\\' === \DIRECTORY_SEPARATOR;
$force = $input->getOption('force');

if ($force && !@is_executable(strtok(exec($win ? 'where git' : 'command -v git'), PHP_EOL))) {
throw new RuntimeException('Cannot run "sync-recipes --force": git not found.');
}

$symfonyLock = new Lock(getenv('SYMFONY_LOCKFILE') ?: str_replace('composer.json', 'symfony.lock', Factory::getComposerFile()));
$composer = $this->getComposer();
$locker = $composer->getLocker();
Expand Down Expand Up @@ -80,6 +88,53 @@ protected function execute(InputInterface $input, OutputInterface $output)
$operations[] = new InstallOperation($pkg);
}

if ($createEnvLocal = $force && file_exists($this->rootDir.'/.env') && file_exists($this->rootDir.'/.env.dist') && !file_exists($this->rootDir.'/.env.local')) {
rename($this->rootDir.'/.env', $this->rootDir.'/.env.local');
$pipes = [];
proc_close(proc_open(sprintf('git mv .env.dist .env > %s 2>&1 || %s .env.dist .env', $win ? 'NUL' : '/dev/null', $win ? 'rename' : 'mv'), $pipes, $pipes, $this->rootDir));
if (file_exists($this->rootDir.'/phpunit.xml.dist')) {
touch($this->rootDir.'/.env.test');
}
}

$this->flex->update(new UpdateEvent($force), $operations);

if ($force) {
$output = [
'',
'<bg=blue;fg=white> </>',
'<bg=blue;fg=white> Config files are now reset to their initial state. </>',
'<bg=blue;fg=white> </>',
'',
' * Use <comment>git diff</comment> to inspect the changes.',
'',
' Not all of the changes will be relevant to your app: you now',
' need to selectively add or revert them using e.g. a combination',
' of <comment>git add -p</> and <comment>git checkout -p</>',
'',
];

if ($createEnvLocal) {
$output[] = ' Dotenv files have been renamed: .env -> .env.local and .env.dist -> .env';
$output[] = ' See https://symfony.com/doc/current/configuration/dot-env-changes.html';
$output[] = '';
}

$output[] = ' * Use <comment>git checkout .</> to revert the changes.';
$output[] = '';

if ($createEnvLocal) {
$output[] = ' To revert the changes made to .env files, run';
$output[] = sprintf(' <comment>git mv %s.env %1$s.env.dist</> && <comment>%s %1$s.env.local %1$s.env</>', '.' !== $this->rootDir ? $this->rootDir.'/' : '', $win ? 'rename' : 'mv');
$output[] = '';
}

$output[] = ' New (untracked) files can be inspected using <comment>git clean --dry-run</>';
$output[] = ' Add the new files you want to keep using <comment>git add</>';
$output[] = ' then delete the rest using <comment>git clean --force</>';
$output[] = '';

$io->write($output);
}
}
}
2 changes: 1 addition & 1 deletion src/Flex.php
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ public function activate(Composer $composer, IOInterface $io)
$app->add(new Command\UpdateCommand($resolver));
$app->add(new Command\RemoveCommand($resolver));
$app->add(new Command\UnpackCommand($resolver));
$app->add(new Command\SyncRecipesCommand($this));
$app->add(new Command\SyncRecipesCommand($this, $this->options->get('root-dir')));
$app->add(new Command\GenerateIdCommand($this));

break;
Expand Down
19 changes: 4 additions & 15 deletions src/Options.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,12 @@ public function shouldWriteFile(string $file, bool $overwrite): bool
return false;
}

if ($this->gitExists()) {
exec('git status --short --ignored -- '.ProcessExecutor::escape($file).' 2>&1', $output, $status);
} else {
$status = 1;
if (!filesize($file)) {
return true;
}

exec('git status --short --ignored -- '.ProcessExecutor::escape($file).' 2>&1', $output, $status);

if (0 !== $status) {
return (bool) $this->io && $this->io->askConfirmation(\sprintf('Cannot determine the state of the "%s" file, overwrite anyway? [y/N] ', $file), false);
}
Expand All @@ -80,15 +80,4 @@ public function shouldWriteFile(string $file, bool $overwrite): bool

return (bool) $this->io && $this->io->askConfirmation(\sprintf('File "%s" has uncommitted changes, overwrite? [y/N] ', $name), false);
}

private function gitExists(): bool
{
static $gitExists;

if (\is_bool($gitExists)) {
return $gitExists;
}

return $gitExists = @is_executable(strtok(exec('\\' === \DIRECTORY_SEPARATOR ? 'where git' : 'command -v git'), PHP_EOL));
}
}
2 changes: 1 addition & 1 deletion tests/Configurator/CopyFromPackageConfiguratorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public function testConfigureAndOverwriteFiles()
mkdir($this->sourceDirectory);
}
file_put_contents($this->sourceFile, 'somecontent');
file_put_contents($this->targetFile, '');
file_put_contents($this->targetFile, '-');

$this->io->expects($this->at(0))->method('writeError')->with([' Setting configuration and copying files']);
$this->io->expects($this->at(2))->method('writeError')->with([' Created <fg=green>"./public/file"</>']);
Expand Down
2 changes: 1 addition & 1 deletion tests/Configurator/CopyFromRecipeConfiguratorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public function testConfigureAndOverwriteFiles()
if (!file_exists($this->targetDirectory)) {
mkdir($this->targetDirectory);
}
file_put_contents($this->targetFile, '');
file_put_contents($this->targetFile, '-');

$this->io->expects($this->at(0))->method('writeError')->with([' Setting configuration and copying files']);
$this->io->expects($this->at(2))->method('writeError')->with([' Created <fg=green>"./config/file"</>']);
Expand Down

0 comments on commit 5745527

Please sign in to comment.