diff --git a/lib/manager/resolve.js b/lib/manager/resolve.js index ee1ab6467841f6430e2d80aba83c3425f213c029..f38ad3fe9140eca4f3fa8884c9b7c14b5902613f 100644 --- a/lib/manager/resolve.js +++ b/lib/manager/resolve.js @@ -18,10 +18,8 @@ async function resolvePackageFiles(config) { ? config.packageFiles : await manager.detectPackageFiles(config); logger.debug({ allPackageFiles }, 'allPackageFiles'); - const packageFiles = []; - for (let packageFile of allPackageFiles) { - packageFile = - typeof packageFile === 'string' ? { packageFile } : packageFile; + async function resolvePackageFile(p) { + const packageFile = typeof p === 'string' ? { packageFile: p } : p; if (packageFile.packageFile.endsWith('package.json')) { logger.debug(`Resolving packageFile ${JSON.stringify(packageFile)}`); const pFileRaw = await platform.getFile(packageFile.packageFile); @@ -34,19 +32,20 @@ async function resolvePackageFiles(config) { depName: packageFile.packageFile, message: 'Cannot find package.json', }); - } else { - try { - packageFile.content = JSON.parse(pFileRaw); - } catch (err) { - logger.info( - { packageFile: packageFile.packageFile }, - 'Cannot parse package.json' - ); - config.warnings.push({ - depName: packageFile.packageFile, - message: 'Cannot parse package.json (invalid JSON)', - }); - } + return null; + } + try { + packageFile.content = JSON.parse(pFileRaw); + } catch (err) { + logger.info( + { packageFile: packageFile.packageFile }, + 'Cannot parse package.json' + ); + config.warnings.push({ + depName: packageFile.packageFile, + message: 'Cannot parse package.json (invalid JSON)', + }); + return null; } if (!config.ignoreNpmrcFile) { packageFile.npmrc = await platform.getFile( @@ -62,75 +61,73 @@ async function resolvePackageFiles(config) { if (!packageFile.yarnrc) { delete packageFile.yarnrc; } - if (packageFile.content) { - // hoist renovate config if exists - if (packageFile.content.renovate) { - logger.debug( - { - packageFile: packageFile.packageFile, - config: packageFile.content.renovate, - }, - `Found package.json renovate config` - ); - const migratedConfig = migrateAndValidate( - config, - packageFile.content.renovate - ); - logger.debug( - { config: migratedConfig }, - 'package.json migrated config' - ); - const resolvedConfig = await presets.resolveConfigPresets( - migratedConfig - ); - logger.debug( - { config: resolvedConfig }, - 'package.json resolved config' - ); - Object.assign(packageFile, resolvedConfig); - delete packageFile.content.renovate; - } else { - logger.debug( - { packageFile: packageFile.packageFile }, - `No renovate config` - ); - } - // Detect if lock files are used - const yarnLockFileName = path.join( - path.dirname(packageFile.packageFile), - 'yarn.lock' + // hoist renovate config if exists + if (packageFile.content.renovate) { + logger.debug( + { + packageFile: packageFile.packageFile, + config: packageFile.content.renovate, + }, + `Found package.json renovate config` + ); + const migratedConfig = migrateAndValidate( + config, + packageFile.content.renovate + ); + logger.debug( + { config: migratedConfig }, + 'package.json migrated config' ); - packageFile.yarnLock = await platform.getFile(yarnLockFileName); - if (packageFile.yarnLock) { - logger.debug( - { packageFile: packageFile.packageFile }, - 'Found yarn.lock' - ); - } - const packageLockFileName = path.join( - path.dirname(packageFile.packageFile), - 'package-lock.json' + const resolvedConfig = await presets.resolveConfigPresets( + migratedConfig ); - packageFile.packageLock = await platform.getFile(packageLockFileName); - if (packageFile.packageLock) { - logger.debug( - { packageFile: packageFile.packageFile }, - 'Found package-lock.json' - ); - } + logger.debug( + { config: resolvedConfig }, + 'package.json resolved config' + ); + Object.assign(packageFile, resolvedConfig); + delete packageFile.content.renovate; } else { - continue; // eslint-disable-line + logger.debug( + { packageFile: packageFile.packageFile }, + `No renovate config` + ); + } + // Detect if lock files are used + const yarnLockFileName = path.join( + path.dirname(packageFile.packageFile), + 'yarn.lock' + ); + packageFile.yarnLock = await platform.getFile(yarnLockFileName); + if (packageFile.yarnLock) { + logger.debug( + { packageFile: packageFile.packageFile }, + 'Found yarn.lock' + ); } + const packageLockFileName = path.join( + path.dirname(packageFile.packageFile), + 'package-lock.json' + ); + packageFile.packageLock = await platform.getFile(packageLockFileName); + if (packageFile.packageLock) { + logger.debug( + { packageFile: packageFile.packageFile }, + 'Found package-lock.json' + ); + } + return packageFile; } else if (packageFile.packageFile.endsWith('package.js')) { // meteor - packageFile = mergeChildConfig(config.meteor, packageFile); + return mergeChildConfig(config.meteor, packageFile); } else if (packageFile.packageFile.endsWith('Dockerfile')) { logger.debug('Resolving Dockerfile'); - packageFile = await dockerResolve.resolvePackageFile(config, packageFile); - } - if (packageFile) { - packageFiles.push(packageFile); + return dockerResolve.resolvePackageFile(config, packageFile); } + return null; } + logger.debug('queue'); + const queue = allPackageFiles.map(p => resolvePackageFile(p)); + const packageFiles = (await Promise.all(queue)).filter(p => p !== null); return checkMonorepos({ ...config, packageFiles }); } diff --git a/test/manager/__snapshots__/resolve.spec.js.snap b/test/manager/__snapshots__/resolve.spec.js.snap index 876e0c8a1fb136b451d549079a24253ba7846864..f7f41cdcf362f60e541c738e2e986a1846ccc73a 100644 --- a/test/manager/__snapshots__/resolve.spec.js.snap +++ b/test/manager/__snapshots__/resolve.spec.js.snap @@ -2181,6 +2181,490 @@ This PR has been generated by [Renovate Bot](https://renovateapp.com).", } `; +exports[`manager/resolve resolvePackageFiles() handles wrong filenames 1`] = ` +Object { + "assignees": Array [], + "autodiscover": false, + "automerge": false, + "automergeType": "pr", + "baseBranch": null, + "branchName": "{{branchPrefix}}{{depNameSanitized}}-{{newVersionMajor}}.x", + "branchPrefix": "renovate/", + "commitMessage": "Update dependency {{depName}} to v{{newVersion}}", + "dependencies": Object { + "semanticPrefix": "fix(deps):", + }, + "description": Array [], + "devDependencies": Object { + "pin": Object { + "group": Object { + "commitMessage": "Pin devDependencies", + "prTitle": "Pin devDependencies", + }, + }, + }, + "digest": Object { + "semanticPrefix": "refactor(deps):", + }, + "docker": Object { + "branchName": "{{branchPrefix}}docker-{{depNameSanitized}}-{{newVersionMajor}}.x", + "commitMessage": "Update {{depName}} to tag {{newTag}}", + "digest": Object { + "branchName": "{{branchPrefix}}docker-{{depNameSanitized}}-{{currentTag}}", + "commitMessage": "Update {{depName}}:{{currentTag}} digest", + "prBody": "This Pull Request updates Docker base image \`{{depName}}:{{currentTag}}\` to the latest digest (\`{{newDigest}}\`). For details on Renovate's Docker support, please visit https://renovateapp.com/docs/language-support/docker + +{{#if schedule}} +**Note**: This PR was created on a configured schedule (\\"{{schedule}}\\"{{#if timezone}} in timezone \`{{timezone}}\`{{/if}}) and will not receive updates outside those times. +{{/if}} + +{{#if hasErrors}} + +--- + +### Errors + +Renovate encountered some errors when processing your repository, so you are being notified here even if they do not directly apply to this PR. + +{{#each errors as |error|}} +- \`{{error.depName}}\`: {{error.message}} +{{/each}} +{{/if}} + +{{#if hasWarnings}} + +--- + +### Warnings + +Please make sure the following warnings are safe to ignore: + +{{#each warnings as |warning|}} +- \`{{warning.depName}}\`: {{warning.message}} +{{/each}} +{{/if}} + +--- + +This PR has been generated by [Renovate Bot](https://renovateapp.com).", + "prTitle": "Update Dockerfile {{depName}} image {{currentTag}} digest ({{newDigestShort}})", + }, + "enabled": true, + "group": Object { + "prBody": "This Pull Request updates Dockerfiles to use image digests. + +{{#if schedule}} +**Note**: This PR was created on a configured schedule (\\"{{schedule}}\\"{{#if timezone}} in timezone \`{{timezone}}\`{{/if}}) and will not receive updates outside those times. +{{/if}} + +{{#each upgrades as |upgrade|}} +- {{#if repositoryUrl}}[{{upgrade.depName}}]({{upgrade.repositoryUrl}}){{else}}\`{{depName}}\`{{/if}}: \`{{upgrade.newDigest}}\` +{{/each}} + +{{#if hasErrors}} + +--- + +### Errors + +Renovate encountered some errors when processing your repository, so you are being notified here even if they do not directly apply to this PR. + +{{#each errors as |error|}} +- \`{{error.depName}}\`: {{error.message}} +{{/each}} +{{/if}} + +{{#if hasWarnings}} + +--- + +### Warnings + +Please make sure the following warnings are safe to ignore: + +{{#each warnings as |warning|}} +- \`{{warning.depName}}\`: {{warning.message}} +{{/each}} +{{/if}} + +--- + +This PR has been generated by [Renovate Bot](https://renovateapp.com).", + "prTitle": "Update Docker {{groupName}} digests", + }, + "major": Object { + "enabled": false, + }, + "pin": Object { + "branchName": "{{branchPrefix}}docker-pin-{{depNameSanitized}}-{{currentTag}}", + "group": Object { + "prBody": "This Pull Request pins Dockerfiles to use image digests. For details on Renovate's Docker support, please visit https://renovateapp.com/docs/language-support/docker + +{{#if schedule}} +**Note**: This PR was created on a configured schedule (\\"{{schedule}}\\"{{#if timezone}} in timezone \`{{timezone}}\`{{/if}}) and will not receive updates outside those times. +{{/if}} + +{{#each upgrades as |upgrade|}} +- {{#if repositoryUrl}}[{{upgrade.depName}}]({{upgrade.repositoryUrl}}){{else}}\`{{depName}}\`{{/if}}: \`{{upgrade.newDigest}}\` +{{/each}} + +{{#if hasErrors}} + +--- + +### Errors + +Renovate encountered some errors when processing your repository, so you are being notified here even if they do not directly apply to this PR. + +{{#each errors as |error|}} +- \`{{error.depName}}\`: {{error.message}} +{{/each}} +{{/if}} + +{{#if hasWarnings}} + +--- + +### Warnings + +Please make sure the following warnings are safe to ignore: + +{{#each warnings as |warning|}} +- \`{{warning.depName}}\`: {{warning.message}} +{{/each}} +{{/if}} + +--- + +This PR has been generated by [Renovate Bot](https://renovateapp.com).", + "prTitle": "Pin Docker digests", + }, + "groupName": "Pin Docker Digests", + "prBody": "This Pull Request pins Docker base image \`{{depName}}:{{currentTag}}\` to use a digest (\`{{newDigest}}\`). +This digest will then be kept updated via Pull Requests whenever the image is updated on the Docker registry. For details on Renovate's Docker support, please visit https://renovateapp.com/docs/language-support/docker + +{{#if schedule}} +**Note**: This PR was created on a configured schedule (\\"{{schedule}}\\"{{#if timezone}} in timezone \`{{timezone}}\`{{/if}}) and will not receive updates outside those times. +{{/if}} + +{{#if hasErrors}} + +--- + +### Errors + +Renovate encountered some errors when processing your repository, so you are being notified here even if they do not directly apply to this PR. + +{{#each errors as |error|}} +- \`{{error.depName}}\`: {{error.message}} +{{/each}} +{{/if}} + +{{#if hasWarnings}} + +--- + +### Warnings + +Please make sure the following warnings are safe to ignore: + +{{#each warnings as |warning|}} +- \`{{warning.depName}}\`: {{warning.message}} +{{/each}} +{{/if}} + +--- + +This PR has been generated by [Renovate Bot](https://renovateapp.com).", + "prTitle": "Pin Dockerfile {{depName}}:{{currentTag}} image digest", + }, + "prBody": "This Pull Request updates Docker base image \`{{depName}}\` from tag \`{{currentTag}}\` to new tag \`{{newTag}}\`. For details on Renovate's Docker support, please visit https://renovateapp.com/docs/language-support/docker + +{{#if schedule}} +**Note**: This PR was created on a configured schedule (\\"{{schedule}}\\"{{#if timezone}} in timezone \`{{timezone}}\`{{/if}}) and will not receive updates outside those times. +{{/if}} + +{{#if hasErrors}} + +--- + +### Errors + +Renovate encountered some errors when processing your repository, so you are being notified here even if they do not directly apply to this PR. + +{{#each errors as |error|}} +- \`{{error.depName}}\`: {{error.message}} +{{/each}} +{{/if}} + +{{#if hasWarnings}} + +--- + +### Warnings + +Please make sure the following warnings are safe to ignore: + +{{#each warnings as |warning|}} +- \`{{warning.depName}}\`: {{warning.message}} +{{/each}} +{{/if}} + +--- + +This PR has been generated by [Renovate Bot](https://renovateapp.com).", + "prTitle": "Update {{depName}} Dockerfile tag to {{#if isMajor}}v{{newVersionMajor}}{{else}}v{{newTag}}{{/if}}", + }, + "enabled": true, + "encrypted": null, + "endpoint": null, + "errors": Array [], + "excludePackageNames": Array [], + "excludePackagePatterns": Array [], + "extends": Array [], + "group": Object { + "branchName": "{{branchPrefix}}{{groupSlug}}", + "commitMessage": "Renovate {{groupName}} packages", + "prBody": "This Pull Request renovates the package group \\"{{groupName}}\\". + +{{#if schedule}} +**Note**: This PR was created on a configured schedule (\\"{{schedule}}\\"{{#if timezone}} in timezone \`{{timezone}}\`{{/if}}) and will not receive updates outside those times. +{{/if}} + +{{#each upgrades as |upgrade|}} +- {{#if repositoryUrl}}[{{upgrade.depName}}]({{upgrade.repositoryUrl}}){{else}}\`{{depName}}\`{{/if}}: from \`{{upgrade.currentVersion}}\` to \`{{upgrade.newVersion}}\` +{{/each}} + +{{#unless isPin}} +### Commits + +{{#each upgrades as |upgrade|}} +{{#if upgrade.releases.length}} +<details> +<summary>{{upgrade.githubName}}</summary> +{{#each upgrade.releases as |release|}} + +#### {{release.version}} +{{#each release.commits as |commit|}} +- [\`{{commit.shortSha}}\`]({{commit.url}}){{commit.message}} +{{/each}} +{{/each}} + +</details> +{{/if}} +{{/each}} +{{/unless}} +<br /> + +{{#if hasErrors}} + +--- + +### Errors + +Renovate encountered some errors when processing your repository, so you are being notified here even if they do not directly apply to this PR. + +{{#each errors as |error|}} +- \`{{error.depName}}\`: {{error.message}} +{{/each}} +{{/if}} + +{{#if hasWarnings}} + +--- + +### Warnings + +Please make sure the following warnings are safe to ignore: + +{{#each warnings as |warning|}} +- \`{{warning.depName}}\`: {{warning.message}} +{{/each}} +{{/if}} + +--- + +This PR has been generated by [Renovate Bot](https://renovateapp.com).", + "prTitle": "Renovate {{groupName}} packages", + "recreateClosed": true, + }, + "groupName": null, + "groupSlug": null, + "ignoreDeps": Array [], + "ignoreFuture": true, + "ignoreNpmrcFile": false, + "ignorePaths": Array [ + "**/node_modules/**", + ], + "ignoreUnstable": true, + "labels": Array [], + "lazyGrouping": true, + "lockFileMaintenance": Object { + "branchName": "{{branchPrefix}}lock-file-maintenance", + "commitMessage": "Update lock file", + "enabled": false, + "groupName": null, + "prBody": "This Pull Request updates \`package.json\` lock files to use the latest dependency versions. + +{{#if schedule}} +**Note**: This PR was created on a configured schedule (\\"{{schedule}}\\"{{#if timezone}} in timezone \`{{timezone}}\`{{/if}}) and will not receive updates outside those times. +{{/if}} + +{{#if hasErrors}} + +--- + +### Errors + +Renovate encountered some errors when processing your repository, so you are being notified here even if they do not directly apply to this PR. + +{{#each errors as |error|}} +- \`{{error.depName}}\`: {{error.message}} +{{/each}} +{{/if}} + +{{#if hasWarnings}} + +--- + +### Warnings + +Please make sure the following warnings are safe to ignore: + +{{#each warnings as |warning|}} +- \`{{warning.depName}}\`: {{warning.message}} +{{/each}} +{{/if}} + +--- + +This PR has been generated by [Renovate Bot](https://renovateapp.com).", + "prTitle": "Lock file maintenance", + "recreateClosed": true, + "schedule": Array [ + "before 5am on monday", + ], + }, + "logFile": null, + "logFileLevel": "debug", + "logLevel": "info", + "major": Object {}, + "meteor": Object { + "enabled": true, + }, + "minor": Object {}, + "monorepoPackages": Array [], + "multipleMajorPrs": false, + "npm": Object { + "enabled": true, + "pin": Object { + "automerge": true, + }, + }, + "npmrc": null, + "onboarding": true, + "optionalDependencies": Object {}, + "packageFiles": Array [], + "packageNames": Array [], + "packagePatterns": Array [], + "packageRules": Array [], + "patch": Object { + "branchName": "{{branchPrefix}}{{depNameSanitized}}-{{newVersionMajor}}.{{newVersionMinor}}.x", + }, + "peerDependencies": Object { + "enabled": false, + }, + "pin": Object { + "group": Object { + "commitMessage": "Pin Dependencies", + "prTitle": "{{groupName}}", + "semanticPrefix": "refactor(deps):", + }, + "groupName": "Pin Dependencies", + "rebaseStalePrs": true, + "recreateClosed": true, + "unpublishSafe": false, + }, + "pinDigests": true, + "pinVersions": null, + "platform": "github", + "prBody": "This Pull Request {{#if isRollback}}rolls back{{else}}updates{{/if}} dependency {{#if repositoryUrl}}[{{depName}}]({{repositoryUrl}}){{else}}\`{{depName}}\`{{/if}} from \`{{#unless isRange}}{{#unless isPin}}v{{/unless}}{{/unless}}{{currentVersion}}\` to \`{{#unless isRange}}v{{/unless}}{{newVersion}}\`{{#if isRollback}}. This is necessary and important because \`v{{currentVersion}}\` cannot be found in the npm registry - probably because of it being unpublished.{{/if}} +{{#if releases.length}} + +{{#if schedule}} +**Note**: This PR was created on a configured schedule (\\"{{schedule}}\\"{{#if timezone}} in timezone \`{{timezone}}\`{{/if}}) and will not receive updates outside those times. +{{/if}} + +### Commits + +<details> +<summary>{{githubName}}</summary> + +{{#each releases as |release|}} +#### {{release.version}} +{{#each release.commits as |commit|}} +- [\`{{commit.shortSha}}\`]({{commit.url}}) {{commit.message}} +{{/each}} +{{/each}} + +</details> +{{/if}} + +{{#if hasErrors}} + +--- + +### Errors + +Renovate encountered some errors when processing your repository, so you are being notified here even if they do not directly apply to this PR. + +{{#each errors as |error|}} +- \`{{error.depName}}\`: {{error.message}} +{{/each}} +{{/if}} + +{{#if hasWarnings}} + +--- + +### Warnings + +Please make sure the following warnings are safe to ignore: + +{{#each warnings as |warning|}} +- \`{{warning.depName}}\`: {{warning.message}} +{{/each}} +{{/if}} + +--- + +This PR has been generated by [Renovate Bot](https://renovateapp.com).", + "prCreation": "immediate", + "prNotPendingHours": 12, + "prTitle": "{{#if isPin}}Pin{{else}}{{#if isRollback}}Roll back{{else}}Update{{/if}}{{/if}} dependency {{depName}} to {{#if isRange}}{{newVersion}}{{else}}{{#if isMajor}}v{{newVersionMajor}}{{else}}v{{newVersion}}{{/if}}{{/if}}", + "privateKey": null, + "rebaseStalePrs": false, + "recreateClosed": false, + "renovateFork": false, + "repositories": Array [], + "requiredStatusChecks": Array [], + "respectLatest": true, + "reviewers": Array [], + "schedule": Array [], + "semanticCommits": null, + "semanticPrefix": "chore(deps):", + "separateMajorReleases": true, + "separatePatchReleases": false, + "timezone": null, + "token": null, + "unpublishSafe": false, + "unstablePattern": null, + "updateNotScheduled": true, + "warnings": Array [], + "yarnrc": null, +} +`; + exports[`manager/resolve resolvePackageFiles() skips docker if no content or no match 1`] = ` Object { "assignees": Array [], diff --git a/test/manager/resolve.spec.js b/test/manager/resolve.spec.js index 7b959f5158962e8dfd786dc061a7ef3faaa84847..3e6096310ddde23edcee3cb5c3b90624c925fb76 100644 --- a/test/manager/resolve.spec.js +++ b/test/manager/resolve.spec.js @@ -11,6 +11,11 @@ beforeEach(() => { describe('manager/resolve', () => { describe('resolvePackageFiles()', () => { + it('handles wrong filenames', async () => { + config.packageFiles = ['wrong.txt']; + const res = await resolvePackageFiles(config); + expect(res).toMatchSnapshot(); + }); it('uses packageFiles if already configured and raises error if not found', async () => { config.packageFiles = [ 'package.json',