Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RFC: Satis as a composer 2.3 plugin (POC implementation available) #700

Closed
ralflang opened this issue Aug 17, 2022 · 9 comments
Closed

RFC: Satis as a composer 2.3 plugin (POC implementation available) #700

ralflang opened this issue Aug 17, 2022 · 9 comments

Comments

@ralflang
Copy link
Contributor

ralflang commented Aug 17, 2022

Running Satis as a Composer Plugin

tldr - I have mostly implemented a composer plugin that makes a slightly patched satis work as a composer 2.3.x plugin. I want to know if anybody is interested in this before I spend more time on it.

Motivation

I use satis in the build pipeline for a 100+ packages framework. I have recently begun to expand the framework's composer installer plugin to replace older standalone tools that are currently used in CI jobs and in the development process. Discovering the similarities between satis and composer I decided to spend two evening hours on making satis run inside composer

State of the PoC

All four commands are wrapped into shim classes which changes the name to satis:add, satis:build etc and nicely groups them below the native composer commands in a special satis section.

The add and purge commands work as normal.
All commandline options are passed work as desired. I did only limited testing.
The build command sort of works:

  • packagist is not used unless explicitly configured in satis.json

  • in require-all mode, all packages of the configured repos are downloaded. If you enable the packagist repo, you will essentially get a local. static mirror

  • commandline repo filters do work
    - Explicit require lists in the satis.json file currently don't work as expected. Instead, as soon as the satis file contains a require section, the require section of the root package is used. In standalone mode, satis abuses a composer installation and pretends its config file is a root package. I will need to trick the already running composer into accepting satis' config file as the root package.
    Now composer accepts requires from the commandline's json file. This may be a satis.json or your project's root package if that's what you desire. Could actually be a useful edge case.

  • commandline package filters were not tested but likely are affected by the root package issue.

  • In plugin mode, satis does not install its own composer/composer version (unless it is the root package) but runs against the composer phar file which calls into it.

Potential uses/benefits

Composer has a more mature but similar base application, event system, and plugin ecosystem. Hooking satis into composer allows us to shrink satis' codebase. Developers / volunteers can focus on actual functionality and leave infrastucture work to composer/composer which is already maintained much better. Third party plugin developers can leverage satis for their automation or integration plugins and call into it by emitting events (provided satis moves into that direction).

One could easily integrate the little boilerplate plugin into satis itself, in other words make satis itself a composer plugin. I decided to leave that unexplored for the moment and gather feedback first. Maybe there is no interest in this at all.

As a side effect I fixed some incompatibilities between satis (dev-main) and composer 2.3.x

Questions

  • Is there any interest at all in this? If not, at least it was a fun experiment.
  • Which line of development would you prefer, making satis itself the plugin or making satis only capable of working with the plugin library and otherwise leaving it as it is?
@ralflang
Copy link
Contributor Author

Update: I did run this against the phar release of composer 2.4.0 and it did work just as well as with composer 2.3.10.

How to reproduce:

Have a root project with a standin composer.json

{
    "name": "satis/repo",
    "homepage": "horde-satis.maintaina.com",
    "description": "A base project for a satis-generated repo",
    "type": "project",
    "repositories": {
        "ralflang/satis-plugin" : {
            "url": "https://github.com/ralflang/satis-plugin",
            "type": "github"
            },
        "composer/satis": {
          "url": "https://github.com/ralflang/satis",
          "type": "github"

        }
    },
    "require": {
        "composer-plugin-api": "^2.3",
    },
    "require-dev": {
        "ralflang/satis-plugin": "dev-0.1.0-dev"
    },
    "license": "GPL-3.0-only",
    "authors": [
        {
            "name": "Ralf Lang",
            "email": "[email protected]"
        }
    ],
    "minimum-stability": "dev",
    "prefer-stable": true,
    "config": {
        "allow-plugins": {
            "horde/horde-installer-plugin": true,
            "ralflang/satis-plugin": true
        }
    }
}

now run composer install and if asked, trust the plugin.
now run composerand see the new commands pop up in your help screen

...
 update               [u|upgrade] Updates your dependencies to the latest version according to composer.json, and updates the composer.lock file.
  validate             Validates a composer.json and composer.lock.
 satis
  satis:add            Add repository URL to satis JSON file
  satis:build          Builds a composer repository out of a json file
  satis:configure      
  satis:init           Initialize Satis configuration file
  satis:purge          Purge packages

Unfortunately satis and composer json files are not 100% compatible. They don't tolerate each others' keys like "type" (for composer.json) and the mandatory "homepage" (for satis.json). Otherwise you could use a project's root package composer.json as an input file for a composer satis:build run.

@SvenRtbg
Copy link
Contributor

What is your idea behind it? I see I can execute some commands now, but what is intended to happen - in a broad sense and more high-level?

Currently I can have a dedicated configuration file and a dedicated CLI executable, and it is creating my repository. What is happening better/different with the plugin approach?

@ralflang
Copy link
Contributor Author

Ultimately I wanted it to work with composer 2.3/2.4 and then got to play around a bit. Abandoning satis' own Application kernel in favor of hooking into composer's runtime helped me get there fast.

As a stretch goal, to trigger satis based on events programmatically from another composer plugin. Think like #508 but through the intended interface rather than by touching implementation details of composer itself.

Not having satis install its own, outdated copy of composer made sense to me.

As an option, reducing the amount of code that is just a less maintained, older copy of composer's internals and ends up calling into composer anyway also seemed not bad. The plugin approach does not stop you from having a dedicated config file or multiple.

@alcohol
Copy link
Member

alcohol commented Aug 30, 2022

Interesting. If you can make it work as intended, without disrupting normal usage of Satis as most users are accustomed to, then I'm fine with merging your PR.

@ralflang
Copy link
Contributor Author

Yes, that is easily possible.
The current PR creates one disruptive change on purpose:

  • If satis is not the root project, composer will not be installed as a dependency. In this case, a call to the standalone cli creates an instructive error message and aborts.

I will move composer/composer back to the require: section and test for possible conflicting scenarios. I will report back once it is in the PR.

@ralflang
Copy link
Contributor Author

@alcohol I have re-added composer/composer to require section. In my tests it now works in CLI mode both as a root package and as a dependency.

@ralflang
Copy link
Contributor Author

ralflang commented Oct 6, 2022

@alcohol Is there anything left to do?

@alcohol
Copy link
Member

alcohol commented Oct 10, 2022

I don't think so, sorry. Will see if I can merge this right now.

@ralflang
Copy link
Contributor Author

Closing as the RFC resulted in a merge.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants