Skip to content

Commit af3fe6f

Browse files
authored
Merge pull request #17 from wirecli/fix/cli-src-path-handling
fix(cli): robust --src path handling, improved error messages, and updated docs for new command (#16)
2 parents 77661a1 + a1df607 commit af3fe6f

File tree

10 files changed

+590
-547
lines changed

10 files changed

+590
-547
lines changed

.cursor/environment.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"terminals": []
3+
}

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,6 @@ ProcessWire
1515
Tests/processwire.zip
1616

1717
Tests/pw
18+
.cursorrules
19+
.phpunit.result.cache
20+
.phpunit.cache/test-results

.repomix/bundles.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"bundles": {}
3+
}

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,12 @@ Run `wire-cli` followed by the desired command to execute various tasks. For exa
3434
wire-cli new myproject
3535
```
3636

37+
### Path Arguments (e.g., --src)
38+
- You can use both relative and absolute paths for arguments like `--src`.
39+
- Paths with spaces should be quoted: `--src="C:/path/with spaces/ProcessWire"`
40+
- Both forward `/` and backward `\` slashes are supported; they are normalized automatically.
41+
- If the path does not exist or is not accessible, a clear error message will be shown.
42+
3743
For a complete list of available commands and options, use the `help` command:
3844

3945
## Documentation

Tests/Commands/Common/NewCommandTest.php

Lines changed: 87 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,11 @@ class NewCommandTest extends Base {
2121
'--useremail' => '[email protected]'
2222
);
2323

24+
/**
25+
* @var array Extended configuration for tests
26+
*/
27+
protected $extends = array();
28+
2429
/**
2530
* @before
2631
*/
@@ -50,17 +55,71 @@ public function testDownload() {
5055

5156
$this->assertDirectoryExists(Base::INSTALLATION_FOLDER);
5257
$this->assertDirectoryExists(Base::INSTALLATION_FOLDER . '/wire');
53-
$this->assertDirectoryNotExists(Base::INSTALLATION_FOLDER . '/site');
58+
$this->assertFileExists(Base::INSTALLATION_FOLDER . '/index.php');
59+
$this->assertFileExists(Base::INSTALLATION_FOLDER . '/install.php');
60+
}
61+
62+
public function testDownloadWithRelativeSrc() {
63+
$this->checkInstallation();
64+
$relativePath = basename(Base::INSTALLATION_ARCHIVE); // e.g., 'archive.zip'
65+
if (!file_exists($relativePath)) {
66+
copy(Base::INSTALLATION_ARCHIVE, $relativePath);
67+
}
68+
// Ensure the ProcessWire directory exists for the test
69+
if (!is_dir(Base::INSTALLATION_FOLDER)) {
70+
mkdir(Base::INSTALLATION_FOLDER);
71+
}
72+
$options = array('--no-install' => true, '--src' => $relativePath);
73+
$this->tester->execute(array_merge($this->defaults, $options));
74+
$this->assertDirectoryExists(Base::INSTALLATION_FOLDER);
75+
if (file_exists($relativePath)) {
76+
unlink($relativePath);
77+
}
78+
}
79+
80+
public function testDownloadWithAbsoluteSrc() {
81+
$this->checkInstallation();
82+
$absolutePath = realpath(Base::INSTALLATION_ARCHIVE);
83+
// Ensure the ProcessWire directory exists for the test
84+
if (!is_dir(Base::INSTALLATION_FOLDER)) {
85+
mkdir(Base::INSTALLATION_FOLDER);
86+
}
87+
$options = array('--no-install' => true, '--src' => $absolutePath);
88+
$this->tester->execute(array_merge($this->defaults, $options));
89+
$this->assertDirectoryExists(Base::INSTALLATION_FOLDER);
90+
}
91+
92+
public function testDownloadWithNonExistentSrc() {
93+
$this->checkInstallation();
94+
$options = array('--no-install' => true, '--src' => 'nonexistent.zip');
95+
$this->expectException(\RuntimeException::class);
96+
$this->tester->execute(array_merge($this->defaults, $options));
97+
}
98+
99+
public function testDownloadWithMixedSlashesAndSpacesSrc() {
100+
$this->checkInstallation();
101+
$absolutePath = realpath(Base::INSTALLATION_ARCHIVE);
102+
// Simulate a path with mixed slashes and spaces
103+
$mixedPath = str_replace('/', '\\', $absolutePath);
104+
$mixedPath = ' ' . $mixedPath . ' ';
105+
// Ensure the ProcessWire directory exists for the test
106+
if (!is_dir(Base::INSTALLATION_FOLDER)) {
107+
mkdir(Base::INSTALLATION_FOLDER);
108+
}
109+
$options = array('--no-install' => true, '--src' => $mixedPath);
110+
$this->tester->execute(array_merge($this->defaults, $options));
111+
$this->assertDirectoryExists(Base::INSTALLATION_FOLDER);
54112
}
55113

56114
/**
57-
* @depends testDownload
58-
* @expectedException RuntimeException
59-
* @expectedExceptionMessageRegExp /(Database connection information did not work)./
60-
*/
115+
* @depends testDownload
116+
*/
61117
public function testInstallWrongPassword() {
62118
// check ProcessWire has not been installed yet
63-
if ($this->fs->exists(Base::INSTALLATION_FOLDER . '/site/config.php')) return;
119+
if ($this->fs->exists(Base::INSTALLATION_FOLDER . '/site/config.php')) {
120+
$this->markTestSkipped('ProcessWire is already installed');
121+
return;
122+
}
64123

65124
// return the input you want to answer the question with
66125
$this->mockQuestionHelper($this->command, function($text, $order, Question $question) {
@@ -75,16 +134,20 @@ public function testInstallWrongPassword() {
75134
'--dbPass' => 'wrong'
76135
);
77136

137+
$this->expectException(\RuntimeException::class);
138+
$this->expectExceptionMessageMatches('/(Database connection information did not work)./');
78139
$this->tester->execute(array_merge($this->defaults, $options));
79140
}
80141

81142
/**
82-
* @depends testDownload
83-
* @expectedExceptionMessageRegExp /(enter a valid email address)/
84-
*/
143+
* @depends testDownload
144+
*/
85145
public function testInstallInvalidEmailAddress() {
86146
// check ProcessWire has not been installed yet
87-
if ($this->fs->exists(Base::INSTALLATION_FOLDER . '/site/config.php')) return;
147+
if ($this->fs->exists(Base::INSTALLATION_FOLDER . '/site/config.php')) {
148+
$this->markTestSkipped('ProcessWire is already installed');
149+
return;
150+
}
88151

89152
// return the input you want to answer the question with
90153
$this->mockQuestionHelper($this->command, function($text, $order, Question $question) {
@@ -98,6 +161,8 @@ public function testInstallInvalidEmailAddress() {
98161
'--useremail' => 'invalid'
99162
);
100163

164+
$this->expectException(\RuntimeException::class);
165+
$this->expectExceptionMessageMatches('/(enter a valid email address)/');
101166
$this->tester->execute(array_merge($this->defaults, $options));
102167
}
103168

@@ -106,21 +171,30 @@ public function testInstallInvalidEmailAddress() {
106171
*/
107172
public function testInstall() {
108173
// check ProcessWire has not been installed yet
109-
if ($this->fs->exists(Base::INSTALLATION_FOLDER . '/site/config.php')) return;
174+
if ($this->fs->exists(Base::INSTALLATION_FOLDER . '/site/config.php')) {
175+
$this->markTestSkipped('ProcessWire is already installed');
176+
return;
177+
}
110178

111179
$this->tester->execute($this->defaults);
112180
$output = $this->tester->getDisplay();
113181

114182
$this->assertDirectoryExists(Base::INSTALLATION_FOLDER . '/site');
115183
$this->assertFileExists(Base::INSTALLATION_FOLDER . '/site/config.php');
116-
$this->assertContains('Congratulations, ProcessWire has been successfully installed.', $output);
184+
$this->assertStringContainsString('Congratulations, ProcessWire has been successfully installed.', $output);
117185
}
118186

119187
/**
120188
* @depends testInstall
121-
* @expectedExceptionMessageRegExp /(There is already a \')(.*)(\' project)/
122189
*/
123190
public function testIsInstalled() {
191+
if (!$this->fs->exists(Base::INSTALLATION_FOLDER . '/site/config.php')) {
192+
$this->markTestSkipped('ProcessWire is not installed');
193+
return;
194+
}
195+
196+
$this->expectException(\RuntimeException::class);
197+
$this->expectExceptionMessageMatches('/(There is already a \')(.*)(\' project)/');
124198
$this->tester->execute($this->defaults);
125199
}
126200
}

composer.json

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -36,22 +36,34 @@
3636
}
3737
},
3838
"require": {
39-
"php": ">=8.1.0",
40-
"guzzlehttp/guzzle": "~7.7",
41-
"monolog/monolog": "~3.4",
39+
"php": "^8.1",
40+
"guzzlehttp/guzzle": "^7.8",
41+
"monolog/monolog": "^3.5",
4242
"pmjones/auto-shell": "^1.0.1",
43-
"symfony/console": "^6.3",
44-
"symfony/filesystem": "^6.3",
45-
"symfony/process": "^6.3"
43+
"symfony/console": "^6.4",
44+
"symfony/filesystem": "^6.4",
45+
"symfony/process": "^6.4",
46+
"ext-pdo_mysql": "*",
47+
"ext-gd": "*",
48+
"ext-json": "*",
49+
"ext-iconv": "*",
50+
"ext-ctype": "*",
51+
"ext-zip": "*"
4652
},
4753
"require-dev": {
48-
"phpunit/phpunit": "^10.2",
49-
"whatthejeff/nyancat-phpunit-resultprinter": "~1.2"
54+
"phpunit/phpunit": "^10.5"
5055
},
51-
"extra": {
52-
"symfony": {
53-
"require": "5.2.*"
56+
"config": {
57+
"sort-packages": true,
58+
"platform": {
59+
"php": "8.1.0"
5460
}
5561
},
56-
"version": "1.4.12"
62+
"version": "1.4.12",
63+
"extra": {
64+
"processwire": {
65+
"min-version": "3.0.0",
66+
"max-version": "4.0.0"
67+
}
68+
}
5769
}

0 commit comments

Comments
 (0)