update documentation & update compile:prompt command
This commit is contained in:
commit
f75a653a7d
24
README.md
24
README.md
@ -37,31 +37,27 @@ Follow those steps to install the library:
|
||||
```bash
|
||||
composer require retailcrm/api-client-php:"~6.0"
|
||||
```
|
||||
During the installation, you'll see a message which will look like this:
|
||||
During the installation you will see this message. Press `'y'` when you do:
|
||||
```sh
|
||||
civicrm/composer-compile-plugin contains a Composer plugin which is currently not in your allow-plugins config. See https://getcomposer.org/allow-plugins
|
||||
Do you trust "civicrm/composer-compile-plugin" to execute code and wish to enable it now? (writes "allow-plugins" to composer.json) [y,n,d,?]
|
||||
```
|
||||
After that, you may see a message which will look like this:
|
||||
```sh
|
||||
The following packages have new compilation tasks:
|
||||
- retailcrm/api-client-php has 1 task
|
||||
|
||||
Allow these packages to compile? ([y]es, [a]lways, [n]o, [l]ist, [h]elp)
|
||||
```
|
||||
That's because the Client uses code generation to speed up serialization and deserialization of models in production. This code should be generated during installation or update. Without that code, the library itself will not work at all.
|
||||
|
||||
Choose `[a]lways` by typing `a` and pressing Enter if you don't want to see this message anymore. If you want to approve the compilation task every time - use `[y]es` option. The DTO cache will be generated after that.
|
||||
Choose `[a]lways` by typing `a` and pressing Enter.
|
||||
|
||||
**Note:** You should choose `[a]lways` if your application is using CI/CD pipeline because the interactive terminal is not available
|
||||
**Note:** You should choose `'y'` and `[a]lways` if your application is using CI/CD pipeline because the interactive terminal is not available
|
||||
in that environment which will result in failure during the dependencies installation.
|
||||
|
||||
If you skipped the compilation task - don't worry, it can be executed manually at any time with this command:
|
||||
```sh
|
||||
composer compile --all
|
||||
```
|
||||
If you chose something else during the installation and API client doesn't work properly - please follow [these instructions](doc/compilation_prompt.md#ive-chosen-something-else-now-api-client-doesnt-work) to fix the problem.
|
||||
|
||||
3. **Optional.** Disable compilation prompt that you have seen in the previous step.
|
||||
|
||||
If you wish to disable the compilation prompt but didn't do that at the previous step - you can disable the prompt manually.
|
||||
Read the [documentation](doc/compilation_prompt.md) to learn how to do that.
|
||||
|
||||
4. Include the autoloader if it's not included, or you didn't use Composer before.
|
||||
3. Include the autoloader if it's not included, or you didn't use Composer before.
|
||||
```php
|
||||
require 'path/to/vendor/autoload.php';
|
||||
```
|
||||
|
@ -1,6 +1,12 @@
|
||||
## Compilation prompt
|
||||
## Dealing with `civicrm/composer-compile-plugin` prompts
|
||||
|
||||
After almost every Composer operation you will see this prompt:
|
||||
During installation you will see this prompt:
|
||||
```sh
|
||||
civicrm/composer-compile-plugin contains a Composer plugin which is currently not in your allow-plugins config. See https://getcomposer.org/allow-plugins
|
||||
Do you trust "civicrm/composer-compile-plugin" to execute code and wish to enable it now? (writes "allow-plugins" to composer.json) [y,n,d,?]
|
||||
```
|
||||
|
||||
And after almost any Composer operation you will see this prompt:
|
||||
```sh
|
||||
The following packages have new compilation tasks:
|
||||
- retailcrm/api-client-php has 1 task
|
||||
@ -9,7 +15,7 @@ Allow these packages to compile? ([y]es, [a]lways, [n]o, [l]ist, [h]elp)
|
||||
```
|
||||
|
||||
That's because the API client utilizes code generation to speed up the serialization and deserialization of the requests. However,
|
||||
this prompt may be annoying and sometimes can even break the application lifecycle pipeline (in the CI/CD environment). We can't just
|
||||
these prompts may be annoying and sometimes can even break the application lifecycle pipeline (in the CI/CD environment). We can't just
|
||||
disable it for everyone [because of security concerns](https://github.com/composer/composer/issues/1193). But you can disable it for your project.
|
||||
|
||||
There are three ways of disabling this prompt:
|
||||
@ -17,54 +23,65 @@ There are three ways of disabling this prompt:
|
||||
2. Automated way.
|
||||
3. Manual way.
|
||||
|
||||
### Disable compilation prompt during the installation
|
||||
### Disable compilation prompts during the installation
|
||||
|
||||
Just choose `[a]lways` option by pressing `a` followed by Enter. This will automatically edit your `composer.json` and will disable
|
||||
the compilation prompt for you. No additional steps are needed.
|
||||
Press `'y'` when you see this message:
|
||||
```sh
|
||||
civicrm/composer-compile-plugin contains a Composer plugin which is currently not in your allow-plugins config. See https://getcomposer.org/allow-plugins
|
||||
Do you trust "civicrm/composer-compile-plugin" to execute code and wish to enable it now? (writes "allow-plugins" to composer.json) [y,n,d,?]
|
||||
```
|
||||
|
||||
### Disable or enable compilation prompt via CLI
|
||||
And when you see this prompt, press `'a'`:
|
||||
```sh
|
||||
The following packages have new compilation tasks:
|
||||
- retailcrm/api-client-php has 1 task
|
||||
|
||||
Alternatively, you can use `retailcrm-client` CLI utility. It will be in your binary directory. By default, it'll be in the
|
||||
`vendor/bin` directory if not defined otherwise in the composer.json `config.bin-dir` entry.
|
||||
Allow these packages to compile? ([y]es, [a]lways, [n]o, [l]ist, [h]elp)
|
||||
```
|
||||
|
||||
The only benefit of this utility is the fact that it also can enable the prompt again.
|
||||
That's it. Code generation is now enabled.
|
||||
|
||||
#### Disabling compilation prompt
|
||||
|
||||
You can disable the compiler prompt by running this command:
|
||||
### I've chosen something else, now API client doesn't work!
|
||||
|
||||
That happens. We provide special CLI utility which will automatically configure your `composer.json` to enable code generation.
|
||||
Just run this command inside your project after API client installation:
|
||||
```sh
|
||||
./vendor/bin/retailcrm-client compiler:prompt
|
||||
```
|
||||
|
||||
Replace `vendor/bin` with your bin directory path if it's different from the default.
|
||||
|
||||
You should see this message after that:
|
||||
You should see this message after running the command:
|
||||
```sh
|
||||
✓ Done, generator prompt is now enabled.
|
||||
✓ Done, code generation has been enabled.
|
||||
```
|
||||
|
||||
#### Enabling compilation prompt
|
||||
|
||||
If you want to revert this change and enable the compilation prompt then just run this command again with the `--activate` flag:
|
||||
|
||||
You may also want to run code generation manually once. It can be achieved by running this command:
|
||||
```sh
|
||||
./vendor/bin/retailcrm-client compiler:prompt --activate
|
||||
composer compile --all
|
||||
```
|
||||
|
||||
### Disable or enable compilation prompt manually
|
||||
**Note:** `retailcrm-client` should be in your binary directory. By default it is set to `vendor/bin`. You can check `config.bin-dir`
|
||||
value in your `composer.json` and update paths in the commands above accordingly.
|
||||
**Note (2):** `compiler:prompt` command has `--revert` flag. You can use it if you want to disable automatic code generation for some reason.
|
||||
|
||||
#### Enabling compilation prompt
|
||||
### Disabling compilation prompts manually
|
||||
|
||||
It is possible to replicate the same actions manually. Add these params into the `extra` segment of your `composer.json` if
|
||||
you want to execute code generation automatically after library installation or update.
|
||||
It is possible to replicate the same actions manually. First, you will need to enable compiler plugin. Add the plugin
|
||||
to the `config.allow-plugins` segment of your `composer.json` file:
|
||||
|
||||
```json
|
||||
"allow-plugins": {
|
||||
"civicrm/composer-compile-plugin": true
|
||||
}
|
||||
```
|
||||
|
||||
After that add these params into the `extra` segment of your `composer.json`:
|
||||
|
||||
```json
|
||||
"compile-mode": "whitelist",
|
||||
"compile-whitelist": ["retailcrm/api-client-php"]
|
||||
```
|
||||
|
||||
Your `composer.json` file will look like this:
|
||||
Your `composer.json` file should look like this:
|
||||
```json
|
||||
{
|
||||
"name": "author/some-project",
|
||||
@ -77,6 +94,11 @@ Your `composer.json` file will look like this:
|
||||
"nyholm/psr7": "^1.4",
|
||||
"retailcrm/api-client-php": "~6.0"
|
||||
},
|
||||
"config": {
|
||||
"allow-plugins": {
|
||||
"civicrm/composer-compile-plugin": true
|
||||
}
|
||||
},
|
||||
"extra": {
|
||||
"compile-mode": "whitelist",
|
||||
"compile-whitelist": ["retailcrm/api-client-php"]
|
||||
@ -85,7 +107,3 @@ Your `composer.json` file will look like this:
|
||||
```
|
||||
|
||||
Voilà! You won't see the annoying prompt again.
|
||||
|
||||
#### Enabling compilation prompt
|
||||
|
||||
Just remove `extra.compile-mode` and `extra.compile-whitelist` params from your `composer.json`.
|
||||
|
@ -1,8 +1,9 @@
|
||||
# Documentation
|
||||
|
||||
* [Compilation prompt](compilation_prompt.md)
|
||||
+ [Disable or enable compilation prompt via CLI](compilation_prompt.md#disable-or-enable-compilation-prompt-via-cli)
|
||||
+ [Disable or enable compilation prompt manually](compilation_prompt.md#disable-or-enable-compilation-prompt-manually)
|
||||
* [Dealing with `civicrm/composer-compile-plugin` prompts](compilation_prompt.md)
|
||||
+ [Disable compilation prompts during the installation](compilation_prompt.md#disable-compilation-prompts-during-the-installation)
|
||||
+ [I've chosen something else, now API client doesn't work!](compilation_prompt.md#ive-chosen-something-else-now-api-client-doesnt-work)
|
||||
+ [Disabling compilation prompts manually](compilation_prompt.md#disabling-compilation-prompts-manually)
|
||||
* [Client structure](structure.md)
|
||||
+ [Design principles](structure.md#design-principles)
|
||||
+ [Resource groups](structure.md#resource-groups)
|
||||
|
@ -16,37 +16,37 @@ parameters:
|
||||
path: src/Client.php
|
||||
|
||||
-
|
||||
message: "#^Cannot access offset 'compile\\-mode' on mixed\\.$#"
|
||||
count: 2
|
||||
path: src/Command/CompilerPromptCommand.php
|
||||
|
||||
-
|
||||
message: "#^Cannot access offset 'compile\\-whitelist' on mixed\\.$#"
|
||||
count: 2
|
||||
path: src/Command/CompilerPromptCommand.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$value of function count expects array\\|Countable, mixed given\\.$#"
|
||||
message: "#^Cannot assign new offset to array\\<string\\>\\|string\\.$#"
|
||||
count: 1
|
||||
path: src/Command/CompilerPromptCommand.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#2 \\$array of function array_key_exists expects array, mixed given\\.$#"
|
||||
message: "#^Parameter \\#1 \\$array of function array_filter expects array, string given\\.$#"
|
||||
count: 1
|
||||
path: src/Command/CompilerPromptCommand.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#2 \\$haystack of function in_array expects array, array\\<string\\>\\|string given\\.$#"
|
||||
count: 1
|
||||
path: src/Command/CompilerPromptCommand.php
|
||||
|
||||
-
|
||||
message: "#^Unsafe access to private constant RetailCrm\\\\Api\\\\Command\\\\CompilerPromptCommand\\:\\:COMPILER_PLUGIN through static\\:\\:\\.$#"
|
||||
count: 3
|
||||
path: src/Command/CompilerPromptCommand.php
|
||||
|
||||
-
|
||||
message: "#^Unsafe access to private constant RetailCrm\\\\Api\\\\Command\\\\CompilerPromptCommand\\:\\:PACKAGE_NAME through static\\:\\:\\.$#"
|
||||
count: 5
|
||||
path: src/Command/CompilerPromptCommand.php
|
||||
|
||||
-
|
||||
message: "#^Unsafe call to private method RetailCrm\\\\Api\\\\Command\\\\CompilerPromptCommand\\:\\:activatePrompt\\(\\) through static\\:\\:\\.$#"
|
||||
message: "#^Unsafe call to private method RetailCrm\\\\Api\\\\Command\\\\CompilerPromptCommand\\:\\:activateAutoCompiler\\(\\) through static\\:\\:\\.$#"
|
||||
count: 1
|
||||
path: src/Command/CompilerPromptCommand.php
|
||||
|
||||
-
|
||||
message: "#^Unsafe call to private method RetailCrm\\\\Api\\\\Command\\\\CompilerPromptCommand\\:\\:deactivatePrompt\\(\\) through static\\:\\:\\.$#"
|
||||
message: "#^Unsafe call to private method RetailCrm\\\\Api\\\\Command\\\\CompilerPromptCommand\\:\\:activatePlugin\\(\\) through static\\:\\:\\.$#"
|
||||
count: 1
|
||||
path: src/Command/CompilerPromptCommand.php
|
||||
|
||||
-
|
||||
message: "#^Unsafe call to private method RetailCrm\\\\Api\\\\Command\\\\CompilerPromptCommand\\:\\:deactivateAutoCompiler\\(\\) through static\\:\\:\\.$#"
|
||||
count: 1
|
||||
path: src/Command/CompilerPromptCommand.php
|
||||
|
||||
|
@ -25,6 +25,7 @@ use Symfony\Component\Console\Output\OutputInterface;
|
||||
class CompilerPromptCommand extends Command
|
||||
{
|
||||
private const PACKAGE_NAME = 'retailcrm/api-client-php';
|
||||
private const COMPILER_PLUGIN = 'civicrm/composer-compile-plugin';
|
||||
|
||||
/**
|
||||
* Sets description and help for a command.
|
||||
@ -32,20 +33,14 @@ class CompilerPromptCommand extends Command
|
||||
protected function configure(): void
|
||||
{
|
||||
$this->setName('compiler:prompt')
|
||||
->setDescription('Enable or disable composer compiler prompt.')
|
||||
->setHelp('Use this command to suppress the compiler message and enable automatic compilation.')
|
||||
->addOption(
|
||||
'deactivate',
|
||||
'd',
|
||||
->setDescription('Enable or disable code generation during client installation & update.')
|
||||
->setHelp(
|
||||
'Use this command to enable or disable automatic code generation.'
|
||||
)->addOption(
|
||||
'revert',
|
||||
'r',
|
||||
InputOption::VALUE_OPTIONAL,
|
||||
'Hide compiler prompt and run compiler task automatically. This mode is used by default.',
|
||||
false
|
||||
)
|
||||
->addOption(
|
||||
'activate',
|
||||
'a',
|
||||
InputOption::VALUE_OPTIONAL,
|
||||
'Show compiler prompt and only run compiler task if user allows it.',
|
||||
'You will need to run ./vendor/bin/retailcrm-client models:generate -a after each update.',
|
||||
false
|
||||
);
|
||||
}
|
||||
@ -78,12 +73,13 @@ class CompilerPromptCommand extends Command
|
||||
return -1;
|
||||
}
|
||||
|
||||
$activatePrompt = false !== $input->getOption('activate');
|
||||
$revert = false !== $input->getOption('revert');
|
||||
|
||||
if ($activatePrompt) {
|
||||
static::activatePrompt($json);
|
||||
if ($revert) {
|
||||
static::deactivateAutoCompiler($json);
|
||||
} else {
|
||||
static::deactivatePrompt($json);
|
||||
static::activateAutoCompiler($json);
|
||||
static::activatePlugin($json);
|
||||
}
|
||||
|
||||
try {
|
||||
@ -101,73 +97,110 @@ class CompilerPromptCommand extends Command
|
||||
}
|
||||
|
||||
$output->writeln(sprintf(
|
||||
'<fg=black;bg=green> ✓ Done, generator prompt is now %s.</>',
|
||||
$activatePrompt ? 'enabled' : 'disabled'
|
||||
'<fg=black;bg=green> ✓ Done, code generation has been %s.</>',
|
||||
$revert ? 'disabled' : 'enabled'
|
||||
));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Activate prompt in the provided composer.json
|
||||
* Activate plugin in the provided composer.json
|
||||
*
|
||||
* @param array<string, mixed> $composerJson
|
||||
* @param array<string, array<string, array<string>|string>> $composerJson
|
||||
*/
|
||||
private static function activatePrompt(array &$composerJson): void
|
||||
private static function activatePlugin(array &$composerJson): void
|
||||
{
|
||||
if (!array_key_exists('config', $composerJson)) {
|
||||
$composerJson['config'] = [
|
||||
'allow-plugins' => [
|
||||
static::COMPILER_PLUGIN => true
|
||||
]
|
||||
];
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!array_key_exists('allow-plugins', $composerJson['config'])) {
|
||||
$composerJson['config']['allow-plugins'] = [
|
||||
static::COMPILER_PLUGIN => true
|
||||
];
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$composerJson['config']['allow-plugins'][static::COMPILER_PLUGIN] = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Activate auto compiler in the provided composer.json
|
||||
*
|
||||
* @param array<string, array<string, array<string>|string>> $composerJson
|
||||
*/
|
||||
private static function activateAutoCompiler(array &$composerJson): void
|
||||
{
|
||||
if (!array_key_exists('extra', $composerJson)) {
|
||||
$composerJson['extra'] = [];
|
||||
$composerJson['extra'] = [
|
||||
'compile-mode' => 'whitelist',
|
||||
'compile-whitelist' => [self::PACKAGE_NAME]
|
||||
];
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (array_key_exists('compile-mode', $composerJson['extra'])) {
|
||||
if (
|
||||
array_key_exists('compile-whitelist', $composerJson['extra']) &&
|
||||
is_array($composerJson['extra']['compile-whitelist']) &&
|
||||
in_array(static::PACKAGE_NAME, $composerJson['extra']['compile-whitelist'], true)
|
||||
'prompt' === $composerJson['extra']['compile-mode'] ||
|
||||
'none' === $composerJson['extra']['compile-mode']
|
||||
) {
|
||||
$composerJson['extra']['compile-whitelist'] = array_filter(
|
||||
$composerJson['extra']['compile-whitelist'],
|
||||
static function ($value) {
|
||||
return static::PACKAGE_NAME !== $value;
|
||||
}
|
||||
);
|
||||
$composerJson['extra']['compile-mode'] = 'whitelist';
|
||||
}
|
||||
|
||||
if (
|
||||
empty($composerJson['extra']['compile-whitelist']) &&
|
||||
array_key_exists('compile-mode', $composerJson['extra']) &&
|
||||
'whitelist' === $composerJson['extra']['compile-mode']
|
||||
) {
|
||||
unset($composerJson['extra']['compile-whitelist'], $composerJson['extra']['compile-mode']);
|
||||
if ('all' === $composerJson['extra']['compile-mode']) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (1 === count($composerJson['extra'])) {
|
||||
unset($composerJson['extra']);
|
||||
$composerJson['extra']['compile-mode'] = 'whitelist';
|
||||
|
||||
if (!array_key_exists('compile-whitelist', $composerJson['extra'])) {
|
||||
$composerJson['extra']['compile-whitelist'] = [self::PACKAGE_NAME];
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!in_array(self::PACKAGE_NAME, $composerJson['extra']['compile-whitelist'])) {
|
||||
$composerJson['extra']['compile-whitelist'][] = self::PACKAGE_NAME;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deactivate prompt in the provided composer.json
|
||||
*
|
||||
* @param array<string, mixed> $composerJson
|
||||
* @param array<string, array<string>> $composerJson
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.ElseExpression)
|
||||
*/
|
||||
private static function deactivatePrompt(array &$composerJson): void
|
||||
private static function deactivateAutoCompiler(array &$composerJson): void
|
||||
{
|
||||
if (!array_key_exists('extra', $composerJson)) {
|
||||
$composerJson['extra'] = [];
|
||||
return;
|
||||
}
|
||||
|
||||
if (
|
||||
array_key_exists('compile-whitelist', $composerJson['extra']) &&
|
||||
is_array($composerJson['extra']['compile-whitelist']) &&
|
||||
!in_array(static::PACKAGE_NAME, $composerJson['extra']['compile-whitelist'], true)
|
||||
null !== $composerJson['extra']['compile-whitelist']
|
||||
) {
|
||||
$composerJson['extra']['compile-whitelist'][] = static::PACKAGE_NAME;
|
||||
} else {
|
||||
$composerJson['extra']['compile-whitelist'] = [static::PACKAGE_NAME];
|
||||
$composerJson['extra']['compile-whitelist'] = array_filter(
|
||||
$composerJson['extra']['compile-whitelist'],
|
||||
static function (string $item) {
|
||||
return $item !== self::PACKAGE_NAME;
|
||||
}
|
||||
);
|
||||
|
||||
$composerJson['extra']['compile-mode'] = 'whitelist';
|
||||
if (0 === count($composerJson['extra']['compile-whitelist'])) {
|
||||
unset($composerJson['extra']['compile-whitelist']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -67,7 +67,7 @@ class ComposerLocator
|
||||
$counter++;
|
||||
$dir = dirname($dir);
|
||||
|
||||
if (5 < $counter) {
|
||||
if (2 < $counter) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -80,7 +80,9 @@ class ComposerLocator
|
||||
*/
|
||||
private static function getBaseDirectory(): string
|
||||
{
|
||||
return (string) realpath(implode(DIRECTORY_SEPARATOR, [__DIR__, '..', '..']));
|
||||
$cwd = getcwd();
|
||||
|
||||
return false === $cwd ? (string) realpath(implode(DIRECTORY_SEPARATOR, [__DIR__, '..', '..'])) : $cwd;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -54,12 +54,12 @@ class CompilerPromptCommandTest extends TestCase
|
||||
}
|
||||
}
|
||||
|
||||
public function testDeactivate(): void
|
||||
public function testEnable(): void
|
||||
{
|
||||
$tester = new CommandTester(new CompilerPromptCommand());
|
||||
$tester->execute([]);
|
||||
|
||||
self::assertStringContainsString('Done, generator prompt is now disabled', $tester->getDisplay());
|
||||
self::assertStringContainsString('Done, code generation has been enabled', $tester->getDisplay());
|
||||
|
||||
$composerJson = static::getComposerJson();
|
||||
|
||||
@ -70,17 +70,16 @@ class CompilerPromptCommandTest extends TestCase
|
||||
self::assertEquals(['retailcrm/api-client-php'], $composerJson['extra']['compile-whitelist']);
|
||||
}
|
||||
|
||||
public function testActivate(): void
|
||||
public function testRevert(): void
|
||||
{
|
||||
$tester = new CommandTester(new CompilerPromptCommand());
|
||||
$tester->execute(['--activate' => '']);
|
||||
$tester->execute(['--revert' => '']);
|
||||
|
||||
self::assertStringContainsString('Done, generator prompt is now enabled', $tester->getDisplay());
|
||||
self::assertStringContainsString('Done, code generation has been disabled', $tester->getDisplay());
|
||||
|
||||
$composerJson = static::getComposerJson();
|
||||
|
||||
self::assertArrayHasKey('extra', $composerJson);
|
||||
self::assertArrayNotHasKey('compile-mode', $composerJson['extra']);
|
||||
self::assertArrayNotHasKey('compile-whitelist', $composerJson['extra']);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user