Git Product home page Git Product logo

castor's People

Contributors

alexislefebvre avatar arnolem avatar ceciledelmon avatar damienalexandre avatar drupol avatar gromnan avatar jeckel avatar joelwurtz avatar jorickpepin avatar korbeil avatar lyrixx avatar marionleherisson avatar nispeon avatar ptondereau avatar pyrech avatar qboot avatar ruudk avatar seblours avatar tacman avatar ternel avatar thedomeffm avatar theod02 avatar tigitz avatar tucksaun avatar welcomattic avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

castor's Issues

Build castor apps as a single binary

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.

Documentation deployed independently before release

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 ^^

Is it possible to install Castor locally with Composer ?

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

Inconsistent API

ATM, we have:

function(SymfonyStyle $io)
{
    $io->ask();
    fs()->mkdir();
}

It's not consistent:

  • $io is passed via the function argument
  • $fs is got via a function

For the record, here is list of param supported via the DI

  • Context
  • SymfonyStyle
  • Application
  • Command
  • InputInterface
  • OutputInterface

ref

We could have:

Everything via DI

function(SymfonyStyle $io, Filesystem $fs)
{
    $io->ask();
    $fs->mkdir();
}

Cons

  • You have to know each type + import a NS + it's long
  • It'll not work well with the finder: there is a state in it, so you cannot use it twice (or you have to clone it)
  • It does not play well when command chaining

Pros

  • It's cleaner

Everything as a function

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!

Add a spinner

Using parallel() make the output empty until the first task is done. We could provide a spinner to inform user the tasks are running.

Castor completion installation

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!

Errors in the stub file

Hello, I tried to include castor.php in the PHPStan analysis and there are errors because of the .castor.stub.php file.

Capture d’écran 2023-06-08 aΜ€ 17 10 03

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.

Fatal error: Allowed memory size of ... / change memory limit in binary

Hello,

I am using Castor 0.15.0 to make a small test program that imports 2 functions but I have a Memory Limit error on the binary version

vendor/bin/castor repack --app-name=wixi
image

vendor/bin/castor compile wixi.linux.phar
image

How can I modify the embedded PHP configuration to change this limit?

Need for a `wait_for` helper

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

What about using class for declaring some Task ?

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();
}

Proposed Approach

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:

image

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

Why This Approach?

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!

Example of switching between bin/console and symfony console

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?

When `exit_code` or `run` is invoked, the task does not complete (`fwrite()` error)

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()).

Binary installation with Homebrew

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

One liner install doesn't work on Linux

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

Add possibility to keep the directory of imported castor file

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 ?

image

Import with custom namespace and default context

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

image

The test autogeneration script seems to break the output files

The test autogeneration script seems to break the output files, or at least change the output format, is this normal?

image

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 πŸ˜„

Homebrew

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.

install via a bundle, like tailwind

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.

Latest release conflicts with old versions of Docker Compose

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

Testability and Dry-run

Great you created this, \me and i guess quite some others suffer from similar pain.
There are two blockers for me though:

  • a --dry-run option
  • and a way to test my tasks

I'm putting these into one issue becuse these are quite related:

  • For some tasks, i can simply do a dry-run and compare the output
  • For other tasks, i additionally have to mock some sub-tasks (like at least remote calls)

Is this missing or did i miss something?

Repack command: merge local box config?

Hello!

I encounter a problem with the repackcommand.

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!

Watcher issue with mac m1

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 ❀️ .

Depend on the Symfony Command Profiler for an out-of-the-box debugging panel

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.

What do you think about using events?

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');
            }
        }
    }
);

Add SSH upload/download functions

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:

  1. Add ssh_upload() and ssh_download()
  2. Add 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.)

Quiet repack doesn't finish

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.

image

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]

SymfonyCommandTask: wrap a console command in castor

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.

Is there a limit that `run` can stream?

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.

Pipe command to another command

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?

Clarification Needed on `Task` vs `Command`

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.
image

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.
image

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).

Add a HttpClient

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).

Support array of folders for watcher

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";
    });
}

Add a helper to run a command if some files changed since last execution

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.

Conditional `import`

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).

curl command not working on MacOs - "Could not install castor. Is the target directory writeable?" error

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.

Composer files discrepancy

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:

  1. git clone https://github.com/jolicode/castor/
  2. cd castor
  3. composer validate

A PR fixing the issue will follow in a few minutes.

Completion failed : Call to undefined function filter_var

Hello

β˜‘οΈ completion work with castor
image

β˜‘οΈ completion work with a custom phar
image

β›” completion failed with a custom binary
image

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

Add macos-arm64 target

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.

Output is cut off at some places

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!

Import does not work on windows

image

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

[Documentation] Install Castor via composer global

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.

Why is the update check cache so long? (60 days)

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?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.