Coder Social home page Coder Social logo

production-dependencies-guard's Introduction

production-dependencies-guard

Prevents development packages from being added into require and getting into production environment. In practical field prevents e.g. debug tool-bars deployment into production environments.

Additionally, you can configure the guard to decline packages with missing/unfit license, abandoned or mentioning debug in description and analyze packages on basis of composer.lock (deeper analysis).

Installation

composer require --dev kalessil/production-dependencies-guard:dev-master

Configuration

Additional guard checks can be enabled in the top-level composer.json file:

{
    "name": "...",

    "extra": {
        "production-dependencies-guard": [
            "check-lock-file",
            "check-description",
            "check-license",
            "check-abandoned",
            
            "white-list:vendor/package-one",
            "white-list:vendor/package-two",
            
            "accept-license:MIT",
            "accept-license:proprietary"
        ]
    }
}
  • white-list:... adds a package to white-list, so it's not getting reported in spite of violations
  • check-lock-file uses composer.lock instead of composer.json, allowing deeper dependencies analysis
  • check-description enables description and keywords analysis (searches debug), allowing to detect custom dev-packages
  • check-abandoned enables abandoned packages checking
  • check-license enables license checking (packages must provide license information)
  • accept-license:... specifies which licenses should be accepted (if the setting omitted, any license incl. proprietary)

Usage

When the package is added to require-dev section of your composer.json file ("kalessil/production-dependencies-guard": "dev-master"), it'll prevent adding dev-packages into require section. Since dev-packages has no security guaranties (not intended for production use, only development purposes), this also improves your application security.

composer require --dev kalessil/production-dependencies-guard:dev-master

composer require phpunit/phpunit:*
# it should be `composer require --dev phpunit/phpunit:*` here

will run with an error (profit!):

./composer.json has been updated

Installation failed, reverting ./composer.json to its original content.

[RuntimeException]                                                                   
  Dependencies guard has found violations in require-dependencies (source: manifest):  
   - phpunit/phpunit: dev-package-name

Stability

This package is only available in its dev-master version: according to the package purpose.

production-dependencies-guard's People

Contributors

kalessil 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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

Forkers

edditor edefimov

production-dependencies-guard's Issues

Allow missing license

Using PDG (production-dependencies-guard) in existing projects stops the whole team because after installing and setting the config like this:

"production-dependencies-guard": [
      "check-description",
      "check-license"
    ]

You get lots of errors:

Dependencies guard has found violations in require-dependencies (source: manifest):
foo missing-license

Please add an option to ignore missing license.
Otherwise we would have to add almost 13 packages to whitelist by now.

Composer 2 support

I see this error message:

kalessil/production-dependencies-guard dev-master requires composer-plugin-api ^1.1 -> found composer-plugin-api[2.0.0] but it does not match the constraint.

You are using Composer 2, which some of your plugins seem to be incompatible with. Make sure you update your plugins or report a plugin-issue to ask them to support Composer 2.

FR: Dedicated run

Right now this is an extension to composer and hooking into it.
Running these assertions in CI is not very easy.
So having a dedicated config file or some command to run specific configs during CI would be great.

  • We rather have such blocking tools decoupled in CI than blocking a developers interest in finding out interesting stuff.
  • This is currently possible by putting the extra-config in the repo but running composer require ... and composer update in the CI.
  • But there are multiple scenarios:
    • Our SAST-CI wants to go for check-abandoned only.
    • Our Compliance-CI wants to go for plenty other checks.
    • The Compliance-CI shall fail on check-lock-file but pass with warning for check-description
    • This makes it 3 different configs.
    • By now we store different configs as JSON and merge them during CI (jq -s '.[0] * .[1]' composer.json pdg-sast.json | sponge composer.json)
  • So having different configs is possible but not native by this package.

Here you go. This is what I thought about it yesterday :)
Focus is on a dedicated command for CI and allow the dev to try things.

Don't run on self removal

Our CI installs composer packages with dev deps, prepares blobs for release and then removes dev packages to produce release image without them.
Unfortunately, production-dependencies-guard plugin tries to run itself after it's been removed.

$ composer install
# do some work using dev packages………………………………… and then remove them
$ composer install --prefer-dist --no-dev --optimize-autoloader --no-suggest --apcu-autoloader
Loading composer repositories with package information
Installing dependencies from lock file
Package operations: 0 installs, 0 updates, 84 removals
……………………………… lots of packages removed
  - Removing localheinz/composer-normalize (0.9.0)
  - Removing kalessil/production-dependencies-guard (dev-master)
……………………………… lots of packages removed
Generating optimized autoload files

Fatal error: Uncaught Error: Class 'Kalessil\Composer\Plugins\ProductionDependenciesGuard\Suppliers\FromComposerManifestSupplier' not found in /tmp/build/vendor/kalessil/production-dependencies-guard/src/Guard.php:105
Stack trace:
#0 [internal function]: Kalessil\Composer\Plugins\ProductionDependenciesGuard\Guard->checkGeneric(Object(Composer\Script\Event))
#1 phar:///usr/bin/composer/src/Composer/EventDispatcher/EventDispatcher.php(176): call_user_func(Array, Object(Composer\Script\Event))
#2 phar:///usr/bin/composer/src/Composer/EventDispatcher/EventDispatcher.php(96): Composer\EventDispatcher\EventDispatcher->doDispatch(Object(Composer\Script\Event))
#3 phar:///usr/bin/composer/src/Composer/Installer.php(324): Composer\EventDispatcher\EventDispatcher->dispatchScript('post-install-cm...', false)
#4 phar:///usr/bin/composer/src/Composer/Command/InstallCommand.php(122): Composer\Installer->run()
#5 phar:///usr/bin/composer/vendor/symfony/console/Command/Command.php(245): Composer\Command\InstallCommand->execute(Object(Sym in /tmp/build/vendor/kalessil/production-dependencies-guard/src/Guard.php on line 105

accept-licence: any-open-source wildcard

It would be very useful if you could add something like accept-licence: any-open-source which would be same as accepting all the versions of open source licences. I have this is my list and it is a bit bothering to maintain it.

      "accept-license:Apache-2.0",
      "accept-license:BSD-2-Clause",
      "accept-license:BSD-3-Clause",
      "accept-license:GPL-2.0",
      "accept-license:GPL-2.0-only",
      "accept-license:GPL-3.0",
      "accept-license:GPL-3.0-only",
      "accept-license:ISC",
      "accept-license:LGPL-2.1-or-later",
      "accept-license:LGPL-3.0",
      "accept-license:MIT",

check-license requires all instead of only one when license is an array

Hi,

Today I ran into an issue when the license of a package is an array. In the composer.json documentation the following is said about using an array for the license:

For a package, when there is a choice between licenses ("disjunctive license"), multiple can be specified as array.

So you can choose which license you want to use. Based on that my expectation would be that the check-license guard will consider the license of a package valid if at least one of its licenses is allowed via accept-license:. However it seems right now that the check-license guard is instead requiring that all the licenses in the array are allowed via accept-license:.

This creates a problem with for example the nette/utils package which allows you to use either a BSD 3-Clause, GPL 2.0 or GPL 3.0 license. If you don't want to allow GPL, but are fine with BSD 3-Clause, the guard (incorrectly) blocks the package from installing. This also prevents you from installing Laravel because nette/utils is an indirect dependency for Laravel.

A quick way to reproduce is to start a docker container using docker run -it --rm php:8.0-cli bash -l and then running:

apt-get update -qq
apt-get install -qq -y git unzip jq moreutils > /dev/null
curl -s -o /usr/local/bin/composer https://getcomposer.org/download/latest-stable/composer.phar
chmod +x /usr/local/bin/composer
mkdir -p /app
cd /app
composer require --quiet --dev kalessil/production-dependencies-guard:dev-master

echo -e "\n==========> nette/utils is rejected even though BSD-3-Clause is an accepted license\n"
jq '. * {"extra":{"production-dependencies-guard":["check-license","accept-license:BSD-3-Clause"]}}' composer.json | sponge composer.json
jq '.' composer.json
composer require --quiet nette/utils

echo -e "\n==========> nette/utils is allowed because we're accepting all three licenses BSD-3-Clause, GPL-2.0-only and GPL-3.0-only\n"
jq '. * {"extra":{"production-dependencies-guard":["check-license","accept-license:BSD-3-Clause","accept-license:GPL-2.0-only","accept-license:GPL-3.0-only"]}}' composer.json | sponge composer.json
jq '.' composer.json
composer require --quiet nette/utils

echo -e "\n==========> laravel/framework is not allowed with check-lock-file because it depends on nette/utils even though we are allowing the minimum licenses needed\n"
jq '. * {"extra":{"production-dependencies-guard":["check-lock-file","check-license","accept-license:MIT","accept-license:BSD-3-Clause","accept-license:Apache-2.0"]}}' composer.json | sponge composer.json
jq '.' composer.json
composer require --quiet laravel/framework

Show "composer why" among dev-package

This error is shown:

 [RuntimeException]                                                                    
  Dependencies guard has found violations in require-dependencies (source: lock-file):  
   - symfony/debug: dev-package-name  

But I did not require this package so I need to ask composer why .
It would be great if the error message already shows that symfony/console brought this upon us.

Aside: A bit sad that everything gets block due to symfony/console .

FR: add white-list options ('white-list:vendor/package1', 'white-list:vendor/package2')

I am thinking of a use-case like this: I am developing an add-on for a development tool, let's say CaptainHook. CaptainHook is clearly a development tool and is tagged in such a way. That way I could not install it as a require dependency in my application project. However, in case I want to develop an extension for CaptainHook, I need to add the CaptainHook package to the require section of my extension so that composer install is working fine. But since CaptainHook is marked a development dependency, this would fail when your plugin is enabled. Or am I missing the point?

PHP 8 support

Hi,

The current composer.json PHP requirement for ^7.0 blocks upgrading to PHP 8. Is it possible to expand to ^7.0|^8.0 or are there any known incompatibilities?

Thanks!

Is there any way to declare own protected dependecies list?

Currently, it check and prevent to install dependencies declared in Repository, so if someone create library for dev purpose,than he, or community should add PR with new package in this repo. But what about internal project packages for dev, that often has created for big complex projects

Whitelist ability to specify specific guards

Hi,

First I want to say that I love this composer plugin. It really helps keeping track of not accidentally installing a bad license or an abandoned package. The check-description guard is something I like too, but is something that feels a bit conflicting with the whitelist. There are some packages that I'd like to whitelist (for example symfony/error-handler because it's included as a non-dev requirement by Laravel but the guard blocks it as it thinks it's a debug only package). However I'd only like to whitelist that package for the check-description guard, not for the check-abandoned or the check-license guards. If for some reason the package becomes abandoned, or they change the license, installation should be blocked.

So maybe the white-list options can be expanded for example like so:

{
    "name": "...",

    "extra": {
        "production-dependencies-guard": [
            "check-lock-file",
            "check-description",
            "check-license",
            "check-abandoned",
            
            "white-list:vendor/package-one:license,abandoned",
            "white-list:vendor/package-two",
            
            "accept-license:MIT"
        ]
    }
}

A change like this could be backwards compatible, where vendor/package-two still uses all guards, but vendor/package-one will only trigger when checking the license or when it's abandoned.

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.