Skip to content

Commit 15669f0

Browse files
committed
Use git file option
1 parent 57c6d3c commit 15669f0

10 files changed

Lines changed: 120 additions & 161 deletions

File tree

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
"require": {
2424
"php": "^7.3 || ^8.0",
2525
"ext-json": "*",
26-
"simple-cli/simple-cli": "^1.3.1",
26+
"simple-cli/simple-cli": "^1.4",
2727
"phpmd/phpmd": "^2.7",
2828
"phpstan/phpstan": "^0.11.15"
2929
},

src/Phug/Split.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public function gray()
2525
$this->write($this->getColorCode('dark_gray'));
2626
}
2727

28-
public function ungray()
28+
public function discolor()
2929
{
3030
$this->write($this->escapeCharacter.'[0m');
3131
}

src/Phug/Split/Command/Analyze.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ class Analyze extends CommandBase
3737
protected $ast;
3838

3939
/**
40-
* @param Split $cli
40+
* @param Split|SimpleCli $cli
4141
*
4242
* @return bool
4343
*/
@@ -123,6 +123,7 @@ protected function getPackage(string $directory, array $data): array
123123
{
124124
return [
125125
'name' => $data['name'],
126+
'directory' => $directory,
126127
'children' => [],
127128
];
128129
}
@@ -153,4 +154,4 @@ protected function scanDirectories(string $directory): iterable
153154
yield $mainPackage;
154155
}
155156
}
156-
}
157+
}

src/Phug/Split/Command/CommandBase.php

Lines changed: 11 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,14 @@
55
use Exception;
66
use Phug\Split\Git\Commit;
77
use Phug\Split\Git\Log;
8-
use RecursiveDirectoryIterator;
9-
use RecursiveIteratorIterator;
10-
use SimpleCli\Command;
11-
use SimpleCli\Options\Help;
8+
use SimpleCli\CommandBase as Command;
129

13-
abstract class CommandBase implements Command
10+
/**
11+
* @property-read string $gitProgram Git program path.
12+
* @property-read string $hashPrefix Prefix for split linked commit hashes.
13+
*/
14+
abstract class CommandBase extends Command
1415
{
15-
use Help;
16-
1716
/**
1817
* Escape a value for git command argument or option.
1918
*
@@ -23,7 +22,7 @@ abstract class CommandBase implements Command
2322
*/
2423
protected function gitEscape(string $value): string
2524
{
26-
return "$'".addcslashes($value, "'\\")."'";
25+
return '"'.addcslashes($value, '"').'"';
2726
}
2827

2928
/**
@@ -120,23 +119,9 @@ protected function getCurrentLinkedCommitHash(): ?string
120119
*/
121120
protected function remove(string $fileOrDirectory): bool
122121
{
123-
if (is_dir($fileOrDirectory)) {
124-
$dir = new RecursiveDirectoryIterator($fileOrDirectory, RecursiveDirectoryIterator::SKIP_DOTS);
125-
$dir = new RecursiveIteratorIterator($dir, RecursiveIteratorIterator::CHILD_FIRST);
126-
127-
foreach ($dir as $filename => $file) {
128-
is_file($filename)
129-
? unlink($filename)
130-
: rmdir($filename);
131-
}
132-
133-
return rmdir($fileOrDirectory);
134-
}
135-
136-
if (file_exists($fileOrDirectory)) {
137-
return unlink($fileOrDirectory);
138-
}
122+
@shell_exec('rm -rf '.escapeshellarg($fileOrDirectory).' 2>&1');
123+
@shell_exec('rmdir /S /Q '.escapeshellarg($fileOrDirectory).' 2>&1');
139124

140-
return false;
125+
return true;
141126
}
142-
}
127+
}

src/Phug/Split/Command/Copy.php

Lines changed: 5 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22

33
namespace Phug\Split\Command;
44

5+
use Exception;
56
use Phug\Split;
67
use Phug\Split\Command\Options\GitProgram;
78
use Phug\Split\Command\Options\HashPrefix;
89
use SimpleCli\SimpleCli;
9-
use Traversable;
1010

1111
/**
1212
* Copy files from the mono-repository to a sub-package at the current linked revision.
@@ -43,7 +43,9 @@ class Copy extends CommandBase
4343
public $filters = 'composer.json';
4444

4545
/**
46-
* @param Split $cli
46+
* @param Split|SimpleCli $cli
47+
*
48+
* @throws Exception
4749
*
4850
* @return bool
4951
*/
@@ -80,111 +82,4 @@ public function run(SimpleCli $cli): bool
8082

8183
return true;
8284
}
83-
84-
protected function calculatePackagesTree(Split $cli): bool
85-
{
86-
$this->directory = realpath($this->directory);
87-
88-
if (!$this->directory) {
89-
return $cli->error('Input directory not found.');
90-
}
91-
92-
$cli->chdir($this->directory);
93-
94-
if (!file_exists($this->composerFile)) {
95-
return $cli->error('Root project directory should contains a '.$this->composerFile.' file.');
96-
}
97-
98-
$data = json_decode(file_get_contents($this->composerFile), true);
99-
$vendorDirectory = ($data['config'] ?? [])['vendor-dir'] ?? 'vendor';
100-
101-
$cli->writeLine($data['name']);
102-
$this->ast = $this->mapDirectories('.', function (string $path, string $element) use ($vendorDirectory) {
103-
if ($element === $vendorDirectory) {
104-
return null;
105-
}
106-
107-
return $this->scanDirectories($path);
108-
});
109-
110-
return true;
111-
}
112-
113-
protected function getPackages(): iterable
114-
{
115-
if ($this->ast instanceof Traversable) {
116-
$this->ast = iterator_to_array($this->ast);
117-
}
118-
119-
return $this->ast;
120-
}
121-
122-
protected function dumpPackagesTree(Split $cli, iterable $packages, int $level = 0): bool
123-
{
124-
$count = count($packages);
125-
126-
foreach ($packages as $index => $package) {
127-
$symbol = $index === $count - 1 ? '' : '';
128-
$cli->writeLine(str_repeat(' ', $level).' '.$symbol.' '.$package['name'], 'light_cyan');
129-
$this->dumpPackagesTree($cli, $package['children']);
130-
}
131-
132-
return true;
133-
}
134-
135-
protected function mapDirectories(string $directory, callable $callback): iterable
136-
{
137-
foreach (scandir($directory) as $element) {
138-
if (substr($element, 0, 1) === '.') {
139-
continue;
140-
}
141-
142-
$path = $directory.DIRECTORY_SEPARATOR.$element;
143-
144-
if (is_dir($path)) {
145-
$result = $callback($path, $element);
146-
147-
if ($result !== null) {
148-
foreach ($result as $item) {
149-
yield $item;
150-
}
151-
}
152-
}
153-
}
154-
}
155-
156-
protected function getPackage(string $directory, array $data): array
157-
{
158-
return [
159-
'name' => $data['name'],
160-
'children' => [],
161-
];
162-
}
163-
164-
protected function scanDirectories(string $directory): iterable
165-
{
166-
$mainPackage = null;
167-
$composerPath = $directory.DIRECTORY_SEPARATOR.$this->composerFile;
168-
169-
if (file_exists($composerPath)) {
170-
$data = json_decode(file_get_contents($composerPath), true);
171-
$mainPackage = $this->getPackage($directory, $data);
172-
}
173-
174-
foreach ($this->mapDirectories($directory, function (string $path) {
175-
return $this->scanDirectories($path);
176-
}) as $package) {
177-
if ($mainPackage) {
178-
$mainPackage['children'][] = $package;
179-
180-
continue;
181-
}
182-
183-
yield $package;
184-
}
185-
186-
if ($mainPackage) {
187-
yield $mainPackage;
188-
}
189-
}
190-
}
85+
}

src/Phug/Split/Command/Dist.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ class Dist extends Analyze
3333
public $gitCredentials = '';
3434

3535
/**
36-
* @param Split $cli
36+
* @param Split|SimpleCli $cli
3737
*
3838
* @return bool
3939
*/
@@ -111,7 +111,7 @@ protected function distributePackage(Split $cli, array $package, string $branch)
111111

112112
$cli->gray();
113113
$this->git("clone $url $directory");
114-
$cli->ungray();
114+
$cli->discolor();
115115

116116
$cli->chdir($directory);
117117

@@ -122,8 +122,8 @@ protected function distributePackage(Split $cli, array $package, string $branch)
122122
$cli->writeLine("git checkout$option $branch", 'light_green');
123123
$cli->gray();
124124
$this->git("checkout$option $branch");
125-
$cli->ungray();
125+
$cli->discolor();
126126

127127
return true;
128128
}
129-
}
129+
}

src/Phug/Split/Command/Update.php

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,16 @@ protected function getPackage(string $directory, array $data): array
4343
];
4444
}
4545

46+
/**
47+
* Get list of commit to replay.
48+
*
49+
* @param Split $cli
50+
* @param string $hash
51+
*
52+
* @throws Exception
53+
*
54+
* @return Log
55+
*/
4656
protected function getReplayLog(Split $cli, string $hash): Log
4757
{
4858
$max = $this->maximumCommitsReplay;
@@ -74,6 +84,8 @@ protected function setGitCommitter(Author $author): void
7484
}
7585

7686
/**
87+
* Distribute and update the sub-package.
88+
*
7789
* @param Split $cli
7890
* @param array $package
7991
* @param string $branch
@@ -115,12 +127,14 @@ protected function distributePackage(Split $cli, array $package, string $branch)
115127
$this->setGitCommitter($commit->getCommit()->getAuthor());
116128
$author = $commit->getAuthor();
117129

130+
$commitMessageFile = sys_get_temp_dir().'/commit-message-'.mt_rand(0, 99999999);
131+
file_put_contents($commitMessageFile, $commit->getMessage()."\n\n".$this->hashPrefix.$hash);
118132
$this->git('add .');
119-
$this->git('commit', [
120-
'message' => $commit->getMessage()."\n\n".$this->hashPrefix.$hash,
133+
$this->git('commit --file='.escapeshellarg($commitMessageFile), [
121134
'author' => $author,
122135
'date' => $author->getDate(),
123136
], '2>&1');
137+
unlink($commitMessageFile);
124138

125139
if (!$this->noPush) {
126140
$name = $package['name'];

src/Phug/Split/Git/Commit.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ public static function fromGitLogString(string $log): self
7676
new Author(trim($matches['commitName']), trim($matches['commitEmail'])),
7777
new Date($matches['commitDate']),
7878
),
79-
preg_replace('/^ /m', '', trim($matches['message']))
79+
preg_replace('/^ {4}/m', '', trim($matches['message']))
8080
);
8181
}
8282

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<?php
2+
3+
namespace Phug\Test\Split\Command;
4+
5+
use Nette\Utils\FileSystem;
6+
use PHPUnit\Framework\TestCase;
7+
use Phug\Split\Command\CommandBase;
8+
use Phug\Split\Command\Copy;
9+
use ReflectionMethod;
10+
11+
/**
12+
* @coversDefaultClass \Phug\Split\Command\CommandBase
13+
*/
14+
class CommandBaseTest extends TestCase
15+
{
16+
public function getEscapableStrings()
17+
{
18+
return [
19+
['foobar'],
20+
["something\\Yoh'la' hop"],
21+
["something\\Yoh\'\"12\"' hop"],
22+
];
23+
}
24+
25+
/**
26+
* @dataProvider getEscapableStrings
27+
* @covers ::gitEscape
28+
*/
29+
public function testGitEscape(string $string)
30+
{
31+
$cwd = getcwd();
32+
$copy = new Copy();
33+
$gitEscape = new ReflectionMethod(CommandBase::class, 'gitEscape');
34+
$gitEscape->setAccessible(true);
35+
$directory = sys_get_temp_dir().'/split-test-'.mt_rand(0, 9999999);
36+
FileSystem::createDir($directory);
37+
chdir($directory);
38+
shell_exec('git init');
39+
file_put_contents('readme.md', '# README');
40+
shell_exec('git add readme.md');
41+
shell_exec('git commit --message='.$gitEscape->invoke($copy, $string));
42+
$log = shell_exec('git log -n 1 2>&1');
43+
chdir($cwd);
44+
@shell_exec('rmdir /S /Q '.escapeshellarg($directory));
45+
@FileSystem::delete($directory);
46+
47+
$log = explode("\n\n", $log);
48+
$log = trim(preg_replace('/^ {4}/m', '', $log[1]));
49+
50+
$this->assertSame($string, $log);
51+
}
52+
}

0 commit comments

Comments
 (0)