Giter VIP home page Giter VIP logo

phelp's People

Contributors

allanmessias avatar

Watchers

 avatar

phelp's Issues

Should give Command a better modeling

I should model a command for a better representation.

A command must have:
1 - A name;
2 - A executable way (Controller or Callback);
3 - It's description;
4 - It's flags (To be implemented);
5 - It's manual (How to be executed);

The base Command is "help" and if called with another Command, it should show the latter's manual.

Happy Path ๐Ÿ˜˜

Well, looks like I'm building a framework for myself without even knowing and forgot about what this application needs to do. It's a simple task actually.

It only needs to:
1 - Create a php file with the given name;
2 - Asks if it's a class, if it is, create like this:

<?php

class GivenName
{
}

3 - If it's an interface or a trait, do it as well, following this pattern.
4 - Insert the namespace automatically

The motivation for this project it's just because I'm really tired of writing this stuff in PHP and I really want to automate this stuff, because I don't want to rely on another text editor, like PHPStorm, that does this out of the box.

Symfony Command Line Application Flow

I've downloaded the Symfony Command Line Application framework and saw a couple of things that could help me out with the Phelp application design, concerning to Command object

To do this, I'm using this code as example:

$application = new Application();
$application->register('generate-admin')
    ->addArgument('username', InputArgument::REQUIRED)
    ->setCode(function (InputInterface $input, OutputInterface $output): int {
        $output->writeln("Teste");
        return Command::SUCCESS;
    });
$application->run();

So, this code does the some things.
1 - Instantiante the application and register the command "generate-admin"
2 - Then, the Application will call it's "add" method to create a new Command instance with the given name
3 - Inside Command's constructor, it's definition property will be assigned as a InputDefinition object, which will later contain all the definitions to the given input, such as: arguments, options, negations and shortcuts
4 - Then, it will set the name of the command and the description
5 - When all is set up, the "add" method will resume as follow:

  1. 1 - First, it'll set the command's attribute "application" to the current application, which will give context to the command and set the helperSet, which are formatter, debug_formatter, process and question
  2. 2 - Will call the init method, that will check if it's already initialized, if not, will set it to true and then add get the default commands: return [new HelpCommand(), new ListCommand(), new CompleteCommand(), new DumpCompletionCommand()];
    and add to the command array

The Command model in the framework is as it follows:

// see https://tldp.org/LDP/abs/html/exitcodes.html
    public const SUCCESS = 0;
    public const FAILURE = 1;
    public const INVALID = 2;

    /**
     * @var string|null The default command name
     *
     * @deprecated since Symfony 6.1, use the AsCommand attribute instead
     */
    protected static $defaultName;

    /**
     * @var string|null The default command description
     *
     * @deprecated since Symfony 6.1, use the AsCommand attribute instead
     */
    protected static $defaultDescription;

    private ?Application $application = null;
    private ?string $name = null;
    private ?string $processTitle = null;
    private array $aliases = [];
    private InputDefinition $definition;
    private bool $hidden = false;
    private string $help = '';
    private string $description = '';
    private ?InputDefinition $fullDefinition = null;
    private bool $ignoreValidationErrors = false;
    private ?\Closure $code = null;
    private array $synopsis = [];
    private array $usages = [];
    private ?HelperSet $helperSet = null;

public static function getDefaultName(): ?string
    {
        $class = static::class;

        if ($attribute = (new \ReflectionClass($class))->getAttributes(AsCommand::class)) {
            return $attribute[0]->newInstance()->name;
        }

        $r = new \ReflectionProperty($class, 'defaultName');

        if ($class !== $r->class || null === static::$defaultName) {
            return null;
        }

        trigger_deprecation('symfony/console', '6.1', 'Relying on the static property "$defaultName" for setting a command name is deprecated. Add the "%s" attribute to the "%s" class instead.', AsCommand::class, static::class);

        return static::$defaultName;
    }

    public static function getDefaultDescription(): ?string
    {
        $class = static::class;

        if ($attribute = (new \ReflectionClass($class))->getAttributes(AsCommand::class)) {
            return $attribute[0]->newInstance()->description;
        }

        $r = new \ReflectionProperty($class, 'defaultDescription');

        if ($class !== $r->class || null === static::$defaultDescription) {
            return null;
        }

        trigger_deprecation('symfony/console', '6.1', 'Relying on the static property "$defaultDescription" for setting a command description is deprecated. Add the "%s" attribute to the "%s" class instead.', AsCommand::class, static::class);

        return static::$defaultDescription;
    }

    /**
     * @param string|null $name The name of the command; passing null means it must be set in configure()
     *
     * @throws LogicException When the command name is empty
     */
    public function __construct(string $name = null)
    {
        $this->definition = new InputDefinition();

        if (null === $name && null !== $name = static::getDefaultName()) {
            $aliases = explode('|', $name);

            if ('' === $name = array_shift($aliases)) {
                $this->setHidden(true);
                $name = array_shift($aliases);
            }

            $this->setAliases($aliases);
        }

        if (null !== $name) {
            $this->setName($name);
        }

        if ('' === $this->description) {
            $this->setDescription(static::getDefaultDescription() ?? '');
        }

        $this->configure();
    }

Commands must be a list

For better understanding, Commands should be stored in a list and the application should rely on this list for execute the command it's being called.

A CommandList should have:
1 - A list of commands
2 - Every command must be like this: ["name_of_command" => CommandObject]

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.