mirror of
https://github.com/renovatebot/renovate.git
synced 2025-01-12 23:16:26 +00:00
feat(composer): extract contraints on update artifacts (#11022)
This commit is contained in:
parent
f0e1070299
commit
ab800f46d1
6 changed files with 55 additions and 59 deletions
|
@ -2,10 +2,6 @@
|
|||
|
||||
exports[`manager/composer/extract extractPackageFile() extracts dependencies with lock file 1`] = `
|
||||
Object {
|
||||
"constraints": Object {
|
||||
"composer": "^1.10.0",
|
||||
"php": ">=5.3.2",
|
||||
},
|
||||
"deps": Array [
|
||||
Object {
|
||||
"currentValue": ">=5.3.2",
|
||||
|
@ -216,10 +212,6 @@ Object {
|
|||
|
||||
exports[`manager/composer/extract extractPackageFile() extracts dependencies with no lock file 1`] = `
|
||||
Object {
|
||||
"constraints": Object {
|
||||
"composer": "^1.10.0",
|
||||
"php": ">=5.3.2",
|
||||
},
|
||||
"deps": Array [
|
||||
Object {
|
||||
"currentValue": ">=5.3.2",
|
||||
|
@ -427,10 +419,6 @@ Object {
|
|||
|
||||
exports[`manager/composer/extract extractPackageFile() extracts object registryUrls 1`] = `
|
||||
Object {
|
||||
"constraints": Object {
|
||||
"composer": "1.*",
|
||||
"php": ">=5.5",
|
||||
},
|
||||
"deps": Array [
|
||||
Object {
|
||||
"currentValue": ">=5.5",
|
||||
|
@ -532,9 +520,6 @@ Object {
|
|||
|
||||
exports[`manager/composer/extract extractPackageFile() extracts object repositories and registryUrls with lock file 1`] = `
|
||||
Object {
|
||||
"constraints": Object {
|
||||
"composer": "1.*",
|
||||
},
|
||||
"deps": Array [
|
||||
Object {
|
||||
"currentValue": "*",
|
||||
|
@ -572,9 +557,6 @@ Object {
|
|||
|
||||
exports[`manager/composer/extract extractPackageFile() extracts registryUrls 1`] = `
|
||||
Object {
|
||||
"constraints": Object {
|
||||
"composer": "^1.10.0",
|
||||
},
|
||||
"deps": Array [
|
||||
Object {
|
||||
"currentValue": "*",
|
||||
|
@ -617,9 +599,6 @@ Object {
|
|||
|
||||
exports[`manager/composer/extract extractPackageFile() extracts repositories and registryUrls 1`] = `
|
||||
Object {
|
||||
"constraints": Object {
|
||||
"composer": "1.*",
|
||||
},
|
||||
"deps": Array [
|
||||
Object {
|
||||
"currentValue": "*",
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import { exec as _exec } from 'child_process';
|
||||
import { join } from 'upath';
|
||||
import { envMock, mockExecAll } from '../../../test/exec-util';
|
||||
import { envMock, exec, mockExecAll } from '../../../test/exec-util';
|
||||
import { env, fs, git, mocked, partial } from '../../../test/util';
|
||||
import { setAdminConfig } from '../../config/admin';
|
||||
import type { RepoAdminConfig } from '../../config/types';
|
||||
|
@ -22,7 +21,6 @@ jest.mock('../../../lib/datasource');
|
|||
jest.mock('../../util/fs');
|
||||
jest.mock('../../util/git');
|
||||
|
||||
const exec: jest.Mock<typeof _exec> = _exec as any;
|
||||
const datasource = mocked(_datasource);
|
||||
|
||||
const config: UpdateArtifactsConfig = {
|
||||
|
@ -55,9 +53,11 @@ describe('.updateArtifacts()', () => {
|
|||
join(adminConfig.cacheDir, './others/composer')
|
||||
);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
setAdminConfig();
|
||||
});
|
||||
|
||||
it('returns if no composer.lock found', async () => {
|
||||
expect(
|
||||
await composer.updateArtifacts({
|
||||
|
@ -68,10 +68,11 @@ describe('.updateArtifacts()', () => {
|
|||
})
|
||||
).toBeNull();
|
||||
});
|
||||
|
||||
it('returns null if unchanged', async () => {
|
||||
fs.readLocalFile.mockResolvedValueOnce('Current composer.lock' as any);
|
||||
fs.readLocalFile.mockResolvedValueOnce('{}');
|
||||
const execSnapshots = mockExecAll(exec);
|
||||
fs.readLocalFile.mockReturnValueOnce('Current composer.lock' as any);
|
||||
fs.readLocalFile.mockResolvedValueOnce('{}');
|
||||
git.getRepoStatus.mockResolvedValue(repoStatus);
|
||||
setAdminConfig({ ...adminConfig, allowScripts: true });
|
||||
expect(
|
||||
|
@ -84,6 +85,7 @@ describe('.updateArtifacts()', () => {
|
|||
).toBeNull();
|
||||
expect(execSnapshots).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('uses hostRules to set COMPOSER_AUTH', async () => {
|
||||
hostRules.add({
|
||||
hostType: PLATFORM_TYPE_GITHUB,
|
||||
|
@ -112,9 +114,9 @@ describe('.updateArtifacts()', () => {
|
|||
username: 'some-other-username',
|
||||
password: 'some-other-password',
|
||||
});
|
||||
fs.readLocalFile.mockResolvedValueOnce('Current composer.lock' as any);
|
||||
fs.readLocalFile.mockResolvedValueOnce('{}');
|
||||
const execSnapshots = mockExecAll(exec);
|
||||
fs.readLocalFile.mockReturnValueOnce('Current composer.lock' as any);
|
||||
fs.readLocalFile.mockResolvedValueOnce('{}');
|
||||
const authConfig = {
|
||||
...config,
|
||||
registryUrls: ['https://packagist.renovatebot.com'],
|
||||
|
@ -130,10 +132,11 @@ describe('.updateArtifacts()', () => {
|
|||
).toBeNull();
|
||||
expect(execSnapshots).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('returns updated composer.lock', async () => {
|
||||
fs.readLocalFile.mockResolvedValueOnce('Current composer.lock' as any);
|
||||
fs.readLocalFile.mockResolvedValueOnce('{}');
|
||||
const execSnapshots = mockExecAll(exec);
|
||||
fs.readLocalFile.mockReturnValueOnce('New composer.lock' as any);
|
||||
fs.readLocalFile.mockResolvedValueOnce('{}');
|
||||
git.getRepoStatus.mockResolvedValue({
|
||||
...repoStatus,
|
||||
modified: ['composer.lock'],
|
||||
|
@ -148,12 +151,13 @@ describe('.updateArtifacts()', () => {
|
|||
).not.toBeNull();
|
||||
expect(execSnapshots).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('supports vendor directory update', async () => {
|
||||
const foo = join('vendor/foo/Foo.php');
|
||||
const bar = join('vendor/bar/Bar.php');
|
||||
const baz = join('vendor/baz/Baz.php');
|
||||
fs.localPathExists.mockResolvedValueOnce(true);
|
||||
fs.readLocalFile.mockResolvedValueOnce('Current composer.lock' as any);
|
||||
fs.readLocalFile.mockResolvedValueOnce('{}');
|
||||
const execSnapshots = mockExecAll(exec);
|
||||
git.getRepoStatus.mockResolvedValueOnce({
|
||||
...repoStatus,
|
||||
|
@ -161,10 +165,10 @@ describe('.updateArtifacts()', () => {
|
|||
not_added: [bar],
|
||||
deleted: [baz],
|
||||
});
|
||||
fs.readLocalFile.mockResolvedValueOnce('New composer.lock' as any);
|
||||
fs.readLocalFile.mockResolvedValueOnce('Foo' as any);
|
||||
fs.readLocalFile.mockResolvedValueOnce('Bar' as any);
|
||||
fs.getSiblingFileName.mockReturnValueOnce('vendor' as any);
|
||||
fs.readLocalFile.mockResolvedValueOnce('{ }');
|
||||
fs.readLocalFile.mockResolvedValueOnce('Foo');
|
||||
fs.readLocalFile.mockResolvedValueOnce('Bar');
|
||||
fs.getSiblingFileName.mockReturnValueOnce('vendor');
|
||||
const res = await composer.updateArtifacts({
|
||||
packageFileName: 'composer.json',
|
||||
updatedDeps: [],
|
||||
|
@ -173,17 +177,18 @@ describe('.updateArtifacts()', () => {
|
|||
});
|
||||
expect(res).not.toBeNull();
|
||||
expect(res?.map(({ file }) => file)).toEqual([
|
||||
{ contents: 'New composer.lock', name: 'composer.lock' },
|
||||
{ contents: '{ }', name: 'composer.lock' },
|
||||
{ contents: 'Foo', name: foo },
|
||||
{ contents: 'Bar', name: bar },
|
||||
{ contents: baz, name: '|delete|' },
|
||||
]);
|
||||
expect(execSnapshots).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('performs lockFileMaintenance', async () => {
|
||||
fs.readLocalFile.mockResolvedValueOnce('Current composer.lock' as any);
|
||||
fs.readLocalFile.mockResolvedValueOnce('{}');
|
||||
const execSnapshots = mockExecAll(exec);
|
||||
fs.readLocalFile.mockReturnValueOnce('New composer.lock' as any);
|
||||
fs.readLocalFile.mockResolvedValueOnce('{ }');
|
||||
git.getRepoStatus.mockResolvedValue({
|
||||
...repoStatus,
|
||||
modified: ['composer.lock'],
|
||||
|
@ -201,13 +206,14 @@ describe('.updateArtifacts()', () => {
|
|||
).not.toBeNull();
|
||||
expect(execSnapshots).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('supports docker mode', async () => {
|
||||
setAdminConfig({ ...adminConfig, binarySource: 'docker' });
|
||||
fs.readLocalFile.mockResolvedValueOnce('Current composer.lock' as any);
|
||||
fs.readLocalFile.mockResolvedValueOnce('{}');
|
||||
|
||||
const execSnapshots = mockExecAll(exec);
|
||||
|
||||
fs.readLocalFile.mockReturnValueOnce('New composer.lock' as any);
|
||||
fs.readLocalFile.mockResolvedValueOnce('{ }');
|
||||
datasource.getPkgReleases.mockResolvedValueOnce({
|
||||
releases: [
|
||||
{ version: '1.10.0' },
|
||||
|
@ -232,11 +238,12 @@ describe('.updateArtifacts()', () => {
|
|||
).not.toBeNull();
|
||||
expect(execSnapshots).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('supports global mode', async () => {
|
||||
setAdminConfig({ ...adminConfig, binarySource: 'global' });
|
||||
fs.readLocalFile.mockResolvedValueOnce('Current composer.lock' as any);
|
||||
fs.readLocalFile.mockResolvedValueOnce('{}');
|
||||
const execSnapshots = mockExecAll(exec);
|
||||
fs.readLocalFile.mockReturnValueOnce('New composer.lock' as any);
|
||||
fs.readLocalFile.mockResolvedValueOnce('{ }');
|
||||
git.getRepoStatus.mockResolvedValue({
|
||||
...repoStatus,
|
||||
modified: ['composer.lock'],
|
||||
|
@ -251,8 +258,9 @@ describe('.updateArtifacts()', () => {
|
|||
).not.toBeNull();
|
||||
expect(execSnapshots).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('catches errors', async () => {
|
||||
fs.readLocalFile.mockResolvedValueOnce('Current composer.lock' as any);
|
||||
fs.readLocalFile.mockResolvedValueOnce('{}');
|
||||
fs.writeLocalFile.mockImplementationOnce(() => {
|
||||
throw new Error('not found');
|
||||
});
|
||||
|
@ -265,8 +273,9 @@ describe('.updateArtifacts()', () => {
|
|||
})
|
||||
).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('catches unmet requirements errors', async () => {
|
||||
fs.readLocalFile.mockResolvedValueOnce('Current composer.lock' as any);
|
||||
fs.readLocalFile.mockResolvedValueOnce('{}');
|
||||
fs.writeLocalFile.mockImplementationOnce(() => {
|
||||
throw new Error(
|
||||
'fooYour requirements could not be resolved to an installable set of packages.bar'
|
||||
|
@ -281,8 +290,9 @@ describe('.updateArtifacts()', () => {
|
|||
})
|
||||
).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('throws for disk space', async () => {
|
||||
fs.readLocalFile.mockResolvedValueOnce('Current composer.lock' as any);
|
||||
fs.readLocalFile.mockResolvedValueOnce('{}');
|
||||
fs.writeLocalFile.mockImplementationOnce(() => {
|
||||
throw new Error(
|
||||
'vendor/composer/07fe2366/sebastianbergmann-php-code-coverage-c896779/src/Report/Html/Renderer/Template/js/d3.min.js: write error (disk full?). Continue? (y/n/^C) '
|
||||
|
@ -297,10 +307,11 @@ describe('.updateArtifacts()', () => {
|
|||
})
|
||||
).rejects.toThrow();
|
||||
});
|
||||
|
||||
it('disables ignorePlatformReqs', async () => {
|
||||
fs.readLocalFile.mockResolvedValueOnce('Current composer.lock' as any);
|
||||
fs.readLocalFile.mockResolvedValueOnce('{}');
|
||||
const execSnapshots = mockExecAll(exec);
|
||||
fs.readLocalFile.mockReturnValueOnce('New composer.lock' as any);
|
||||
fs.readLocalFile.mockResolvedValueOnce('{ }');
|
||||
git.getRepoStatus.mockResolvedValue({
|
||||
...repoStatus,
|
||||
modified: ['composer.lock'],
|
||||
|
|
|
@ -25,7 +25,11 @@ import { getRepoStatus } from '../../util/git';
|
|||
import * as hostRules from '../../util/host-rules';
|
||||
import type { UpdateArtifact, UpdateArtifactsResult } from '../types';
|
||||
import type { AuthJson } from './types';
|
||||
import { composerVersioningId, getConstraint } from './utils';
|
||||
import {
|
||||
composerVersioningId,
|
||||
extractContraints,
|
||||
getConstraint,
|
||||
} from './utils';
|
||||
|
||||
function getAuthJson(): string | null {
|
||||
const authJson: AuthJson = {};
|
||||
|
@ -82,7 +86,7 @@ export async function updateArtifacts({
|
|||
);
|
||||
|
||||
const lockFileName = packageFileName.replace(/\.json$/, '.lock');
|
||||
const existingLockFileContent = await readLocalFile(lockFileName);
|
||||
const existingLockFileContent = await readLocalFile(lockFileName, 'utf8');
|
||||
if (!existingLockFileContent) {
|
||||
logger.debug('No composer.lock found');
|
||||
return null;
|
||||
|
@ -93,6 +97,15 @@ export async function updateArtifacts({
|
|||
await ensureLocalDir(vendorDir);
|
||||
try {
|
||||
await writeLocalFile(packageFileName, newPackageFileContent);
|
||||
|
||||
const constraints = {
|
||||
...extractContraints(
|
||||
JSON.parse(newPackageFileContent),
|
||||
JSON.parse(existingLockFileContent)
|
||||
),
|
||||
...config.constraints,
|
||||
};
|
||||
|
||||
if (config.isLockFileMaintenance) {
|
||||
await deleteLocalFile(lockFileName);
|
||||
}
|
||||
|
@ -105,7 +118,7 @@ export async function updateArtifacts({
|
|||
},
|
||||
docker: {
|
||||
image: 'composer',
|
||||
tagConstraint: getConstraint(config),
|
||||
tagConstraint: getConstraint(constraints),
|
||||
tagScheme: composerVersioningId,
|
||||
},
|
||||
};
|
||||
|
|
|
@ -12,7 +12,6 @@ import type {
|
|||
ComposerManagerData,
|
||||
Repo,
|
||||
} from './types';
|
||||
import { extractContraints } from './utils';
|
||||
|
||||
/**
|
||||
* The regUrl is expected to be a base URL. GitLab composer repository installation guide specifies
|
||||
|
@ -116,8 +115,6 @@ export async function extractPackageFile(
|
|||
res.registryUrls = registryUrls;
|
||||
}
|
||||
|
||||
res.constraints = extractContraints(composerJson, lockParsed);
|
||||
|
||||
const deps = [];
|
||||
const depTypes = ['require', 'require-dev'];
|
||||
for (const depType of depTypes) {
|
||||
|
|
|
@ -4,9 +4,7 @@ import { extractContraints, getConstraint } from './utils';
|
|||
describe(getName(), () => {
|
||||
describe('getConstraint', () => {
|
||||
it('returns from config', () => {
|
||||
expect(getConstraint({ constraints: { composer: '1.1.0' } })).toEqual(
|
||||
'1.1.0'
|
||||
);
|
||||
expect(getConstraint({ composer: '1.1.0' })).toEqual('1.1.0');
|
||||
});
|
||||
|
||||
it('returns from null', () => {
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
import { logger } from '../../logger';
|
||||
import { api, id as composerVersioningId } from '../../versioning/composer';
|
||||
import type { UpdateArtifactsConfig } from '../types';
|
||||
import type { ComposerConfig, ComposerLock } from './types';
|
||||
|
||||
export { composerVersioningId };
|
||||
|
||||
export function getConstraint(config: UpdateArtifactsConfig): string {
|
||||
const { constraints = {} } = config;
|
||||
export function getConstraint(constraints: Record<string, string>): string {
|
||||
const { composer } = constraints;
|
||||
|
||||
if (composer) {
|
||||
|
|
Loading…
Reference in a new issue