{"id":20208210,"url":"https://github.com/cubiclesoft/php-decomposer","last_synced_at":"2025-07-11T23:39:42.231Z","repository":{"id":145129438,"uuid":"94651677","full_name":"cubiclesoft/php-decomposer","owner":"cubiclesoft","description":"Generate no-conflict standalone builds of PHP Composer/PSR-enabled software.  MIT or LGPL.","archived":false,"fork":false,"pushed_at":"2025-02-03T21:58:47.000Z","size":2163,"stargazers_count":11,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-24T11:44:35.991Z","etag":null,"topics":["composer","decomposer","linter","linting","php"],"latest_commit_sha":null,"homepage":null,"language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cubiclesoft.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":"support/base_decompose.php","governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-06-17T22:08:13.000Z","updated_at":"2025-03-01T18:35:02.000Z","dependencies_parsed_at":null,"dependency_job_id":"0ef353ad-b9f3-411b-bb8d-26cdecd98791","html_url":"https://github.com/cubiclesoft/php-decomposer","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cubiclesoft%2Fphp-decomposer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cubiclesoft%2Fphp-decomposer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cubiclesoft%2Fphp-decomposer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cubiclesoft%2Fphp-decomposer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cubiclesoft","download_url":"https://codeload.github.com/cubiclesoft/php-decomposer/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248221748,"owners_count":21067619,"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","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":["composer","decomposer","linter","linting","php"],"created_at":"2024-11-14T05:34:32.490Z","updated_at":"2025-04-10T12:55:02.773Z","avatar_url":"https://github.com/cubiclesoft.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"Decomposer\n==========\n\nGenerate no-conflict standalone builds of PHP Composer/PSR-enabled software.\n\nDecomposer is also a fantastic dependency linting tool for Composer enabled projects.  Try integrating it into your automated Continuous Integration (CI) lifecycle to identify various software issues long before anyone else discovers them.\n\n[![Donate](https://cubiclesoft.com/res/donate-shield.png)](https://cubiclesoft.com/donate/) [![Discord](https://img.shields.io/discord/777282089980526602?label=chat\u0026logo=discord)](https://cubiclesoft.com/product-support/github/)\n\nFeatures\n--------\n\n* Quickly reduce Composer/PSR software down to one or two files containing only the parts that are actually used.\n* Three decomposition modes depending on application needs.\n* Easily create and manage projects.\n* A complete, question/answer enabled command-line interface.\n* Has a liberal open source license.  MIT or LGPL, your choice.\n* Designed for relatively painless integration into your environment.\n* Sits on GitHub for all of that pull request and issue tracker goodness to easily submit changes and ideas respectively.\n\nGetting Started\n---------------\n\nThe command-line interface is question/answer enabled, which means all you have to do is run:\n\n```\nphp decomposer.php\n```\n\nWhich will enter interactive mode and guide you through the entire process.\n\nOnce you grow tired of manually entering information, you can pass in some or all of the answers to the questions on the command-line:\n\n```\nphp decomposer.php list\n\nphp decomposer.php create myproject\n\nphp decomposer.php -s decompose myproject all\n```\n\nThe -s option suppresses normal output (except for fatal error conditions), which allows for the processed JSON result to be the only thing that is output.  Useful for automation.\n\nCreating Projects\n-----------------\n\nTo create a project, run:\n\n```\nphp decomposer.php create [yourprojectname]\n\ncd projects/[yourprojectname]\n\nphp composer.phar require [vendor/someproject:~1.2]\nphp composer.phar require [vendor2/someotherproject:~2.0]\n...\n\nphp decompose.php all\n```\n\nThis will create a set of directories, run Composer to pull down the various bits of software, and then generate the final decomposed build bundling every file into one fully-validated PHP file in the `projects/[yourprojectname]/final` directory.\n\nInstrumenting Builds\n--------------------\n\nThe 'decompose' command does all of the heavy lifting.  Using the 'all' mode will always work but might be a bit more resource intensive (e.g. RAM) than might be desired on the tail end of things (i.e. your application).  To minimize resource usage, it is possible to teach the command about the classes that are actually going to be used in the most common scenarios.  This is accomplished by instrumenting the build with one or more working examples.\n\nEdit the `/projects/[yourprojectname]/examples.php` file that was generated during project creation.  After that, grab some example code and put it where `examples.php` says to put example code.  Test the functionality by manually running `examples.php` from the command-line.  Note that the usual `require \"vendor/autoload.php\";` should NOT be called as that is automatically handled by `DecomposerHelper::Init()`.\n\n```\ncd projects/[yourprojectname]\nphp examples.php\n```\n\nRunning the code updates 'instrumented.json', which contains a list of files that were loaded by `examples.php`.  This information is used to correctly instrument the build when decomposing later on.\n\nOnce the code is working, preferably with no output to the screen, the 'auto' and 'none' modes become more useful.\n\n```\nphp decompose.php auto\n```\n\nThe 'auto' mode appends an autoloader to the first generated file that loads the second file if the autoloader is ever called by PHP.  The 'none' mode is for anyone who likes to live dangerously and is okay with their application breaking in spectacular ways at inopportune times.\n\nPatching Broken Software\n------------------------\n\nSometimes a Composer project makes assumptions about where it sits in its ecosystem and the developers are stubborn to change the software.  If a file called `decomposer.diff` exists in the project's directory (i.e. a text diff file), Decomposer will automatically attempt to apply the patch to the software before instrumenting it.\n\nIf you design a working patch for using a specific project with Decomposer, be a good netizen and commit it back to the original repository.  The authors will (possibly) appreciate it.\n\nAt the end of a Decomposer run, it outputs any 'warnings' it encountered as well as any 'failed' files.  Warnings are emitted for very specific functions that are known to cause issues and will likely require a patch.  Failed files are emitted for a variety of reasons and may or may not result in functional output.\n\nAny patches should be extremely laser-focused such that they are idempotent since Decomposer will always attempt to apply all patches before instrumenting every time it runs.\n\nHow It Works\n------------\n\nDecomposer takes in a number of pieces of information, runs any patches that need to be applied, instruments the build multiple times, generates several PHP files during the process to guarantee that dependency order is maintained and that no errors occur, and verifies the build.\n\nThe most interesting parts of the process are extracting just the useful content bits (i.e. code minus comments), the approach used to determine if a file failed to load, and how dependency calculations are made.  The built-in PHP tokenizer function `token_get_all()` does most of the work of identifying things such as comments, whitespace, and namespace keywords.  Determining file load failures is a bit trickier but each PHP file that will be loaded is written to disk before it is included.  Dependencies are determined by monitoring what additional files are loaded when a specific PHP file is loaded.  Removing failed files and resolving dependencies repeats ad nauseum until nothing else can be processed.\n\nDecomposer is somewhat brute force-ish in its approach and abuses the Composer autoloader to get to its destination, which is why it can take anywhere from a few seconds to a few minutes to decompose a project.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcubiclesoft%2Fphp-decomposer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcubiclesoft%2Fphp-decomposer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcubiclesoft%2Fphp-decomposer/lists"}