From 7c5e5e3ede952486010defdb1a938202788847b6 Mon Sep 17 00:00:00 2001 From: Arnout Boks Date: Sat, 19 Oct 2019 21:46:29 +0200 Subject: [PATCH 1/2] Add option to disable the lock file When the `lock` option is set to false, composer will not write a `composer.lock` file to disk. This signals that the package is meant to be developed with unlocked and always updated dependencies. At the moment, both `install` and `update` are allowed to install the dependencies for such a package. If #6822 is implemented, only `update` should be used for packages without a lockfile. https://github.com/composer/composer/issues/8354 --- doc/06-config.md | 5 +++++ res/composer-schema.json | 4 ++++ src/Composer/Command/ConfigCommand.php | 1 + src/Composer/Config.php | 3 +++ src/Composer/Installer.php | 4 +++- 5 files changed, 16 insertions(+), 1 deletion(-) diff --git a/doc/06-config.md b/doc/06-config.md index f3afc4eb1..6ffbea411 100644 --- a/doc/06-config.md +++ b/doc/06-config.md @@ -296,4 +296,9 @@ Example: Defaults to `true`. If set to `false`, Composer will not create `.htaccess` files in the composer home, cache, and data directories. +## lock + +Defaults to `true`. If set to `false`, Composer will not create a `composer.lock` +file. + ← [Repositories](05-repositories.md) | [Community](07-community.md) → diff --git a/res/composer-schema.json b/res/composer-schema.json index cb3594f7b..a45574f77 100644 --- a/res/composer-schema.json +++ b/res/composer-schema.json @@ -290,6 +290,10 @@ "sort-packages": { "type": "boolean", "description": "Defaults to false. If set to true, Composer will sort packages when adding/updating a new dependency." + }, + "lock": { + "type": "boolean", + "description": "Defaults to true. If set to false, Composer will not create a composer.lock file." } } }, diff --git a/src/Composer/Command/ConfigCommand.php b/src/Composer/Command/ConfigCommand.php index 71ec9d816..24e2bd3c3 100644 --- a/src/Composer/Command/ConfigCommand.php +++ b/src/Composer/Command/ConfigCommand.php @@ -412,6 +412,7 @@ EOT ), 'github-expose-hostname' => array($booleanValidator, $booleanNormalizer), 'htaccess-protect' => array($booleanValidator, $booleanNormalizer), + 'lock' => array($booleanValidator, $booleanNormalizer), ); $multiConfigValues = array( 'github-protocols' => array( diff --git a/src/Composer/Config.php b/src/Composer/Config.php index 7abca7dfa..1050096b1 100644 --- a/src/Composer/Config.php +++ b/src/Composer/Config.php @@ -63,6 +63,7 @@ class Config 'archive-dir' => '.', 'htaccess-protect' => true, 'use-github-api' => true, + 'lock' => true, // valid keys without defaults (auth config stuff): // bitbucket-oauth // github-oauth @@ -329,6 +330,8 @@ class Config return $this->config[$key] !== 'false' && (bool) $this->config[$key]; case 'use-github-api': return $this->config[$key] !== 'false' && (bool) $this->config[$key]; + case 'lock': + return $this->config[$key] !== 'false' && (bool) $this->config[$key]; default: if (!isset($this->config[$key])) { return null; diff --git a/src/Composer/Installer.php b/src/Composer/Installer.php index 11edcbe72..d688a4f1f 100644 --- a/src/Composer/Installer.php +++ b/src/Composer/Installer.php @@ -118,7 +118,7 @@ class Installer protected $preferStable = false; protected $preferLowest = false; protected $skipSuggest = false; - protected $writeLock = true; + protected $writeLock; protected $executeOperations = true; /** @@ -164,6 +164,8 @@ class Installer $this->installationManager = $installationManager; $this->eventDispatcher = $eventDispatcher; $this->autoloadGenerator = $autoloadGenerator; + + $this->writeLock = $config->get('lock'); } /** From 22caa0f097a873db2abbbc90ce05c284688f0b47 Mon Sep 17 00:00:00 2001 From: Arnout Boks Date: Sun, 20 Oct 2019 10:51:59 +0200 Subject: [PATCH 2/2] Add tests for installer with lock: false https://github.com/composer/composer/issues/8354 --- .../installer/install-without-lock.test | 25 +++++++++++++++++++ .../installer/update-without-lock.test | 25 +++++++++++++++++++ tests/Composer/Test/InstallerTest.php | 9 ++++++- 3 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 tests/Composer/Test/Fixtures/installer/install-without-lock.test create mode 100644 tests/Composer/Test/Fixtures/installer/update-without-lock.test diff --git a/tests/Composer/Test/Fixtures/installer/install-without-lock.test b/tests/Composer/Test/Fixtures/installer/install-without-lock.test new file mode 100644 index 000000000..c5d73dcbb --- /dev/null +++ b/tests/Composer/Test/Fixtures/installer/install-without-lock.test @@ -0,0 +1,25 @@ +--TEST-- +Installs from composer.json without writing a lock file +--COMPOSER-- +{ + "repositories": [ + { + "type": "package", + "package": [ + { "name": "a/a", "version": "1.0.0" } + ] + } + ], + "require": { + "a/a": "1.0.0" + }, + "config": { + "lock": "false" + } +} +--RUN-- +install +--EXPECT-- +Installing a/a (1.0.0) +--EXPECT-LOCK-- +false diff --git a/tests/Composer/Test/Fixtures/installer/update-without-lock.test b/tests/Composer/Test/Fixtures/installer/update-without-lock.test new file mode 100644 index 000000000..0fd1562c3 --- /dev/null +++ b/tests/Composer/Test/Fixtures/installer/update-without-lock.test @@ -0,0 +1,25 @@ +--TEST-- +Updates when no lock file is present without writing a lock file +--COMPOSER-- +{ + "repositories": [ + { + "type": "package", + "package": [ + { "name": "a/a", "version": "1.0.0" } + ] + } + ], + "require": { + "a/a": "1.0.0" + }, + "config": { + "lock": false + } +} +--RUN-- +update +--EXPECT-- +Installing a/a (1.0.0) +--EXPECT-LOCK-- +false diff --git a/tests/Composer/Test/InstallerTest.php b/tests/Composer/Test/InstallerTest.php index c3b957afb..fa093a460 100644 --- a/tests/Composer/Test/InstallerTest.php +++ b/tests/Composer/Test/InstallerTest.php @@ -197,6 +197,9 @@ class InstallerTest extends TestCase // so store value temporarily in reference for later assetion $actualLock = $hash; })); + } elseif ($expectLock === false) { + $lockJsonMock->expects($this->never()) + ->method('write'); } $contents = json_encode($composerConfig); @@ -319,7 +322,11 @@ class InstallerTest extends TestCase } $run = $testData['RUN']; if (!empty($testData['EXPECT-LOCK'])) { - $expectLock = JsonFile::parseJson($testData['EXPECT-LOCK']); + if ($testData['EXPECT-LOCK'] === 'false') { + $expectLock = false; + } else { + $expectLock = JsonFile::parseJson($testData['EXPECT-LOCK']); + } } $expectOutput = isset($testData['EXPECT-OUTPUT']) ? $testData['EXPECT-OUTPUT'] : null; $expect = $testData['EXPECT'];