-
Notifications
You must be signed in to change notification settings - Fork 0
Add run-template:clone command #56
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,85 @@ | ||
| <?php | ||
|
|
||
| declare(strict_types=1); | ||
|
|
||
| /** | ||
| * This file is part of the MultiFlexi package | ||
| * | ||
| * https://multiflexi.eu/ | ||
| * | ||
| * (c) Vítězslav Dvořák <http://vitexsoftware.com> | ||
| * | ||
| * For the full copyright and license information, please view the LICENSE | ||
| * file that was distributed with this source code. | ||
| */ | ||
|
|
||
| namespace MultiFlexi\Cli\Command\RunTemplate; | ||
|
|
||
| use MultiFlexi\RunTemplate; | ||
| use Symfony\Component\Console\Input\InputInterface; | ||
| use Symfony\Component\Console\Input\InputOption; | ||
| use Symfony\Component\Console\Output\OutputInterface; | ||
|
|
||
| class CloneCommand extends BaseCommand | ||
| { | ||
| protected static $defaultName = 'run-template:clone'; | ||
|
|
||
| protected function configure(): void | ||
| { | ||
| $this | ||
| ->setName('run-template:clone') | ||
| ->setDescription('Clone a run template; the clone is always created disabled') | ||
| ->addOption('format', 'f', InputOption::VALUE_OPTIONAL, 'Output format: text or json', 'text') | ||
| ->addOption('id', null, InputOption::VALUE_REQUIRED, 'Source RunTemplate ID') | ||
| ->addOption('name', null, InputOption::VALUE_OPTIONAL, 'Name for the clone (default: "<source name> Clone")'); | ||
|
Comment on lines
+31
to
+34
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win Translate all user-visible strings. Only As per coding guidelines, Also applies to: 44-46, 56-59, 64-64, 69-71, 78-80 🤖 Prompt for AI AgentsSource: Coding guidelines |
||
| } | ||
|
|
||
| protected function execute(InputInterface $input, OutputInterface $output): int | ||
|
Comment on lines
+23
to
+37
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win Add docblocks for the class and methods.
As per coding guidelines, 🤖 Prompt for AI AgentsSource: Coding guidelines |
||
| { | ||
| $format = strtolower($input->getOption('format')); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win Reject unsupported output formats.
🤖 Prompt for AI Agents |
||
| $id = $input->getOption('id'); | ||
|
|
||
| if (empty($id)) { | ||
| if ($format === 'json') { | ||
| $output->writeln(json_encode(['status' => 'error', 'message' => 'Missing --id'], \JSON_PRETTY_PRINT)); | ||
| } else { | ||
| $output->writeln('<error>Missing --id</error>'); | ||
| } | ||
|
|
||
| return self::FAILURE; | ||
| } | ||
|
|
||
| $source = new RunTemplate((int) $id); | ||
|
Comment on lines
+40
to
+52
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win Validate the source ID before casting it.
🤖 Prompt for AI Agents |
||
|
|
||
| if (empty($source->getMyKey())) { | ||
| if ($format === 'json') { | ||
| $output->writeln(json_encode(['status' => 'error', 'message' => 'RunTemplate not found'], \JSON_PRETTY_PRINT)); | ||
| } else { | ||
| $output->writeln('<error>RunTemplate not found: '.$id.'</error>'); | ||
| } | ||
|
|
||
| return self::FAILURE; | ||
| } | ||
|
|
||
| $newName = $input->getOption('name') ?: $source->getRecordName().' '._('Clone'); | ||
| $newId = $source->cloneAs($newName); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
# Verify the resolved core dependency and inspect available clone-state handling.
rg -n -C 6 '"vitexsoftware/multiflexi-core"|cloneAs\s*\(|setActive\s*\(|\bactive\b' \
. -g 'composer.json' -g 'composer.lock' -g '*.php' || trueRepository: VitexSoftware/multiflexi-cli Length of output: 21125 🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '%s\n' '--- CloneCommand.php ---'
cat -n src/Command/RunTemplate/CloneCommand.php
printf '%s\n' '--- locked dependency metadata ---'
sed -n '3568,3595p' composer.lock
printf '%s\n' '--- upstream cloneAs references at the locked commit ---'
commit='80eefa9362998179f5c68374ec5dc77fd605cc57'
curl --fail --silent --show-error \
"https://api.github.com/repos/VitexSoftware/php-vitexsoftware-multiflexi-core/commits/${commit}" |
jq -r '.sha, .html_url, (.files[]?.filename)' | head -80
curl --fail --silent --show-error \
"https://api.github.com/repos/VitexSoftware/php-vitexsoftware-multiflexi-core/git/trees/${commit}?recursive=1" |
jq -r '.tree[] | select(.path | endswith(".php")) | .path' |
while IFS= read -r path; do
content_url="https://raw.githubusercontent.com/VitexSoftware/php-vitexsoftware-multiflexi-core/${commit}/${path}"
body="$(curl --fail --silent --show-error "$content_url" || true)"
if printf '%s' "$body" | grep -qE 'cloneAs|class RunTemplate'; then
printf '%s\n' "--- ${path} ---"
printf '%s\n' "$body" | grep -n -C 12 -E 'cloneAs|class RunTemplate'
fi
doneRepository: VitexSoftware/multiflexi-cli Length of output: 5049 🏁 Script executed: #!/bin/bash
set -u
repo='VitexSoftware/php-vitexsoftware-multiflexi-core'
commit='80eefa9362998179f5c68374ec5dc77fd605cc57'
printf '%s\n' '--- exact commit API response ---'
curl -sS -w '\nHTTP %{http_code}\n' \
"https://api.github.com/repos/${repo}/commits/${commit}" |
jq '{sha, message: .commit.message, url: .html_url, status: .status, documentation_url, message_error: .message}'
printf '%s\n' '--- remote refs ---'
git ls-remote --heads --tags "https://github.com/${repo}.git" 2>&1 |
grep -E 'refs/(heads/(main|master|dev-main)|tags/)' | tail -80
printf '%s\n' '--- current dev-main tree paths ---'
curl -sS --fail --show-error \
"https://api.github.com/repos/${repo}/git/trees/dev-main?recursive=1" |
jq -r '.tree[]?.path' | grep -E '\.php$' | head -200
printf '%s\n' '--- current dev-main cloneAs references ---'
curl -sS --fail --show-error \
"https://api.github.com/repos/${repo}/search/code?q=cloneAs+repo:${repo}" |
jq -r '.items[]?.html_url' 2>/dev/null || trueRepository: VitexSoftware/multiflexi-cli Length of output: 878 🏁 Script executed: #!/bin/bash
set -euo pipefail
repo='VitexSoftware/php-vitexsoftware-multiflexi-core'
branch='main'
curl --fail --silent --show-error \
"https://api.github.com/repos/${repo}/git/trees/${branch}?recursive=1" |
jq -r '.tree[] | select(.type == "blob") | .path' |
tee /tmp/multiflexi-core-php-paths.txt |
grep -Ei 'run.?template|template|\.php$' |
head -250
printf '%s\n' '--- candidate source excerpts ---'
while IFS= read -r path; do
case "$path" in
*[Rr]un*[Tt]emplate*.php|*runtemplate*.php|*RunTemplate*.php)
url="https://raw.githubusercontent.com/${repo}/${branch}/${path}"
body="$(curl --fail --silent --show-error "$url")"
if printf '%s' "$body" | grep -qE 'cloneAs|class RunTemplate'; then
printf '%s\n' "--- ${path} ---"
printf '%s\n' "$body" | grep -n -C 20 -E 'cloneAs|class RunTemplate'
fi
;;
esac
done < /tmp/multiflexi-core-php-paths.txtRepository: VitexSoftware/multiflexi-cli Length of output: 204 🏁 Script executed: #!/bin/bash
set -euo pipefail
repo='VitexSoftware/php-vitexsoftware-multiflexi-core'
branch='main'
tree_file=/tmp/multiflexi-core-tree.json
curl --fail --silent --show-error \
"https://api.github.com/repos/${repo}/git/trees/${branch}?recursive=1" > "$tree_file"
printf '%s\n' '--- candidate paths ---'
jq -r '.tree[] | select(.type == "blob") | .path' "$tree_file" |
grep -Ei 'run.?template|template|\.php$' |
head -250
printf '%s\n' '--- candidate source excerpts ---'
jq -r '.tree[] | select(.type == "blob") | .path' "$tree_file" |
while IFS= read -r path; do
case "$path" in
*[Rr]un*[Tt]emplate*.php|*runtemplate*.php|*RunTemplate*.php)
url="https://raw.githubusercontent.com/${repo}/${branch}/${path}"
body="$(curl --fail --silent --show-error "$url")"
if printf '%s' "$body" | grep -qE 'cloneAs|class RunTemplate'; then
printf '%s\n' "--- ${path} ---"
printf '%s\n' "$body" | grep -n -C 20 -E 'cloneAs|class RunTemplate'
fi
;;
esac
doneRepository: VitexSoftware/multiflexi-cli Length of output: 12259 🏁 Script executed: #!/bin/bash
set -euo pipefail
repo='VitexSoftware/php-vitexsoftware-multiflexi-core'
for ref in main v2.9.3; do
file="/tmp/multiflexi-core-RunTemplate-${ref}.php"
curl --fail --silent --show-error \
"https://raw.githubusercontent.com/${repo}/${ref}/src/MultiFlexi/RunTemplate.php" > "$file"
printf '%s\n' "--- ${ref}: clone-related methods and active assignments ---"
grep -n -C 12 -Ei 'function[[:space:]]+[^ (]*clone|cloneAs|active|setDataValue|save' "$file" || true
done
printf '%s\n' '--- direct existence check ---'
for ref in main v2.9.3; do
url="https://raw.githubusercontent.com/${repo}/${ref}/src/MultiFlexi/RunTemplate.php"
if curl --fail --silent --show-error "$url" | grep -qE 'function[[:space:]]+cloneAs[[:space:]]*\('; then
printf '%s: cloneAs present\n' "$ref"
else
printf '%s: cloneAs absent\n' "$ref"
fi
doneRepository: VitexSoftware/multiflexi-cli Length of output: 15773 🏁 Script executed: #!/bin/bash
set -euo pipefail
repo='VitexSoftware/php-vitexsoftware-multiflexi-core'
ref='main'
tree_file=/tmp/multiflexi-core-tree.json
printf '%s\n' '--- DBEngine clone-related methods ---'
curl --fail --silent --show-error \
"https://raw.githubusercontent.com/${repo}/${ref}/src/MultiFlexi/DBEngine.php" |
grep -n -C 20 -Ei 'function[[:space:]]+[^ (]*clone|cloneAs|clone|active|setDataValue' || true
printf '%s\n' '--- all upstream source references to cloneAs ---'
jq -r '.tree[] | select(.type == "blob" and (.path | startswith("src/")) and (.path | endswith(".php"))) | .path' "$tree_file" |
while IFS= read -r path; do
url="https://raw.githubusercontent.com/${repo}/${ref}/${path}"
body="$(curl --fail --silent --show-error "$url")"
if printf '%s' "$body" | grep -qEi 'cloneAs'; then
printf '%s\n' "--- ${path} ---"
printf '%s\n' "$body" | grep -n -C 15 -Ei 'cloneAs'
fi
doneRepository: VitexSoftware/multiflexi-cli Length of output: 255 Align the multiflexi-core dependency before calling 🤖 Prompt for AI AgentsSource: Coding guidelines |
||
|
|
||
| if (!$newId) { | ||
| if ($format === 'json') { | ||
| $output->writeln(json_encode(['status' => 'error', 'message' => 'Failed to create clone'], \JSON_PRETTY_PRINT)); | ||
| } else { | ||
| $output->writeln('<error>Failed to create clone</error>'); | ||
| } | ||
|
|
||
| return self::FAILURE; | ||
| } | ||
|
|
||
| if ($format === 'json') { | ||
| $output->writeln(json_encode(['runtemplate_id' => $newId, 'name' => $newName, 'active' => false], \JSON_PRETTY_PRINT)); | ||
| } else { | ||
| $output->writeln("RunTemplate cloned as ID: {$newId} (disabled — review and enable when ready)"); | ||
| } | ||
|
|
||
| return self::SUCCESS; | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift
Add PHPUnit coverage for the new command.
The provided changes add
CloneCommandwithout its PHPUnit test file. Test invalid IDs, output formats, clone failures, and that an active source creates an inactive clone.As per coding guidelines, create or update a PHPUnit test file whenever a class is created or updated.
🤖 Prompt for AI Agents
Source: Coding guidelines