{"id":13828529,"url":"https://github.com/duncan3dc/console","last_synced_at":"2025-10-14T06:13:22.494Z","repository":{"id":23641183,"uuid":"27011266","full_name":"duncan3dc/console","owner":"duncan3dc","description":"Create command line php applications using symfony/console","archived":false,"fork":false,"pushed_at":"2025-06-11T14:10:56.000Z","size":117,"stargazers_count":16,"open_issues_count":0,"forks_count":3,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-09-27T16:43:00.109Z","etag":null,"topics":["cli","php","symfony"],"latest_commit_sha":null,"homepage":null,"language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/duncan3dc.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2014-11-22T20:20:37.000Z","updated_at":"2025-06-11T14:10:56.000Z","dependencies_parsed_at":"2024-08-04T09:08:39.361Z","dependency_job_id":"e662e66f-eb80-4e39-80b1-8c4b78f29d1f","html_url":"https://github.com/duncan3dc/console","commit_stats":{"total_commits":132,"total_committers":2,"mean_commits":66.0,"dds":0.007575757575757569,"last_synced_commit":"5ef1ab9e26d04287516f22aa9056ae3bbcfa48e3"},"previous_names":[],"tags_count":30,"template":false,"template_full_name":null,"purl":"pkg:github/duncan3dc/console","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/duncan3dc%2Fconsole","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/duncan3dc%2Fconsole/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/duncan3dc%2Fconsole/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/duncan3dc%2Fconsole/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/duncan3dc","download_url":"https://codeload.github.com/duncan3dc/console/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/duncan3dc%2Fconsole/sbom","scorecard":{"id":359620,"data":{"date":"2025-08-11","repo":{"name":"github.com/duncan3dc/console","commit":"db08bf008a065e1039b605df548efd3ba9fc4840"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.3,"checks":[{"name":"Code-Review","score":0,"reason":"Found 1/29 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Maintained","score":4,"reason":"5 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 4","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: containerImage not pinned by hash: Dockerfile:2","Info:   0 out of   1 containerImage dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: Apache License 2.0: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'main'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 2 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-18T10:28:42.009Z","repository_id":23641183,"created_at":"2025-08-18T10:28:42.009Z","updated_at":"2025-08-18T10:28:42.009Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279018118,"owners_count":26086280,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-14T02:00:06.444Z","response_time":60,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cli","php","symfony"],"created_at":"2024-08-04T09:02:50.971Z","updated_at":"2025-10-14T06:13:22.464Z","avatar_url":"https://github.com/duncan3dc.png","language":"PHP","funding_links":["https://tidelift.com/subscription/pkg/packagist-duncan3dc-console?utm_source=packagist-duncan3dc-console\u0026utm_medium=referral\u0026utm_campaign=readme"],"categories":["PHP"],"sub_categories":[],"readme":"console\n=======\n\nCreate command line php applications using symfony/console.  \nThis is basically a fork of symfony/console which does things a little differently and adds some extra features.  \nMost of the features are useful when running commands in a background context (such as via crontab).  \n\n[![release](https://poser.pugx.org/duncan3dc/console/version.svg)](https://packagist.org/packages/duncan3dc/console)\n[![build](https://github.com/duncan3dc/console/workflows/.github/workflows/buildcheck.yml/badge.svg?branch=master)](https://github.com/duncan3dc/console/actions?query=branch%3Amaster+workflow%3A.github%2Fworkflows%2Fbuildcheck.yml)\n[![coverage](https://codecov.io/gh/duncan3dc/console/graph/badge.svg)](https://codecov.io/gh/duncan3dc/console)\n\n\nLoading Commands\n----------------\nCommands can be automatically created from classes (meaning you don't need to call setName() inside your command class) using the following criteria:\n* Files/classes must be named using CamelCase and must end in \"Command\" (with files having the .php extension)  \n* Each uppercase character will be converted to lowercase and preceded by a hyphen  \n* Directories will represent namespaces and each separater will be replaced with a colon  \nUsing the example below, the file src/commands/Category/Topic/RunCommand.php will create a command called category:topic:run\n```php\n$application-\u003eloadCommands(\"src/commands\");\n```\n_Of course, they can still be added the [symfony way](http://symfony.com/doc/current/components/console/introduction.html)_\n\n\nOutput\n------\nWe use [league/climate](http://climate.thephpleague.com/) for terminal output, whilst also maintaining support for the [symfony way](http://symfony.com/doc/current/components/console/introduction.html#coloring-the-output).  \nSo all of the following is possible:\n```php\n$output-\u003eblue()-\u003eout(\"Blue? Wow!\");\n$output-\u003edump($complexArrayForCLImate);\n$output-\u003ewriteln(\"\u003cerror\u003eI am a symfony/console error\u003c/error\u003e\");\n$output-\u003eerror(\"I am a league/climate error\");\n```\n\n\nTime Limit Commands\n-------------------\nCommands can limit how long they are run for, and end in a controlled way when the limit is reached.  \nInside your command's class you can call the timeout() method and pass the number of seconds your command should run for.  \n```php\nclass LimitedCommand extends \\duncan3dc\\Console\\Command\n{\n    protected function execute(InputInterface $input, OutputInterface $output)\n    {\n        while (true) {\n            # If the command has been running for more than 10 minutes then end now\n            if ($this-\u003etimeout(60 * 10)) {\n                break;\n            }\n        }\n    {\n}\n```\n_This behaviour can be overridden by passing the ```--no-time-limit``` when running the application, this will cause the timeout() method to always return false_\n\n\nCalling An Existing Command\n---------------------------\nThe [symfony way](http://symfony.com/doc/current/components/console/introduction.html#calling-an-existing-command) of calling an existing command can be a little long-winded, with steps that seem unnecessary (eg, specifying the command name twice).  \nThe runCommand() method provides a simplified way of doing this (using the example from the symfony docs):\n```php\n$returnCode = $this-\u003egetApplication()-\u003erunCommand(\"demo:greet\", [\n    \"name\"      =\u003e  \"Fabien\",\n    \"--yell\"    =\u003e  true,\n], $input, $output);\n```\n_This also ensures any command event listeners that have been registered are called, which symfony does not do_\n\n\nCommand Locking\n---------------\nAll commands are automatically locked to prevent the same command being run simultaneously on the same host.  \nYou can prevent particular commands from locking using the doNotLock() method:\n```php\nprotected function configure()\n{\n    $this\n        -\u003edoNotLock()\n        -\u003esetDescription(\"This command can run as many times as it likes, whether the previous run has finished or not\");\n}\n```\n_When a command cannot run it will exit with status 201, represented by the class constant Application::STATUS_LOCKED_\n\n\nTab Completion\n--------------\nTab completion is provided by [stecman/symfony-console-completion](https://github.com/stecman/symfony-console-completion) and instructions on setting it up for your application can be found in the README.md of that repository.  \n\n\nNamespace Listing\n-----------------\nWhen you are entering commands in completion mode, it can often be useful to view the list of available commands in the namespace.  \nFor example you might type `cat` then press tab which would complete the namespace, and the namespace separator:\n```sh\n:~$ console category:\n```\nBut when you press tab again, you might be presented with a list of commands (or sub-namespaces) you don't entirely recognise. At this point the symfony way would be to delete the colon, run your cursor back to before your namespace, and type `list`:\n```sh\n:~$ console list category\n```\nThen having identified the command you need from the listing you would then need to type what you had earlier, before entering the command you require:\n```sh\n:~$ console category:\n```\nTo make this use case easier, we have made running a command with a trailing colon, an alias for the list command shown above, so you can actually run:\n```sh\n:~$ console category:\n```\nWhich will list all your available commands, then you can press the up arrow to retrieve that same command from your shell's history and carry on entering the command name, much quicker\n\n\n## duncan3dc/console for enterprise\n\nAvailable as part of the Tidelift Subscription\n\nThe maintainers of duncan3dc/console and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source dependencies you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use. [Learn more.](https://tidelift.com/subscription/pkg/packagist-duncan3dc-console?utm_source=packagist-duncan3dc-console\u0026utm_medium=referral\u0026utm_campaign=readme)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fduncan3dc%2Fconsole","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fduncan3dc%2Fconsole","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fduncan3dc%2Fconsole/lists"}