jolicode / castor Goto Github PK
View Code? Open in Web Editor NEW𦫠DX oriented task runner and command launcher built with PHP.
Home Page: https://castor.jolicode.com
License: MIT License
𦫠DX oriented task runner and command launcher built with PHP.
Home Page: https://castor.jolicode.com
License: MIT License
I wanted to install castor via composer (globally).
The documentation said the package will be available from here:
Then make sure that the Composer global bin directory is in your PATH:
export PATH="$HOME/.composer/vendor/bin:$PATH"
But it did not work.
I saw the stackoverflow article to see the configured composer global path via: composer config --list --global
that resulted in:
// other lines...
[home] /home/<user>/.config/composer
So at least in my setup I needed to export PATH="$HOME/.config/composer/vendor/bin:$PATH"
.
I am not a composer expert, just a "user" so I am not sure if this is just a Linux thing, or did I configured it in the past to be in this path... I don't know.
At least I wanted to share this with you guys, so probably when this is the "new composer standard" we could change it in the docs.
If the strange configuration is just my user error, please bear with me - I'm sorry.
Hello,
Is it normal for the documentation to be deployed independently of the release of GitHub ?
For example, documentation on installation via installer is currently present see here, but should only appear when release 0.15 comes out, right? (even if it works in the current case).
If a new feature is deployed, the documentation will be ahead of the release ^^
Trying out a command that streams a long JSON blob. But I notice that it's been cut off after 1500 lines.
Upon inspection I see that the last 12 lines are missing.
The command did successfully stop.
Using parallel()
make the output empty until the first task is done. We could provide a spinner to inform user the tasks are running.
Hey there!
I'd like to gather your thoughts on adopting a class-based approach. By the "class approach," I mean structuring our code like this:
symfony()->loco()->pull();
This approach is currently possible with version 0.8 of Castor. However, when it comes to exposing task symfony:loco:pull
of methods in objects, it's not currently feasible.
And for now for exposing this i need to "repeat" it like this :
#[AsTask(name: 'pull', namespace: 'loco', description: 'Download translations from Loco.')]
function locoPull(): Process
{
return symfony()->loco()->pull();
}
Let's consider the following implementation:
Symfony.php
#[AsTaskClass(namespace: 'symfony')]
class Symfony
{
private string $cmd = 'php bin/console';
public function console(
string $command,
array $args = [],
array $options = []
): Process {
$cmd = "{$this->cmd} {$command}";
// Add some logic for options and args
return docker()->exec($cmd, interactive: true, tty: true);
}
public function loco(): Loco
{
return new Loco();
}
}
function symfony(): Symfony
{
return new Symfony();
}
Loco.php
#[AsTaskClass(namespace: 'symfony:loco')]
class Loco
{
public function __construct() // Not usable if we use static
{
$context = context();
if (!is_dir($context->currentDirectory . '/vendor/symfony/loco-translation-provider')) {
io()->error("Loco translation provider is not installed in {$context->data['name']}.");
exit(1);
}
}
#[AsTask(description: 'Pull loco translation')]
public static function pull(string $format = 'json'): \Symfony\Component\Process\Process
{
io()->section('Pulling translations from Loco');
return symfony()->console("translation:pull --format={$format}");
}
#[AsTask(description: 'Push loco translation')]
public static function push(): \Symfony\Component\Process\Process
{
io()->section('Pushing translations to Loco');
return symfony()->console('translation:push');
}
}
This will provide the Castor commands in the same way as the current flow:
As of today, it is not possible to use AsTask
in objects because doFindFunctions
searches only for functions in get_defined_functions()
of the user.
One reason I used this approach is to allow sending custom context and params like this if needed, and in case none are sent, we are using the default context:
symfony(ctx: my_project(), tenant: 'MY_TENANT')->console('create:user --email [email protected]');
I've started some things that work fine. Please take a look and review here: GitHub Link
If the approach is appreciated, I'm happy to open a new PR! π
Actually, I catch all public static methods
of the class. Using non-static methods is doable, but I didn't know at the moment what the best approach is. Let me know what you think.
Non-static can be useful, like in Loco::__construct() where i check if library is available before any methods call
You might be wondering why I'm suggesting this approach instead of using namespaces like \symfony\loco\pull();
. I believe that the current way, utilizing class methods, offers better readability and maintainability for our codebase.
Feel free to share your thoughts and concerns regarding this proposal!
Homebrew is a popular package manager on macOS. It would be great if there was a home-brew tap for castor to install and keep it up to date.
Hello, I tried to include castor.php in the PHPStan analysis and there are errors because of the .castor.stub.php
file.
PHPStan setup :
parameters:
level: max
paths:
- castor.php
- config
- public
- src
- tests
symfony:
container_xml_path: var/cache/dev/App_KernelDevDebugContainer.xml
# https://phpstan.org/user-guide/stub-files
stubFiles:
- .castor.stub.php
[16:57:54] coil@localdomain:/Users/coil/MicroSymfony$ castor cs:stan
stan
====
Run PHPStan
-----------
Result cache not used because the metadata do not match.
20/20 [ββββββββββββββββββββββββββββ] 100% 3 secs/3 secs
Result cache is saved.
------ -----------------------------------------------------------------------
Line .castor.stub.php
------ -----------------------------------------------------------------------
9 Method Castor\Attribute\AsArgument::__construct() has parameter
$suggestedValues with no value type specified in iterable type array.
35 Method Castor\Attribute\AsOption::__construct() has parameter
$shortcut with no value type specified in iterable type array.
35 Method Castor\Attribute\AsOption::__construct() has parameter
$suggestedValues with no value type specified in iterable type array.
44 Method Castor\Attribute\AsTask::__construct() has parameter $aliases
with no value type specified in iterable type array.
79 Method Castor\Console\ApplicationFactory::create() has invalid return
type Symfony\Component\Console\SingleCommandApplication.
79 Parameter $logger of method
Castor\Console\ApplicationFactory::create() has invalid type
Psr\Log\LoggerInterface.
85 Class Castor\Console\Command\CastorFileNotFoundCommand extends
unknown class Symfony\Component\Console\SingleCommandApplication.
102 Property Castor\Console\Command\TaskCommand::$argumentsMap type has
no value type specified in iterable type array.
121 Class Castor\Context implements generic interface ArrayAccess but
does not specify its types: TKey, TValue
124 Method Castor\Context::__construct() has parameter $data with no
value type specified in iterable type array.
124 Method Castor\Context::__construct() has parameter $environment with
no value type specified in iterable type array.
127 Method Castor\Context::withData() has parameter $data with no value
type specified in iterable type array.
130 Method Castor\Context::withEnvironment() has parameter $environment
with no value type specified in iterable type array.
182 Property Castor\ContextRegistry::$descriptors type has no value type
specified in iterable type array.
196 Method Castor\ContextRegistry::getNames() return type has no value
type specified in iterable type array.
205 Method Castor\FunctionFinder::findFunctions() return type has no
value type specified in iterable type iterable.
211 Method Castor\FunctionFinder::doFindFunctions() has parameter $files
with no value type specified in iterable type iterable.
211 Method Castor\FunctionFinder::doFindFunctions() return type has no
value type specified in iterable type iterable.
223 Property Castor\GlobalHelper::$logger has unknown class
Psr\Log\LoggerInterface as its type.
230 Parameter $logger of method Castor\GlobalHelper::setLogger() has
invalid type Psr\Log\LoggerInterface.
233 Method Castor\GlobalHelper::getLogger() has invalid return type
Psr\Log\LoggerInterface.
252 Property Castor\SluggerHelper::$slugger has unknown class
Symfony\Component\String\Slugger\AsciiSlugger as its type.
259 Class Castor\Stub\NodeVisitor extends unknown class
PhpParser\NodeVisitorAbstract.
261 Property Castor\Stub\NodeVisitor::$currentUseStatements type has no
value type specified in iterable type array.
262 Method Castor\Stub\NodeVisitor::enterNode() has invalid return type
PhpParser\Node.
262 Parameter $node of method Castor\Stub\NodeVisitor::enterNode() has
invalid type PhpParser\Node.
265 Parameter $node of method Castor\Stub\NodeVisitor::leaveNode() has
invalid type PhpParser\Node.
322 Function Castor\parallel() return type has no value type specified in
iterable type array.
325 Function Castor\run() has parameter $command with no value type
specified in iterable type array.
325 Function Castor\run() has parameter $environment with no value type
specified in iterable type array.
334 Function Castor\log() has parameter $context with no value type
specified in iterable type array.
348 Class Symfony\Component\Console\Application implements unknown
interface Symfony\Contracts\Service\ResetInterface.
350 Property Symfony\Component\Console\Application::$commands type has no
value type specified in iterable type array.
355 Property Symfony\Component\Console\Application::$commandLoader has
unknown class
Symfony\Component\Console\CommandLoader\CommandLoaderInterface as its
type.
358 Property Symfony\Component\Console\Application::$definition has
unknown class Symfony\Component\Console\Input\InputDefinition as its
type.
359 Property Symfony\Component\Console\Application::$helperSet has
unknown class Symfony\Component\Console\Helper\HelperSet as its type.
361 Property Symfony\Component\Console\Application::$terminal has unknown
class Symfony\Component\Console\Terminal as its type.
365 Property Symfony\Component\Console\Application::$signalRegistry has
unknown class Symfony\Component\Console\SignalRegistry\SignalRegistry
as its type.
366 Property
Symfony\Component\Console\Application::$signalsToDispatchEvent type
has no value type specified in iterable type array.
373 Method Symfony\Component\Console\Application::setCommandLoader() has
no return type specified.
373 Parameter $commandLoader of method
Symfony\Component\Console\Application::setCommandLoader() has invalid
type Symfony\Component\Console\CommandLoader\CommandLoaderInterface.
376 Method Symfony\Component\Console\Application::getSignalRegistry() has
invalid return type
Symfony\Component\Console\SignalRegistry\SignalRegistry.
379 Method
Symfony\Component\Console\Application::setSignalsToDispatchEvent()
has no return type specified.
385 Method Symfony\Component\Console\Application::doRun() has no return
type specified.
388 Method Symfony\Component\Console\Application::reset() has no return
type specified.
391 Method Symfony\Component\Console\Application::setHelperSet() has no
return type specified.
391 Parameter $helperSet of method
Symfony\Component\Console\Application::setHelperSet() has invalid
type Symfony\Component\Console\Helper\HelperSet.
394 Method Symfony\Component\Console\Application::getHelperSet() has
invalid return type Symfony\Component\Console\Helper\HelperSet.
397 Method Symfony\Component\Console\Application::setDefinition() has no
return type specified.
397 Parameter $definition of method
Symfony\Component\Console\Application::setDefinition() has invalid
type Symfony\Component\Console\Input\InputDefinition.
400 Method Symfony\Component\Console\Application::getDefinition() has
invalid return type Symfony\Component\Console\Input\InputDefinition.
403 Parameter $input of method
Symfony\Component\Console\Application::complete() has invalid type
Symfony\Component\Console\Completion\CompletionInput.
403 Parameter $suggestions of method
Symfony\Component\Console\Application::complete() has invalid type
Symfony\Component\Console\Completion\CompletionSuggestions.
412 Method Symfony\Component\Console\Application::setCatchExceptions()
has no return type specified.
418 Method Symfony\Component\Console\Application::setAutoExit() has no
return type specified.
424 Method Symfony\Component\Console\Application::setName() has no return
type specified.
430 Method Symfony\Component\Console\Application::setVersion() has no
return type specified.
433 Method Symfony\Component\Console\Application::getLongVersion() has no
return type specified.
439 Method Symfony\Component\Console\Application::addCommands() has no
return type specified.
439 Method Symfony\Component\Console\Application::addCommands() has
parameter $commands with no value type specified in iterable type
array.
442 Method Symfony\Component\Console\Application::add() has no return
type specified.
445 Method Symfony\Component\Console\Application::get() has no return
type specified.
451 Method Symfony\Component\Console\Application::getNamespaces() return
type has no value type specified in iterable type array.
457 Method Symfony\Component\Console\Application::find() has no return
type specified.
460 Method Symfony\Component\Console\Application::all() has no return
type specified.
463 Method Symfony\Component\Console\Application::getAbbreviations() has
parameter $names with no value type specified in iterable type array.
463 Method Symfony\Component\Console\Application::getAbbreviations()
return type has no value type specified in iterable type array.
472 Method Symfony\Component\Console\Application::configureIO() has no
return type specified.
475 Method Symfony\Component\Console\Application::doRunCommand() has no
return type specified.
481 Method
Symfony\Component\Console\Application::getDefaultInputDefinition()
has invalid return type
Symfony\Component\Console\Input\InputDefinition.
484 Method Symfony\Component\Console\Application::getDefaultCommands()
return type has no value type specified in iterable type array.
487 Method Symfony\Component\Console\Application::getDefaultHelperSet()
has invalid return type Symfony\Component\Console\Helper\HelperSet.
490 Method
Symfony\Component\Console\Application::getAbbreviationSuggestions()
has parameter $abbrevs with no value type specified in iterable type
array.
496 Method Symfony\Component\Console\Application::findAlternatives() has
parameter $collection with no value type specified in iterable type
iterable.
496 Method Symfony\Component\Console\Application::findAlternatives()
return type has no value type specified in iterable type array.
505 Method Symfony\Component\Console\Application::splitStringByWidth()
return type has no value type specified in iterable type array.
508 Method Symfony\Component\Console\Application::extractAllNamespaces()
return type has no value type specified in iterable type array.
524 Property Symfony\Component\Console\Input\InputArgument::$default type
has no value type specified in iterable type array.
525 Property
Symfony\Component\Console\Input\InputArgument::$suggestedValues type
has no value type specified in iterable type array.
527 Method Symfony\Component\Console\Input\InputArgument::__construct()
has parameter $default with no value type specified in iterable type
array.
527 Method Symfony\Component\Console\Input\InputArgument::__construct()
has parameter $suggestedValues with no value type specified in
iterable type array.
539 Method Symfony\Component\Console\Input\InputArgument::setDefault()
has no return type specified.
539 Method Symfony\Component\Console\Input\InputArgument::setDefault()
has parameter $default with no value type specified in iterable type
array.
542 Method Symfony\Component\Console\Input\InputArgument::getDefault()
return type has no value type specified in iterable type array.
548 Parameter $input of method
Symfony\Component\Console\Input\InputArgument::complete() has invalid
type Symfony\Component\Console\Completion\CompletionInput.
548 Parameter $suggestions of method
Symfony\Component\Console\Input\InputArgument::complete() has invalid
type Symfony\Component\Console\Completion\CompletionSuggestions.
562 Method
Symfony\Component\Console\Input\InputInterface::hasParameterOption()
has parameter $values with no value type specified in iterable type
array.
565 Method
Symfony\Component\Console\Input\InputInterface::getParameterOption()
has no return type specified.
565 Method
Symfony\Component\Console\Input\InputInterface::getParameterOption()
has parameter $default with no value type specified in iterable type
array.
565 Method
Symfony\Component\Console\Input\InputInterface::getParameterOption()
has parameter $values with no value type specified in iterable type
array.
568 Method Symfony\Component\Console\Input\InputInterface::bind() has no
return type specified.
568 Parameter $definition of method
Symfony\Component\Console\Input\InputInterface::bind() has invalid
type Symfony\Component\Console\Input\InputDefinition.
571 Method Symfony\Component\Console\Input\InputInterface::validate() has
no return type specified.
574 Method Symfony\Component\Console\Input\InputInterface::getArguments()
return type has no value type specified in iterable type array.
577 Method Symfony\Component\Console\Input\InputInterface::getArgument()
has no return type specified.
580 Method Symfony\Component\Console\Input\InputInterface::setArgument()
has no return type specified.
586 Method Symfony\Component\Console\Input\InputInterface::getOptions()
return type has no value type specified in iterable type array.
589 Method Symfony\Component\Console\Input\InputInterface::getOption()
has no return type specified.
592 Method Symfony\Component\Console\Input\InputInterface::setOption()
has no return type specified.
601 Method
Symfony\Component\Console\Input\InputInterface::setInteractive() has
no return type specified.
615 Property Symfony\Component\Console\Input\InputOption::$shortcut type
has no value type specified in iterable type array.
617 Property Symfony\Component\Console\Input\InputOption::$default type
has no value type specified in iterable type array.
618 Property
Symfony\Component\Console\Input\InputOption::$suggestedValues type
has no value type specified in iterable type array.
620 Method Symfony\Component\Console\Input\InputOption::__construct() has
parameter $default with no value type specified in iterable type
array.
620 Method Symfony\Component\Console\Input\InputOption::__construct() has
parameter $shortcut with no value type specified in iterable type
array.
620 Method Symfony\Component\Console\Input\InputOption::__construct() has
parameter $suggestedValues with no value type specified in iterable
type array.
644 Method Symfony\Component\Console\Input\InputOption::setDefault() has
no return type specified.
644 Method Symfony\Component\Console\Input\InputOption::setDefault() has
parameter $default with no value type specified in iterable type
array.
647 Method Symfony\Component\Console\Input\InputOption::getDefault()
return type has no value type specified in iterable type array.
656 Parameter $input of method
Symfony\Component\Console\Input\InputOption::complete() has invalid
type Symfony\Component\Console\Completion\CompletionInput.
656 Parameter $suggestions of method
Symfony\Component\Console\Input\InputOption::complete() has invalid
type Symfony\Component\Console\Completion\CompletionSuggestions.
675 Method Symfony\Component\Console\Output\OutputInterface::write() has
no return type specified.
675 Method Symfony\Component\Console\Output\OutputInterface::write() has
parameter $messages with no value type specified in iterable type
iterable.
678 Method Symfony\Component\Console\Output\OutputInterface::writeln()
has no return type specified.
678 Method Symfony\Component\Console\Output\OutputInterface::writeln()
has parameter $messages with no value type specified in iterable type
iterable.
681 Method
Symfony\Component\Console\Output\OutputInterface::setVerbosity() has
no return type specified.
699 Method
Symfony\Component\Console\Output\OutputInterface::setDecorated() has
no return type specified.
705 Method
Symfony\Component\Console\Output\OutputInterface::setFormatter() has
no return type specified.
705 Parameter $formatter of method
Symfony\Component\Console\Output\OutputInterface::setFormatter() has
invalid type
Symfony\Component\Console\Formatter\OutputFormatterInterface.
708 Method
Symfony\Component\Console\Output\OutputInterface::getFormatter() has
invalid return type
Symfony\Component\Console\Formatter\OutputFormatterInterface.
714 Class Symfony\Component\Console\Style\SymfonyStyle extends unknown
class Symfony\Component\Console\Style\OutputStyle.
719 Property
Symfony\Component\Console\Style\SymfonyStyle::$questionHelper has
unknown class Symfony\Component\Console\Helper\SymfonyQuestionHelper
as its type.
720 Property Symfony\Component\Console\Style\SymfonyStyle::$progressBar
has unknown class Symfony\Component\Console\Helper\ProgressBar as its
type.
722 Property
Symfony\Component\Console\Style\SymfonyStyle::$bufferedOutput has
unknown class Symfony\Component\Console\Output\TrimmedBufferOutput as
its type.
726 Method Symfony\Component\Console\Style\SymfonyStyle::block() has no
return type specified.
726 Method Symfony\Component\Console\Style\SymfonyStyle::block() has
parameter $messages with no value type specified in iterable type
array.
729 Method Symfony\Component\Console\Style\SymfonyStyle::title() has no
return type specified.
732 Method Symfony\Component\Console\Style\SymfonyStyle::section() has no
return type specified.
735 Method Symfony\Component\Console\Style\SymfonyStyle::listing() has no
return type specified.
735 Method Symfony\Component\Console\Style\SymfonyStyle::listing() has
parameter $elements with no value type specified in iterable type
array.
738 Method Symfony\Component\Console\Style\SymfonyStyle::text() has no
return type specified.
738 Method Symfony\Component\Console\Style\SymfonyStyle::text() has
parameter $message with no value type specified in iterable type
array.
741 Method Symfony\Component\Console\Style\SymfonyStyle::comment() has no
return type specified.
741 Method Symfony\Component\Console\Style\SymfonyStyle::comment() has
parameter $message with no value type specified in iterable type
array.
744 Method Symfony\Component\Console\Style\SymfonyStyle::success() has no
return type specified.
744 Method Symfony\Component\Console\Style\SymfonyStyle::success() has
parameter $message with no value type specified in iterable type
array.
747 Method Symfony\Component\Console\Style\SymfonyStyle::error() has no
return type specified.
747 Method Symfony\Component\Console\Style\SymfonyStyle::error() has
parameter $message with no value type specified in iterable type
array.
750 Method Symfony\Component\Console\Style\SymfonyStyle::warning() has no
return type specified.
750 Method Symfony\Component\Console\Style\SymfonyStyle::warning() has
parameter $message with no value type specified in iterable type
array.
753 Method Symfony\Component\Console\Style\SymfonyStyle::note() has no
return type specified.
753 Method Symfony\Component\Console\Style\SymfonyStyle::note() has
parameter $message with no value type specified in iterable type
array.
756 Method Symfony\Component\Console\Style\SymfonyStyle::info() has no
return type specified.
756 Method Symfony\Component\Console\Style\SymfonyStyle::info() has
parameter $message with no value type specified in iterable type
array.
759 Method Symfony\Component\Console\Style\SymfonyStyle::caution() has no
return type specified.
759 Method Symfony\Component\Console\Style\SymfonyStyle::caution() has
parameter $message with no value type specified in iterable type
array.
762 Method Symfony\Component\Console\Style\SymfonyStyle::table() has no
return type specified.
762 Method Symfony\Component\Console\Style\SymfonyStyle::table() has
parameter $headers with no value type specified in iterable type
array.
762 Method Symfony\Component\Console\Style\SymfonyStyle::table() has
parameter $rows with no value type specified in iterable type array.
765 Method
Symfony\Component\Console\Style\SymfonyStyle::horizontalTable() has
no return type specified.
765 Method
Symfony\Component\Console\Style\SymfonyStyle::horizontalTable() has
parameter $headers with no value type specified in iterable type
array.
765 Method
Symfony\Component\Console\Style\SymfonyStyle::horizontalTable() has
parameter $rows with no value type specified in iterable type array.
768 Method Symfony\Component\Console\Style\SymfonyStyle::definitionList()
has no return type specified.
768 Method Symfony\Component\Console\Style\SymfonyStyle::definitionList()
has parameter $list with no value type specified in iterable type
array.
768 Parameter $list of method
Symfony\Component\Console\Style\SymfonyStyle::definitionList() has
invalid type Symfony\Component\Console\Helper\TableSeparator.
780 Method Symfony\Component\Console\Style\SymfonyStyle::choice() has
parameter $choices with no value type specified in iterable type
array.
783 Method Symfony\Component\Console\Style\SymfonyStyle::progressStart()
has no return type specified.
786 Method
Symfony\Component\Console\Style\SymfonyStyle::progressAdvance() has
no return type specified.
789 Method Symfony\Component\Console\Style\SymfonyStyle::progressFinish()
has no return type specified.
792 Method
Symfony\Component\Console\Style\SymfonyStyle::createProgressBar() has
invalid return type Symfony\Component\Console\Helper\ProgressBar.
795 Method
Symfony\Component\Console\Style\SymfonyStyle::progressIterate() has
parameter $iterable with no value type specified in iterable type
iterable.
795 Method
Symfony\Component\Console\Style\SymfonyStyle::progressIterate()
return type has no value type specified in iterable type iterable.
798 Parameter $question of method
Symfony\Component\Console\Style\SymfonyStyle::askQuestion() has
invalid type Symfony\Component\Console\Question\Question.
801 Method Symfony\Component\Console\Style\SymfonyStyle::writeln() has no
return type specified.
801 Method Symfony\Component\Console\Style\SymfonyStyle::writeln() has
parameter $messages with no value type specified in iterable type
iterable.
804 Method Symfony\Component\Console\Style\SymfonyStyle::write() has no
return type specified.
804 Method Symfony\Component\Console\Style\SymfonyStyle::write() has
parameter $messages with no value type specified in iterable type
iterable.
807 Method Symfony\Component\Console\Style\SymfonyStyle::newLine() has no
return type specified.
813 Method Symfony\Component\Console\Style\SymfonyStyle::createTable()
has invalid return type Symfony\Component\Console\Helper\Table.
816 Method Symfony\Component\Console\Style\SymfonyStyle::getProgressBar()
has invalid return type Symfony\Component\Console\Helper\ProgressBar.
828 Method Symfony\Component\Console\Style\SymfonyStyle::createBlock()
has parameter $messages with no value type specified in iterable type
iterable.
828 Method Symfony\Component\Console\Style\SymfonyStyle::createBlock()
return type has no value type specified in iterable type array.
836 Property Symfony\Component\Filesystem\Filesystem::$lastError has no
type specified.
837 Method Symfony\Component\Filesystem\Filesystem::copy() has no return
type specified.
840 Method Symfony\Component\Filesystem\Filesystem::mkdir() has no return
type specified.
840 Method Symfony\Component\Filesystem\Filesystem::mkdir() has parameter
$dirs with no value type specified in iterable type iterable.
843 Method Symfony\Component\Filesystem\Filesystem::exists() has
parameter $files with no value type specified in iterable type
iterable.
846 Method Symfony\Component\Filesystem\Filesystem::touch() has no return
type specified.
846 Method Symfony\Component\Filesystem\Filesystem::touch() has parameter
$files with no value type specified in iterable type iterable.
849 Method Symfony\Component\Filesystem\Filesystem::remove() has no
return type specified.
849 Method Symfony\Component\Filesystem\Filesystem::remove() has
parameter $files with no value type specified in iterable type
iterable.
852 Method Symfony\Component\Filesystem\Filesystem::doRemove() has
parameter $files with no value type specified in iterable type array.
855 Method Symfony\Component\Filesystem\Filesystem::chmod() has no return
type specified.
855 Method Symfony\Component\Filesystem\Filesystem::chmod() has parameter
$files with no value type specified in iterable type iterable.
858 Method Symfony\Component\Filesystem\Filesystem::chown() has no return
type specified.
858 Method Symfony\Component\Filesystem\Filesystem::chown() has parameter
$files with no value type specified in iterable type iterable.
861 Method Symfony\Component\Filesystem\Filesystem::chgrp() has no return
type specified.
861 Method Symfony\Component\Filesystem\Filesystem::chgrp() has parameter
$files with no value type specified in iterable type iterable.
864 Method Symfony\Component\Filesystem\Filesystem::rename() has no
return type specified.
870 Method Symfony\Component\Filesystem\Filesystem::symlink() has no
return type specified.
873 Method Symfony\Component\Filesystem\Filesystem::hardlink() has no
return type specified.
873 Method Symfony\Component\Filesystem\Filesystem::hardlink() has
parameter $targetFiles with no value type specified in iterable type
iterable.
885 Method Symfony\Component\Filesystem\Filesystem::mirror() has no
return type specified.
885 Method Symfony\Component\Filesystem\Filesystem::mirror() has
parameter $iterator with no value type specified in iterable type
Traversable.
885 Method Symfony\Component\Filesystem\Filesystem::mirror() has
parameter $options with no value type specified in iterable type
array.
894 Method Symfony\Component\Filesystem\Filesystem::dumpFile() has no
return type specified.
894 Method Symfony\Component\Filesystem\Filesystem::dumpFile() has
parameter $content with no type specified.
897 Method Symfony\Component\Filesystem\Filesystem::appendToFile() has no
return type specified.
897 Method Symfony\Component\Filesystem\Filesystem::appendToFile() has
parameter $content with no type specified.
900 Method Symfony\Component\Filesystem\Filesystem::toIterable() has
parameter $files with no value type specified in iterable type
iterable.
900 Method Symfony\Component\Filesystem\Filesystem::toIterable() return
type has no value type specified in iterable type iterable.
903 Method
Symfony\Component\Filesystem\Filesystem::getSchemeAndHierarchy()
return type has no value type specified in iterable type array.
922 Property Symfony\Component\Filesystem\Path::$buffer has no type
specified.
923 Property Symfony\Component\Filesystem\Path::$bufferSize has no type
specified.
945 Method Symfony\Component\Filesystem\Path::hasExtension() has
parameter $extensions with no type specified.
975 Method Symfony\Component\Filesystem\Path::findCanonicalParts() return
type has no value type specified in iterable type array.
978 Method Symfony\Component\Filesystem\Path::split() return type has no
value type specified in iterable type array.
993 Class Symfony\Component\Finder\Finder implements generic interface
IteratorAggregate but does not specify its types: TKey, TValue
993 PHPDoc tag @implements has invalid value (): Unexpected token "\n",
expected type at offset 15
999 Property Symfony\Component\Finder\Finder::$names type has no value
type specified in iterable type array.
1000 Property Symfony\Component\Finder\Finder::$notNames type has no value
type specified in iterable type array.
1001 Property Symfony\Component\Finder\Finder::$exclude type has no value
type specified in iterable type array.
1002 Property Symfony\Component\Finder\Finder::$filters type has no value
type specified in iterable type array.
1003 Property Symfony\Component\Finder\Finder::$depths type has no value
type specified in iterable type array.
1004 Property Symfony\Component\Finder\Finder::$sizes type has no value
type specified in iterable type array.
1009 Property Symfony\Component\Finder\Finder::$dirs type has no value
type specified in iterable type array.
1010 Property Symfony\Component\Finder\Finder::$dates type has no value
type specified in iterable type array.
1011 Property Symfony\Component\Finder\Finder::$iterators type has no
value type specified in iterable type array.
1012 Property Symfony\Component\Finder\Finder::$contains type has no value
type specified in iterable type array.
1013 Property Symfony\Component\Finder\Finder::$notContains type has no
value type specified in iterable type array.
1014 Property Symfony\Component\Finder\Finder::$paths type has no value
type specified in iterable type array.
1015 Property Symfony\Component\Finder\Finder::$notPaths type has no value
type specified in iterable type array.
1017 Property Symfony\Component\Finder\Finder::$vcsPatterns type has no
value type specified in iterable type array.
1030 Method Symfony\Component\Finder\Finder::depth() has parameter $levels
with no value type specified in iterable type array.
1033 Method Symfony\Component\Finder\Finder::date() has parameter $dates
with no value type specified in iterable type array.
1036 Method Symfony\Component\Finder\Finder::name() has parameter
$patterns with no value type specified in iterable type array.
1039 Method Symfony\Component\Finder\Finder::notName() has parameter
$patterns with no value type specified in iterable type array.
1042 Method Symfony\Component\Finder\Finder::contains() has parameter
$patterns with no value type specified in iterable type array.
1045 Method Symfony\Component\Finder\Finder::notContains() has parameter
$patterns with no value type specified in iterable type array.
1048 Method Symfony\Component\Finder\Finder::path() has parameter
$patterns with no value type specified in iterable type array.
1051 Method Symfony\Component\Finder\Finder::notPath() has parameter
$patterns with no value type specified in iterable type array.
1054 Method Symfony\Component\Finder\Finder::size() has parameter $sizes
with no value type specified in iterable type array.
1057 Method Symfony\Component\Finder\Finder::exclude() has parameter $dirs
with no value type specified in iterable type array.
1069 Method Symfony\Component\Finder\Finder::addVCSPattern() has no return
type specified.
1069 Method Symfony\Component\Finder\Finder::addVCSPattern() has parameter
$pattern with no value type specified in iterable type array.
1111 Method Symfony\Component\Finder\Finder::in() has parameter $dirs with
no value type specified in iterable type array.
1117 Method Symfony\Component\Finder\Finder::append() has parameter
$iterator with no value type specified in iterable type iterable.
1138 Class Symfony\Component\Process\Process implements generic interface
IteratorAggregate but does not specify its types: TKey, TValue
1138 PHPDoc tag @implements has invalid value (): Unexpected token "\n",
expected type at offset 15
1153 Property Symfony\Component\Process\Process::$callback has no type
specified.
1154 Property Symfony\Component\Process\Process::$hasCallback has no type
specified.
1155 Property Symfony\Component\Process\Process::$commandline has no type
specified.
1156 Property Symfony\Component\Process\Process::$cwd has no type
specified.
1157 Property Symfony\Component\Process\Process::$env has no type
specified.
1158 Property Symfony\Component\Process\Process::$input has no type
specified.
1159 Property Symfony\Component\Process\Process::$starttime has no type
specified.
1160 Property Symfony\Component\Process\Process::$lastOutputTime has no
type specified.
1161 Property Symfony\Component\Process\Process::$timeout has no type
specified.
1162 Property Symfony\Component\Process\Process::$idleTimeout has no type
specified.
1163 Property Symfony\Component\Process\Process::$exitcode has no type
specified.
1164 Property Symfony\Component\Process\Process::$fallbackStatus has no
type specified.
1165 Property Symfony\Component\Process\Process::$processInformation has
no type specified.
1166 Property Symfony\Component\Process\Process::$outputDisabled has no
type specified.
1167 Property Symfony\Component\Process\Process::$stdout has no type
specified.
1168 Property Symfony\Component\Process\Process::$stderr has no type
specified.
1169 Property Symfony\Component\Process\Process::$process has no type
specified.
1170 Property Symfony\Component\Process\Process::$status has no type
specified.
1171 Property Symfony\Component\Process\Process::$incrementalOutputOffset
has no type specified.
1172 Property
Symfony\Component\Process\Process::$incrementalErrorOutputOffset has
no type specified.
1173 Property Symfony\Component\Process\Process::$tty has no type
specified.
1174 Property Symfony\Component\Process\Process::$pty has no type
specified.
1175 Property Symfony\Component\Process\Process::$options has no type
specified.
1176 Property Symfony\Component\Process\Process::$useFileHandles has no
type specified.
1177 Property Symfony\Component\Process\Process::$processPipes has no type
specified.
1178 Property Symfony\Component\Process\Process::$latestSignal has no type
specified.
1179 Property Symfony\Component\Process\Process::$sigchild has no type
specified.
1180 Property Symfony\Component\Process\Process::$exitCodes has no type
specified.
1181 Method Symfony\Component\Process\Process::__construct() has parameter
$command with no value type specified in iterable type array.
1181 Method Symfony\Component\Process\Process::__construct() has parameter
$env with no value type specified in iterable type array.
1184 Method Symfony\Component\Process\Process::fromShellCommandline() has
parameter $env with no value type specified in iterable type array.
1199 Method Symfony\Component\Process\Process::run() has parameter $env
with no value type specified in iterable type array.
1202 Method Symfony\Component\Process\Process::mustRun() has parameter
$env with no value type specified in iterable type array.
1205 Method Symfony\Component\Process\Process::start() has no return type
specified.
1205 Method Symfony\Component\Process\Process::start() has parameter $env
with no value type specified in iterable type array.
1208 Method Symfony\Component\Process\Process::restart() has parameter
$env with no value type specified in iterable type array.
1331 Method Symfony\Component\Process\Process::getEnv() return type has no
value type specified in iterable type array.
1334 Method Symfony\Component\Process\Process::setEnv() has parameter $env
with no value type specified in iterable type array.
1337 Method Symfony\Component\Process\Process::getInput() has no return
type specified.
1343 Method Symfony\Component\Process\Process::checkTimeout() has no
return type specified.
1349 Method Symfony\Component\Process\Process::setOptions() has no return
type specified.
1349 Method Symfony\Component\Process\Process::setOptions() has parameter
$options with no value type specified in iterable type array.
1358 Method Symfony\Component\Process\Process::getDescriptors() return
type has no value type specified in iterable type array.
1364 Method Symfony\Component\Process\Process::updateStatus() has no
return type specified.
1388 Method Symfony\Component\Process\Process::prepareWindowsCommandLine()
has parameter $env with no value type specified in iterable type
array.
1400 Method Symfony\Component\Process\Process::replacePlaceholders() has
parameter $env with no value type specified in iterable type array.
1403 Method Symfony\Component\Process\Process::getDefaultEnv() return type
has no value type specified in iterable type array.
------ -----------------------------------------------------------------------
------ ---------------------------------------------------------------------
Line castor.php
------ ---------------------------------------------------------------------
9 Used function Castor\run not found.
π‘ Learn more at https://phpstan.org/user-guide/discovering-symbols
21 Attribute class Castor\Attribute\AsTask does not exist.
In #183, you mention a SymfonyCommandTask attribute, and wanted to ask about that.
Many of my admin script start out as console commands, I would love to simply tag the command and have it available in castor. In particular, I don't want to have to re-define the arguments and options, so instead of bin/console app:validate (or symfony console app:validate), I could run castor app:validate [with options, args], without having to explicitly re-define that command.
Hi there!
I never noticed the cache validity period, why was it set to a value of 60 days?
Wouldn't a value of 12/24 h be sufficient? Is there a restriction that doesn't allow this?
$item->expiresAfter(3600 * 60 * 24);
Defined here
Can we introduce a default task like check-update
?
For example, currently, if I update castor to the latest version on my workstation and send it to PR, my colleagues will encounter compatibility problems. And I'd need to notify everyone that something needed to be updated manually via message or meeting.
To solve this problem, I thought of introducing a function like min_version_check('0.10.0');
which, even before running a command, checks whether the minimum version required is installed on the workstation. And if it doesn't, we could run the check-update command
What do you think of this?
Hello, it would be nice if castor could be installed like the Symfony CLI with Homebrew.
https://github.com/symfony-cli/homebrew-tap
brew upgrade symfony-cli
Running `brew update --auto-update`...
==> Auto-updated Homebrew!
==> Updated Homebrew from 4.0.19 (33ab8e755) to 4.0.21 (83db7039e).
Updated 3 taps (homebrew/cask-fonts, homebrew/core and homebrew/cask).
==> New Formulae
ansible@7 aws-amplify fastgron joshuto libint melange procps@3 spotify_player tern xbyak
apko bashate git-credential-oauth libecpint libomemo-c nexttrace protobuf@21 swift-outdated votca
argparse ddns-go [email protected] libfastjson libpaho-mqtt openfga shodan tailwindcss-language-server wzprof
==> New Casks
chatbox craft engine-dj eusamanager firefly-shimmer font-diphylleia font-grandiflora-one font-moirai-one font-rethink-sans loupedeck processmonitor tea
copilot dintch eu filemonitor font-bagel-fat-one font-gasoek-one font-intel-one-mono font-orbit lasso motu-m-series skiff yealink-meeting
You have 29 outdated formulae and 1 outdated cask installed.
The 4.0.21 changelog can be found at:
https://github.com/Homebrew/brew/releases/tag/4.0.21
Warning: symfony-cli/tap/symfony-cli 5.5.6 already installed
Hello everyone,
For a project, I need to use common functions, but which are launched in different contexts.
This is already possible via --context=name
, but I find that it can get a bit annoying over time.
I've made a POC that lets you import one or more castor files with a custom namespace, with the option of adding a default namespace.
For example, here are the imports:
import(__DIR__ . /castor/symfony', namespacePrefix: 'app', defaultContext: \contexts\app());
import(__DIR__ . '/castor/symfony', namespacePrefix: 'domains', defaultContext: \contexts\domains());
import(__DIR__ . '/castor/composer.php', namespacePrefix: 'app', defaultContext: \contexts\app());
import(__DIR__ . '/castor/composer.php', namespacePrefix: 'domains', defaultContext: \contexts\domains());
import(__DIR__ . '/castor/pnpm.php', namespacePrefix: 'app', defaultContext: \contexts\app());
import(__DIR__ . '/castor/pnpm.php', namespacePrefix: 'domains:ui', defaultContext: \contexts\domains_ui());
This will create the task list as below, and if I run a app:sf:cache-clear
task, it will automatically be set to work with the app
context.
I have a working POC for now, but I'm not entirely happy with the implementation. I'm opening the topic to get your feedback on this one π
Here is the link to the POC : TheoD02@de0c299
Keeps the project root clean.
Castor 0.14.0 (Phar)
PHP 8.3.4
PowerShell 7.4.1 on Windows 11
Everytime I try to run a task that includes a call to run()
or exit_code()
, the task does not complete. I have to either Ctrl+C
or press Enter
to exit the task, and then an error is displayed:
In AbstractPipes.php line 139:
Notice: fwrite(): Write of 2 bytes failed with errno=22 Invalid argument
The command is OK, because I can see its output right after this error message.
A sample task triggering this error:
#[AsTask]
function phpVersion(): void {
run("php --version"); // Using a string or an array as argument does not change anything.
}
This error does not occur if I use Symfony Process directly (i.e. (new Process(["php", "--version"]))->run()
).
function(SymfonyStyle $io)
{
$io->ask();
fs()->mkdir();
}
It's not consistent:
For the record, here is list of param supported via the DI
function(SymfonyStyle $io, Filesystem $fs)
{
$io->ask();
$fs->mkdir();
}
function()
{
io()->ask();
fs()->mkdir();
}
Pros & cons are the opposite of "Everything via DI"
I would vote for function, but I'm not 100% sure!
Great you created this, \me and i guess quite some others suffer from similar pain.
There are two blockers for me though:
--dry-run
optionI'm putting these into one issue becuse these are quite related:
Is this missing or did i miss something?
While going through the Castor documentation, I encountered some confusion regarding the terms 'task' and 'command'. The introduction section refers to Castor as a "task runner and command launcher," but as I delved deeper, the distinction between these two terms became unclear.
For example, to create and run a command, the documentation instructs to use the #[AsTask]
attribute.
This usage suggests that a Command is equivalent to a Task. However, if that's the case, why are two different terms used? This is particularly perplexing.
To provide some context, I'm familiar with Taskfile, a popular Makefile alternative, which Castor lists as a comparable tool. In Taskfile, tasks are defined as a set of commands. You execute a task, which in turn runs multiple commands.
Drawing from this, running task prod-to-local
in Taskfile is executing a task, whereas castor prod-to-local
in Castor is described as executing a command. So, what exactly constitutes a task in Castor? It's supposed to be a task runner too right ?
This terminology ambiguity seems to extend from the code to the documentation, and I believe Castor could greatly benefit from more precise and consistent language. This was notably pointed out in a recent review suggestion: #218 (comment).
While reviewing the introduction of the EventListener feature, I realized it's yet another Symfony package integrated into Castor, along with HttpClient, Cache, Console, and the Monolog bridge.
This made me think about leveraging the recently added Command Profiler for built-in profiling tools. These could provide valuable traces, logs, and performance tracking out-of-the-box for what happens inside our Castor apps.
For example I suggested to add debug logs while dispatching / listening, something that usually comes for free in Symfony apps.
Castor might even implement its own DataCollector to profile its engine.
I'm uncertain about the potential impact on the codebase (I guess the GlobalHelper would have to be refactored to a Symfony Container ?), so I view this issue more as an idea for discussion.
Hi there,
When I'm working with docker container for example, I often need to wait that a container is ready (healthy) before processing any other action.
We can think of a helper like this :
/**
* @param callable(): bool $callback
* @param int $timeout Maximum number of seconds to wait before throwing a TimeoutException
* @param int $interval Interval in second between calls to the $callback function
* @throw TimeoutException
*/
function wait_for(callable $callback, int $timeout = 10, int $interval = 1): void;
If you think it's a good feature, I can try a PR
Hello all !
I would like to know if it is possible to add an option to import for indicating this import to keep the directory where is located imported castor.php as currentDirectory.
Example
I have a project structure that have :
webdev/
ββ projects/
β ββ A/
β β ββ docker-compose.yml
β β ββ castor.php
β ββ B/
β β ββ docker-compose.yml
β β ββ castor.php
ββ docker-compose.yml
ββ castor.php
castor.php at ~/webdev/castor.php
as a PWD of ~/webdev
and all import too
I'm in ~/webdev
folder, I call the castor start
for starting docker-compose.yml at ~/webdev/docker-compose.yml
that OK, but in this same start, I want to question user if I want to start the project A located in ~/webdev/projects/A
if user confirm, I call the start task from the castor file located in ~/webdev/projects/A
, but this one as PWD of ~/webdev
A suggest would be to keep the PWD of imported like that if possible
import(__DIR__ . '/projects/A/castor.php', keepOriginalDirectory: true);
With that all functions importe from ~/webdev/projects/A/castor.php
will have ~/webdev/projects/A
as currentDirectory
As of today for make this possible, i make a "default context" that have currentDirectory to __DIR__
, that is the right way ?
Hey π
Today we can't conditionally use import
method because the context isn't loaded on runtime.
For example:
if (variable('VARNISH_URL')) {
import(__DIR__ . '/scripts/varnish.php');
}
Won't work because we have a default empty Context on runtime and the real context is only loaded later on.
I would like to do something like that:
import(__DIR__ . '/scripts/varnish.php', fn(Context $c) => $c->offsetExists('VARNISH_URL'));
So Castor import that file (or directory) only if the given callback returns true
(callback should be optional and if none provided it will always import the file/directory).
For some reasons, we need to perform health checks on our apps after being started in Docker via castor. We would like to have something like http()
to be able to perform HTTP requests and check the status code and/or the response content (why not headers too).
Hello,
There's an issue with the composer.lock
file at the moment in the repository.
I spotted that issue while trying to propose the update of Castor to version 0.14.0 to the Nix ecosystem.
To reproduce the issue:
git clone https://github.com/jolicode/castor/
cd castor
composer validate
A PR fixing the issue will follow in a few minutes.
Hello,
When I'm trying to run the bin/castor -vvv watch:fs-change
, I have the following issue :
13:43:27 DEBUG [castor] Running command: "'/Users/me/Projects/castor/src/../watcher/bin/watcher' '/Users/me/Projects/castor/...'".
ERROR: err : sh: /Users/me/Projects/castor/src/../watcher/bin/watcher: cannot execute binary file
sh: /Users/me/Projects/castor/src/../watcher/bin/watcher: Undefined error: 0
13:43:27 NOTICE [castor] Command finished with and error (exit code=1).
In functions.php line 148:
[Symfony\Component\Process\Exception\ProcessFailedException]
The command "'/Users/me/Projects/castor/src/../watcher/bin/watcher' '/Users/me/Projects/castor/...'" failed.
Exit Code: 1(General error)
Working directory: /Users/me/Projects/castor
Output:
================
Error Output:
================
sh: /Users/me/Projects/castor/src/../watcher/bin/watcher: cannot execute binary file
sh: /Users/me/Projects/castor/src/../watcher/bin/watcher: Undefined error: 0
Exception trace:
at /Users/me/Projects/castor/src/functions.php:148
Castor\exec() at /Users/me/Projects/castor/src/functions.php:206
Castor\watch() at /Users/me/Projects/castor/examples/watch.php:13
watch\fs_change() at n/a:n/a
ReflectionFunction->invoke() at /Users/me/Projects/castor/src/Console/Command/TaskCommand.php:132
Castor\Console\Command\TaskCommand->execute() at /Users/me/Projects/castor/vendor/symfony/console/Command/Command.php:312
Symfony\Component\Console\Command\Command->run() at /Users/me/Projects/castor/vendor/symfony/console/Application.php:1022
Symfony\Component\Console\Application->doRunCommand() at /Users/me/Projects/castor/src/Console/Application.php:57
Castor\Console\Application->doRunCommand() at /Users/me/Projects/castor/vendor/symfony/console/Application.php:314
Symfony\Component\Console\Application->doRun() at /Users/me/Projects/castor/src/Console/Application.php:45
Castor\Console\Application->doRun() at /Users/me/Projects/castor/vendor/symfony/console/Application.php:168
Symfony\Component\Console\Application->run() at /Users/me/Projects/castor/src/Console/ApplicationFactory.php:28
Castor\Console\ApplicationFactory::run() at /Users/me/Projects/castor/bin/castor:14
watch:fs-change
Permissions o watcher/bin/watcher
binary looks right, but I have an error when running it :
exec format error: ./watcher
It looks like a compilation platform issue.
Happy to help if needed β€οΈ .
Hello!
I encounter a problem with the repack
command.
I use Twig
to render complex config files.
Twig
has a \Twig\TwigTest
class to implement the test operator.
With the current box
configuration, the Test
files are blacklisted
https://github.com/jolicode/castor/blob/main/tools/phar/box.linux-amd64.json#L9
When i repack my app, i have an error Class "Twig\TwigTest" not found
I can go around this problem adding this configuration in the Castor box config file:
"files": [
"../../../vendor/twig/twig/src/TwigTest.php"
],
Did you think it could be a feature to allow merging a local box config file?
Thanks!
Hey Jolicode!
Just testing Castor. Here is a small feedback.
The documentation states you can install autocompletion by running:
castor completion | sudo tee /etc/bash_completion.d/castor
(here: https://github.com/jolicode/castor/blob/main/doc/01-installation.md#autocomplete)
The problem is that unless you have a castor.php
file in the current directory, castor completion
will fail.
And since you run this command just after installing Castor, it is unlikely that there is a castor.php
file in the directory where you are running
castor completion | sudo tee /etc/bash_completion.d/castor
See ya!
I tried to install Castor with the one liner in the documentation (also I think it could before the "Usage" section) and it failed without errors:
>curl "https://github.com/jolicode/castor/releases/latest/download/castor.linux-amd64.phar" -Lso $HOME/.local/bin/castor && chmod u+x $HOME/.local/bin/castor
>castor
Command 'castor' not found, did you mean:
command 'cantor' from snap cantor (23.08.3)
command 'cantor' from deb cantor (4:21.12.3-0ubuntu1)
See 'snap info <snapname>' for additional versions.
I got a classic Ubuntu 22 installation. Should I be using the $HOME/.local/bin
as it doesn't exist ?
I see that Robo is using this one liner that worked with the /usr/bin
directory:
wget https://robo.li/robo.phar && chmod +x robo.phar && sudo mv robo.phar /usr/bin/robo
Hi,
I have properly read the "Get started" part in your documentation, and there is no mention on how to install it locally with composer. What I mean by locally is "per project", by adding jolicode/castor in the require part of a self made composer package which will contain the necessary custom commands for a project.
I expected to create such a package in order to easily add it to the composer.json of several website projects. But because this custom package will be installed in the vendor folder, even if I create a symlink from the bin to the project root, the file castor.php will not exist from the root and will not be able to find my commands definitions.
Am I doing something wrong ? I'm thinking about a way to add a castor.php file at the root of the project, and then import() the castor.php file of my custom Composer package (which has import() lines to in it).
Is this viable ? Do you have another solution maybe ?
Regards
It appears that castor is locked to Symfony 6.4.
Z:\>php bin/castor -v
In castor.php line 8:
[InvalidArgumentException]
Could not import "examples" in "Z:\castor.php" on line 8. Reason: The import path must be formatted like this: "Z://<organization>/<repository>".
Exception trace:
at Z:\castor.php:8
Castor\Import\Importer->createImportException() at Z:\src\Import\Importer.php:43
Castor\Import\Importer->import() at Z:\src\functions.php:643
Castor\import() at Z:\castor.php:8
require_once() at Z:\src\functions-internal.php:18
Castor\castor_require() at Z:\src\FunctionFinder.php:91
Castor\FunctionFinder->doFindFunctions() at Z:\src\FunctionFinder.php:42
Castor\FunctionFinder->findFunctions() at Z:\src\Console\Application.php:183
Castor\Console\Application->initializeApplication() at Z:\src\Console\Application.php:136
Castor\Console\Application->doRun() at Z:\vendor\symfony\console\Application.php:175
Symfony\Component\Console\Application->run() at Z:\bin\castor:14
In PackageImporter.php line 43:
[Castor\Import\Exception\InvalidImportFormat]
The import path must be formatted like this: "Z://<organization>/<repository>".
Exception trace:
at Z:\src\Import\Remote\PackageImporter.php:43
Castor\Import\Remote\PackageImporter->importPackage() at Z:\src\Import\Importer.php:32
Castor\Import\Importer->import() at Z:\src\functions.php:643
Castor\import() at Z:\castor.php:8
require_once() at Z:\src\functions-internal.php:18
Castor\castor_require() at Z:\src\FunctionFinder.php:91
Castor\FunctionFinder->doFindFunctions() at Z:\src\FunctionFinder.php:42
Castor\FunctionFinder->findFunctions() at Z:\src\Console\Application.php:183
Castor\Console\Application->initializeApplication() at Z:\src\Console\Application.php:136
Castor\Console\Application->doRun() at Z:\vendor\symfony\console\Application.php:175
Symfony\Component\Console\Application->run() at Z:\bin\castor:14
When i am pasting the following command :
curl "https://github.com/jolicode/castor/releases/latest/download/castor.darwin-amd64.phar" -Lfso /usr/local/bin/castor &&
chmod u+x /usr/local/bin/castor &&
castor --version ||
(echo "Could not install castor. Is the target directory writeable?" && (exit 1))
it echo the error message "Could not install castor. Is the target directory writeable?", even when i use sudo mode.
I enjoy the simplicity of Castor for scripting and automation, yet I'd prefer to avoid the need to install PHP everywhere. I'm curious about the possibility of making my custom Castor apps more portable by turning them into a single binary file. That would be awesome.
There's been some recent advancement in PHP that supports this idea, especially seen in https://github.com/crazywhalecc/static-php-cli. This method is already effective in several projects:
Considering this, I'm thinking of developing a native Castor feature to combine Castor, PHP, and user-defined tasks into one binary.
I'm planning to tackle this project myself, but I wanted to share the concept here for any feedback or if anyone find the idea interesting enough to collaborate on this.
How would I write something like this with Castor?
$ bin/console some:command | jq '.some_key'
Should it be like this:
run(['bin/console', 'some:command', '|', 'jq', '.some_key']]
Or is there a nicer API for this?
Hi!
If I perform a simple repack:
composer require jolicode/castor
vendor/castor repack --app-name sylius
It works well!
But if I want it to be quiet, it doesn't.
In verbose (-vvv
) I got this (nothing moreβ¦):
In ComposerOrchestrator.php line 52:
Could not determine the Composer version.
compile [--debug] [--no-parallel] [--no-restart] [--dev] [--no-config] [--with-docker] [--composer-bin COMPOSER-BIN] [--allow-composer-check-failure] [-c|--config CONFIG] [-d|--working-dir WORKING-DIR]
In Process.php line 267:
The command "'/usr/local/bin/box' 'compile' '--config=.box.json'" failed.
Exit Code: 1(General error)
Working directory: /private/tmp/castor
Output:
================
compile [--debug] [--no-parallel] [--no-restart] [--dev] [--no-config] [--with-docker] [--composer-bin COMPOSER-BIN] [--allow-composer-check-failure] [-c|--config CON
FIG] [-d|--working-dir WORKING-DIR]
repack [--app-name APP-NAME] [--app-version APP-VERSION] [--os OS]
Sometimes I want to watch multiple folders at once.
Here is the prototype I have in my mind:
use Castor\Attribute\AsTask;
use function Castor\watch;
#[AsTask]
function watch(): void
{
watch(['src/', 'tests/'], function (string $file, string $action) {
echo "File {$file} has been {$action}\n";
});
}
In some project with docker, I have this recipes in my Makefile
:
# Rebuild docker images if changes detected
var/.docker-build: docker-compose.yml .env $(shell find .docker -type f)
@docker-compose build
@mkdir -p var
@touch var/.docker-build
up: var/.docker-build
@docker-compose up
Each time I launch make up
it checks if the file var/.docker-build
is more recent that any files required to build my docker images (docker-compose.yml
, .env
, any files in .docker
directory). If not, then images are rebuilt and time of var/.docker-build
file is updated.
This is the only recipe in my Makefile
I can't replace with castor
for now.
We can maybe think of some helper like this:
use function Castor\is_updated;
use function Castor\run;
if (is_updated(['docker-compose.yml', '.env', '.docker/*']) {
run("docker-compose build");
}
Bonus: this will be more readable than the Makefile
version.
This looks great, thanks for releasing it! It appears to be able to solve a problem I've been wresting with, and I was hoping you could provide a "best practices" example.
I use docker when developing locally, so my commands are run with the 'symfony' prefix, which I sometimes put into a bash file.
# bin/load-projects.sh
symfony console d:m:m -n
symfony console app:load-project1
symfony console app:load-project2
When I go to production, however, my bash script no longer works, because it's expecting 'bin/console'
bin/console d:m:m -n
bin/console app:load-project1
bin/console app:load-project2
So I'm thinking of making castor calls instead:
castor d:m:m -n
castor app:load-project1
castor app:load-project2
Somewhere in castor it would need to check if the symfony binary was available, or an environment variable, or something to determine how to call the command.
And of course I'd need to register each symfony command I use with AsTask().
Am I thinking about this correctly? Any suggestions?
For example, GitHub follows this with .github
folder.
Makes it clear it's not related to the project.
Would be great not have to keep this empty file around :)
The spatie/ssh
package provides upload()
and download()
methods for transfer of whole directories (via scp
).
There should be matching functions for Castor to do the same.
Not exactly sure how these should be named however. Simply upload()
and download()
would not be an option since the relation to SSH is not clear (could also be HTTP, see request()
function). A few options:
ssh_upload()
and ssh_download()
ssh_client()
as counterpart to http_client()
which returns an Ssh
instance. Then one could do e.g. ssh_client(host: ..., user: ..., ...)->upload(...)
. (Notice that this would have an unclear semantic wrt the ssh()
function.)Hello
βοΈ completion work with castor
βοΈ completion work with a custom phar
β completion failed with a custom binary
for each case I used the command completion --help
to perform the installation :
./wixi.linux.phar completion bash | sudo tee /etc/bash_completion.d/wixi.linux.phar
/usr/local/bin/wixi completion bash | sudo tee /etc/bash_completion.d/wixi
Using the latest Castor release (0.8.0
at the time of writing) and an older Docker Compose version (2.3.3
), I encountered the following error while running castor start
for the first time :
invalid service "frontend". Must specify either image or build
Which happened when it ran
The command "'docker' 'compose' '-p' 'cettefamille-form' '-f' '/home/hedic/Dev/JoliCode/cettefamille-form/infrastructure/docker/docker-compose.yml' '-f' '/home/hedic/Dev/JoliCode/cettefamille-form/infrastructure/docker/docker-compose.worker.yml' 'up' '--remove-orphans' '--detach' '--no-build'" failed.
I could fix the issue by upgrading Docker Compose to 2.20.3.
It probably would be a good idea to inform users that Castor is incompatible with older versions of Docker Compose ? I don't know up to which version the issue exists, hence I'm not opening a PR to update the readme
I noticed that the Castor binary for macOS is AMD64, but I think that should be ARM64, because Apple moved to Apple Silicon for the whole line up.
The test autogeneration script seems to break the output files, or at least change the output format, is this normal?
The problem is only present after the update to 6.4.*. "update to symfony 6.4.*" commit 0666110
EDIT :
The problem is present here too : https://github.com/jolicode/castor/pull/235/files#diff-fc5f4f1650c6b6065733fe148d65106f2953ba440c80b9cc33c03d7c4038421a
I have identified the package : symfony/console
, version 6.4.1
work fine like before
The problem come from this change symfony/symfony#52940
You can fix this by removing the no-ansi
option in bin/generate-tests.php
but that will add the option to all existing tests so I'll let you decide how you want it to go but that was my investigation if it can helps π
Passing a null value to the $c->withTimeout() no longer works since 41f0756#diff-3cce1ea0450771adbc3cae800dc672c1edde9f76fc377da115e1ca05c8da926cR153
null ?? $defaultValue
will always return the default value, thus it's now impossible to reset the timeout if it has been set before.
For example, this is an issue when using the watch()
function when the default context configures a timeout.
What do you think about using events in castor ?
This could allow flexibility and for example run a specific command, for commands starting with keycloak:
for the example?
This make sure keycloak is started
register_event_listener(
BeforeExecuteTaskEvent::class,
function (BeforeExecuteTaskEvent $event): void {
if (u($event->getCommand()->getName())->startsWith('keycloak:')) {
// Do something before the command is executed
$isKeycloakUp = (bool) (capture("docker ps -a -q -f name=my-keycloak-container", allowFailure: true));
if ($isKeycloakUp === false) {
run('docker compose up -d keycloak', path: 'path/to/keycloak');
}
}
}
);
Hi!
When I use the capture()
function with a command that renders a lot of output (like a big JSON), I realize that the output is cut off at some points.
Example with a simple JSON (understand that a big one is returned by the command):
{
"foo": "Yo",
"bar": "Yoo"
}
I often get something like this:
{
"foo": "Yo",
"bar
"Yoo"
}
Or like this:
{
"foo": "Yo"
"bar": "Yoo"
}
I use the clever create
command to create clever cloud instances with the --format json
to get a full json of the newly created app, this json is quite huge and I get a valid response like one on 30 calls⦠I've tested the response of the binary itself, alone, and I always have a valid JSON.
Thank you!
The installation part of castor is a bit intimidating. The tailwind bundle downloads the file to make it a seamless experience.
https://github.com/SymfonyCasts/tailwind-bundle
I deploy my apps to dokku (a heroku-like server), and often run commands like
dokku run "bin/console app:create-project test"
If I change these to castor, I have to figure out how to install it on the production server, but it if were in a bundle that did the install, perhaps I wouldn't need that step at all.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. πππ
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google β€οΈ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.