Skip to content

Commit 458ca2f

Browse files
Reworked commands to use factories which is much cleaner and more flexible
Signed-off-by: Bastian Schwarz <bastian@codename-php.de>
1 parent a82a950 commit 458ca2f

21 files changed

Lines changed: 422 additions & 113 deletions
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?php declare(strict_types=1);
2+
/*
3+
* Copyright 2022 Bastian Schwarz <bastian@codename-php.de>.
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
namespace de\codenamephp\deployer\npm\command;
19+
20+
use de\codenamephp\deployer\base\functions\All;
21+
use de\codenamephp\deployer\base\functions\iGet;
22+
use de\codenamephp\deployer\command\Command;
23+
use de\codenamephp\deployer\command\iCommand;
24+
use de\codenamephp\deployer\command\runConfiguration\iRunConfiguration;
25+
use de\codenamephp\deployer\command\runConfiguration\SimpleContainer;
26+
27+
/**
28+
* Factory that gets the npm binary from deployer with a fallback to npm
29+
*/
30+
final class WithBinaryFromDeployer implements iNpmCommandFactory {
31+
32+
public function __construct(public iGet $deployer = new All()) {}
33+
34+
public function build(string $command, array $arguments = [], array $envVars = [], bool $sudo = false, iRunConfiguration $runConfiguration = null) : iCommand {
35+
return new Command((string) $this->deployer->get('npm:binary', 'npm'), ['--prefix {{release_path}}', '--fund=false', $command, ...$arguments], $envVars, $sudo, $runConfiguration ?? new SimpleContainer());
36+
}
37+
}

src/command/iNpmCommandFactory.php

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php declare(strict_types=1);
2+
/*
3+
* Copyright 2022 Bastian Schwarz <bastian@codename-php.de>.
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
namespace de\codenamephp\deployer\npm\command;
19+
20+
use de\codenamephp\deployer\command\iCommand;
21+
use de\codenamephp\deployer\command\runConfiguration\iRunConfiguration;
22+
23+
/**
24+
* Interface to create commands geared towards npm on the fly. Implementations must take care of setting the npm binary. The npm command should be the first
25+
* argument.
26+
*/
27+
interface iNpmCommandFactory {
28+
29+
/**
30+
* Implementations MUST make sure the command gets the correct binary (e.g. from deployer) and that all parameters are passed on correctly
31+
*
32+
* @param string $command The npm command to run, e.g. 'install' or 'run'
33+
* @param array<int, string> $arguments Array of arguments to pass to the command with numerical indexes so the arguments can be expanded, e.g. ['--production', '--fund=false']
34+
* @param array<string, string> $envVars Array of env vars to pass to the command with the name as key.
35+
* @param bool $sudo Flag if the command should be executed as root
36+
* @param iRunConfiguration|null $runConfiguration The run configuration for the command. Defaults to an empty configuration
37+
* @return iCommand The command to run
38+
*/
39+
public function build(string $command, array $arguments = [], array $envVars = [], bool $sudo = false, iRunConfiguration $runConfiguration = null) : iCommand;
40+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php declare(strict_types=1);
2+
/*
3+
* Copyright 2022 Bastian Schwarz <bastian@codename-php.de>.
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
namespace de\codenamephp\deployer\npm\command\run;
19+
20+
use de\codenamephp\deployer\command\iCommand;
21+
use de\codenamephp\deployer\command\runConfiguration\iRunConfiguration;
22+
use de\codenamephp\deployer\npm\command\iNpmCommandFactory;
23+
use de\codenamephp\deployer\npm\command\WithBinaryFromDeployer;
24+
25+
/**
26+
* Just decorates a command factory to build the command and makes sure the script name and "run" are passed on correctly using the arguments
27+
*/
28+
final class DecorateCommandFactory implements iNpmRunCommandFactory {
29+
30+
public function __construct(public iNpmCommandFactory $commandFactory = new WithBinaryFromDeployer()) {}
31+
32+
public function build(string $scriptName, array $arguments = [], array $envVars = [], bool $sudo = false, iRunConfiguration $runConfiguration = null) : iCommand {
33+
return $this->commandFactory->build('run', [$scriptName, ...$arguments], $envVars, $sudo, $runConfiguration);
34+
}
35+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php declare(strict_types=1);
2+
/*
3+
* Copyright 2022 Bastian Schwarz <bastian@codename-php.de>.
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
namespace de\codenamephp\deployer\npm\command\run;
19+
20+
use de\codenamephp\deployer\command\iCommand;
21+
use de\codenamephp\deployer\command\runConfiguration\iRunConfiguration;
22+
23+
/**
24+
* Interface to create a command for running npm scripts. Implementations must make sure to set the command correctly together with the script name in the
25+
* arguments
26+
*/
27+
interface iNpmRunCommandFactory {
28+
29+
/**
30+
* Implementations MUST make sure the command gets the correct binary and command to run the script and pass on all parameters correctly
31+
*
32+
* @param string $scriptName The name of the script to run
33+
* @param array<int, string> $arguments Array of arguments to pass to the command with numerical indexes so the arguments can be expanded, e.g. ['--production', '--fund=false']
34+
* @param array<string, string> $envVars Array of env vars to pass to the command with the name as key.
35+
* @param bool $sudo Flag if the command should be executed as root
36+
* @param iRunConfiguration|null $runConfiguration The run configuration for the command. Defaults to an empty configuration
37+
* @return iCommand The command to run
38+
*/
39+
public function build(string $scriptName, array $arguments = [], array $envVars = [], bool $sudo = false, iRunConfiguration $runConfiguration = null) : iCommand;
40+
}

src/task/AbstractNpmTask.php

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -17,27 +17,18 @@
1717

1818
namespace de\codenamephp\deployer\npm\task;
1919

20-
use de\codenamephp\deployer\base\functions\All;
21-
use de\codenamephp\deployer\base\functions\iGet;
2220
use de\codenamephp\deployer\base\task\iTask;
23-
use de\codenamephp\deployer\command\Command;
24-
use de\codenamephp\deployer\command\iCommand;
2521
use de\codenamephp\deployer\command\runner\iRunner;
2622
use de\codenamephp\deployer\command\runner\WithDeployerFunctions;
23+
use de\codenamephp\deployer\npm\command\iNpmCommandFactory;
24+
use de\codenamephp\deployer\npm\command\WithBinaryFromDeployer;
2725

2826
/**
2927
* Base class for npm command setting the binary to npm
3028
*/
3129
abstract class AbstractNpmTask implements iTask {
3230

33-
public iCommand $command;
34-
35-
public function __construct(
36-
public iRunner $runner = new WithDeployerFunctions(),
37-
iGet $deployer = new All()
38-
) {
39-
$this->command = new Command((string) $deployer->get('npm:binary', 'npm'), [$this->getNpmCommand(), ...$this->getArguments()]);
40-
}
31+
public function __construct(public iNpmCommandFactory $commandFactory = new WithBinaryFromDeployer(), public iRunner $runner = new WithDeployerFunctions()) {}
4132

4233
/**
4334
* Gets the command for npm, e.g. install or run-script
@@ -55,11 +46,9 @@ abstract public function getNpmCommand() : string;
5546
*
5647
* @return array<int,string>
5748
*/
58-
public function getArguments() : array {
59-
return ['--prefix {{release_path}}', '--fund=false'];
60-
}
49+
abstract public function getArguments() : array;
6150

6251
public function __invoke() : void {
63-
$this->runner->run($this->command);
52+
$this->runner->run($this->commandFactory->build($this->getNpmCommand(), $this->getArguments()));
6453
}
6554
}

src/task/install/Development.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,6 @@
2323
final class Development extends AbstractInstallTask {
2424

2525
public function getArguments() : array {
26-
return [...parent::getArguments(), '--production=false'];
26+
return ['--production=false'];
2727
}
2828
}

src/task/install/Production.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,6 @@
2323
final class Production extends AbstractInstallTask {
2424

2525
public function getArguments() : array {
26-
return [...parent::getArguments(), '--production'];
26+
return ['--production'];
2727
}
2828
}

src/task/run/AbstractRunTask.php

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,28 @@
1717

1818
namespace de\codenamephp\deployer\npm\task\run;
1919

20-
use de\codenamephp\deployer\npm\task\AbstractNpmTask;
20+
use de\codenamephp\deployer\base\task\iTask;
21+
use de\codenamephp\deployer\command\runner\iRunner;
22+
use de\codenamephp\deployer\command\runner\WithDeployerFunctions;
23+
use de\codenamephp\deployer\npm\command\run\DecorateCommandFactory;
24+
use de\codenamephp\deployer\npm\command\run\iNpmRunCommandFactory;
2125

22-
abstract class AbstractRunTask extends AbstractNpmTask {
26+
abstract class AbstractRunTask implements iTask {
27+
28+
public function __construct(public iNpmRunCommandFactory $commandFactory = new DecorateCommandFactory(), public iRunner $runner = new WithDeployerFunctions()) {}
2329

2430
abstract public function getScriptName() : string;
2531

26-
public function getNpmCommand() : string {
27-
return 'run';
28-
}
32+
/**
33+
* Gets the arguments to pass to the command. Override this and add you commands and options as needed.
34+
*
35+
* The array has to be numerical so it can be expanded in the constructor
36+
*
37+
* @return array<int,string>
38+
*/
39+
abstract public function getArguments() : array;
2940

30-
public function getArguments() : array {
31-
return [$this->getScriptName(), ...parent::getArguments()];
41+
public function __invoke() : void {
42+
$this->runner->run($this->commandFactory->build($this->getScriptName(), $this->getArguments()));
3243
}
3344
}

src/task/run/Generic.php

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@
1717

1818
namespace de\codenamephp\deployer\npm\task\run;
1919

20-
use de\codenamephp\deployer\base\functions\All;
21-
use de\codenamephp\deployer\base\functions\iGet;
2220
use de\codenamephp\deployer\command\runner\iRunner;
2321
use de\codenamephp\deployer\command\runner\WithDeployerFunctions;
22+
use de\codenamephp\deployer\npm\command\run\DecorateCommandFactory;
23+
use de\codenamephp\deployer\npm\command\run\iNpmRunCommandFactory;
2424

2525
final class Generic extends AbstractRunTask {
2626

@@ -33,21 +33,24 @@ final class Generic extends AbstractRunTask {
3333

3434
/**
3535
* @param string $scriptName The name of the script to run, e.g. 'build'
36-
* @param array<int,string> $arguments Additional arguments to pass to the script that will be appended to the defaults
37-
* @param iRunner $runner The runner that runs the command
38-
* @param iGet $deployer Deployer function to access the config. Will not be set in the instance
36+
* @param array<int,string> $arguments Additional arguments to pass to the script
37+
* @param iNpmRunCommandFactory $commandFactory The factory to build the command. Will be passed to parent.
38+
* @param iRunner $runner The runner that runs the command. Will be passed to parent.
3939
*/
40-
public function __construct(string $scriptName, array $arguments = [], iRunner $runner = new WithDeployerFunctions(), iGet $deployer = new All()) {
40+
public function __construct(string $scriptName,
41+
array $arguments = [],
42+
iNpmRunCommandFactory $commandFactory = new DecorateCommandFactory(),
43+
iRunner $runner = new WithDeployerFunctions()) {
44+
parent::__construct($commandFactory, $runner);
4145
$this->scriptName = $scriptName;
4246
$this->arguments = $arguments;
43-
parent::__construct($runner, $deployer);
4447
}
4548

4649
public function getScriptName() : string {
4750
return $this->scriptName;
4851
}
4952

5053
public function getArguments() : array {
51-
return [...parent::getArguments(), ...$this->arguments];
54+
return $this->arguments;
5255
}
5356
}

src/task/run/build/Development.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,9 @@ final class Development extends AbstractRunTask {
2727
public function getScriptName() : string {
2828
return 'build:development';
2929
}
30+
31+
public function getArguments() : array {
32+
return [];
33+
}
34+
3035
}

0 commit comments

Comments
 (0)