From 91d2b4e1c54af6a99f09d6e7c9cd476e4ee524f4 Mon Sep 17 00:00:00 2001 From: Michael Kriese <michael.kriese@visualon.de> Date: Tue, 2 Mar 2021 16:57:02 +0100 Subject: [PATCH] feat: static modules (#8679) Co-authored-by: Rhys Arkins <rhys@arkins.net> --- lib/datasource/api.ts | 69 ++++++++++ lib/datasource/index.spec.ts | 10 +- lib/datasource/index.ts | 2 +- lib/manager/api.ts | 123 ++++++++++++++++++ lib/manager/index.spec.ts | 5 +- lib/manager/index.ts | 2 +- lib/platform/__snapshots__/index.spec.ts.snap | 10 +- lib/platform/api.ts | 17 +++ lib/platform/index.spec.ts | 6 +- lib/platform/index.ts | 2 +- lib/versioning/api.ts | 45 +++++++ lib/versioning/index.ts | 2 +- tools/generate-imports.ts | 69 ---------- 13 files changed, 273 insertions(+), 89 deletions(-) create mode 100644 lib/datasource/api.ts create mode 100644 lib/manager/api.ts create mode 100644 lib/platform/api.ts create mode 100644 lib/versioning/api.ts diff --git a/lib/datasource/api.ts b/lib/datasource/api.ts new file mode 100644 index 0000000000..af2186b39a --- /dev/null +++ b/lib/datasource/api.ts @@ -0,0 +1,69 @@ +import * as bitbucketTags from './bitbucket-tags'; +import * as cdnjs from './cdnjs'; +import * as clojure from './clojure'; +import type { DatasourceApi } from './common'; +import * as crate from './crate'; +import * as dart from './dart'; +import * as docker from './docker'; +import * as galaxy from './galaxy'; +import * as gitRefs from './git-refs'; +import * as gitSubmodules from './git-submodules'; +import * as gitTags from './git-tags'; +import * as githubReleases from './github-releases'; +import * as githubTags from './github-tags'; +import * as gitlabTags from './gitlab-tags'; +import * as go from './go'; +import * as gradleVersion from './gradle-version'; +import * as helm from './helm'; +import * as hex from './hex'; +import * as jenkinsPlugins from './jenkins-plugins'; +import * as maven from './maven'; +import * as npm from './npm'; +import * as nuget from './nuget'; +import * as orb from './orb'; +import * as packagist from './packagist'; +import * as pod from './pod'; +import * as pypi from './pypi'; +import * as repology from './repology'; +import * as rubyVersion from './ruby-version'; +import * as rubygems from './rubygems'; +import * as sbtPackage from './sbt-package'; +import * as sbtPlugin from './sbt-plugin'; +import * as terraformModule from './terraform-module'; +import * as terraformProvider from './terraform-provider'; + +const api = new Map<string, DatasourceApi>(); +export default api; + +api.set('bitbucket-tags', bitbucketTags); +api.set('cdnjs', cdnjs); +api.set('clojure', clojure); +api.set('crate', crate); +api.set('dart', dart); +api.set('docker', docker); +api.set('galaxy', galaxy); +api.set('git-refs', gitRefs); +api.set('git-submodules', gitSubmodules); +api.set('git-tags', gitTags); +api.set('github-releases', githubReleases); +api.set('github-tags', githubTags); +api.set('gitlab-tags', gitlabTags); +api.set('go', go); +api.set('gradle-version', gradleVersion); +api.set('helm', helm); +api.set('hex', hex); +api.set('jenkins-plugins', jenkinsPlugins); +api.set('maven', maven); +api.set('npm', npm); +api.set('nuget', nuget); +api.set('orb', orb); +api.set('packagist', packagist); +api.set('pod', pod); +api.set('pypi', pypi); +api.set('repology', repology); +api.set('ruby-version', rubyVersion); +api.set('rubygems', rubygems); +api.set('sbt-package', sbtPackage); +api.set('sbt-plugin', sbtPlugin); +api.set('terraform-module', terraformModule); +api.set('terraform-provider', terraformProvider); diff --git a/lib/datasource/index.spec.ts b/lib/datasource/index.spec.ts index ee1ec40b11..2d37ae1366 100644 --- a/lib/datasource/index.spec.ts +++ b/lib/datasource/index.spec.ts @@ -1,10 +1,11 @@ -import { mocked } from '../../test/util'; +import { getName, mocked } from '../../test/util'; import { EXTERNAL_HOST_ERROR, HOST_DISABLED, } from '../constants/error-messages'; import { ExternalHostError } from '../types/errors/external-host-error'; import { loadModules } from '../util/modules'; +import type { Datasource } from './common'; import * as datasourceDocker from './docker'; import * as datasourceGithubTags from './github-tags'; import * as datasourceMaven from './maven'; @@ -22,7 +23,7 @@ const mavenDatasource = mocked(datasourceMaven); const npmDatasource = mocked(datasourceNpm); const packagistDatasource = mocked(datasourcePackagist); -describe('datasource/index', () => { +describe(getName(__filename), () => { beforeEach(() => { jest.resetAllMocks(); }); @@ -31,10 +32,7 @@ describe('datasource/index', () => { expect(datasource.getDatasourceList()).toBeDefined(); }); it('validates dataource', () => { - function validateDatasource( - module: datasource.Datasource, - name: string - ): boolean { + function validateDatasource(module: Datasource, name: string): boolean { if (!module.getReleases) { return false; } diff --git a/lib/datasource/index.ts b/lib/datasource/index.ts index d907fb674c..94f99bf850 100644 --- a/lib/datasource/index.ts +++ b/lib/datasource/index.ts @@ -8,7 +8,7 @@ import * as packageCache from '../util/cache/package'; import { clone } from '../util/clone'; import { regEx } from '../util/regex'; import * as allVersioning from '../versioning'; -import datasources from './api.generated'; +import datasources from './api'; import { Datasource, DigestConfig, diff --git a/lib/manager/api.ts b/lib/manager/api.ts new file mode 100644 index 0000000000..8bf6ba4e13 --- /dev/null +++ b/lib/manager/api.ts @@ -0,0 +1,123 @@ +import * as ansible from './ansible'; +import * as ansibleGalaxy from './ansible-galaxy'; +import * as azurePipelines from './azure-pipelines'; +import * as batect from './batect'; +import * as batectWrapper from './batect-wrapper'; +import * as bazel from './bazel'; +import * as buildkite from './buildkite'; +import * as bundler from './bundler'; +import * as cargo from './cargo'; +import * as cdnurl from './cdnurl'; +import * as circleci from './circleci'; +import * as cloudbuild from './cloudbuild'; +import * as cocoapods from './cocoapods'; +import type { ManagerApi } from './common'; +import * as composer from './composer'; +import * as depsEdn from './deps-edn'; +import * as dockerCompose from './docker-compose'; +import * as dockerfile from './dockerfile'; +import * as droneci from './droneci'; +import * as gitSubmodules from './git-submodules'; +import * as githubActions from './github-actions'; +import * as gitlabci from './gitlabci'; +import * as gitlabciInclude from './gitlabci-include'; +import * as gomod from './gomod'; +import * as gradle from './gradle'; +import * as gradleLite from './gradle-lite'; +import * as gradleWrapper from './gradle-wrapper'; +import * as helmRequirements from './helm-requirements'; +import * as helmValues from './helm-values'; +import * as helmfile from './helmfile'; +import * as helmv3 from './helmv3'; +import * as homebrew from './homebrew'; +import * as html from './html'; +import * as jenkins from './jenkins'; +import * as kubernetes from './kubernetes'; +import * as kustomize from './kustomize'; +import * as leiningen from './leiningen'; +import * as maven from './maven'; +import * as meteor from './meteor'; +import * as mix from './mix'; +import * as nodenv from './nodenv'; +import * as npm from './npm'; +import * as nuget from './nuget'; +import * as nvm from './nvm'; +import * as pip_requirements from './pip_requirements'; +import * as pip_setup from './pip_setup'; +import * as pipenv from './pipenv'; +import * as poetry from './poetry'; +import * as preCommit from './pre-commit'; +import * as pub from './pub'; +import * as regex from './regex'; +import * as rubyVersion from './ruby-version'; +import * as sbt from './sbt'; +import * as setupCfg from './setup-cfg'; +import * as swift from './swift'; +import * as terraform from './terraform'; +import * as terraformVersion from './terraform-version'; +import * as terragrunt from './terragrunt'; +import * as terragruntVersion from './terragrunt-version'; +import * as travis from './travis'; + +const api = new Map<string, ManagerApi>(); +export default api; + +api.set('ansible', ansible); +api.set('ansible-galaxy', ansibleGalaxy); +api.set('azure-pipelines', azurePipelines); +api.set('batect', batect); +api.set('batect-wrapper', batectWrapper); +api.set('bazel', bazel); +api.set('buildkite', buildkite); +api.set('bundler', bundler); +api.set('cargo', cargo); +api.set('cdnurl', cdnurl); +api.set('circleci', circleci); +api.set('cloudbuild', cloudbuild); +api.set('cocoapods', cocoapods); +api.set('composer', composer); +api.set('deps-edn', depsEdn); +api.set('docker-compose', dockerCompose); +api.set('dockerfile', dockerfile); +api.set('droneci', droneci); +api.set('git-submodules', gitSubmodules); +api.set('github-actions', githubActions); +api.set('gitlabci', gitlabci); +api.set('gitlabci-include', gitlabciInclude); +api.set('gomod', gomod); +api.set('gradle', gradle); +api.set('gradle-lite', gradleLite); +api.set('gradle-wrapper', gradleWrapper); +api.set('helm-requirements', helmRequirements); +api.set('helm-values', helmValues); +api.set('helmfile', helmfile); +api.set('helmv3', helmv3); +api.set('homebrew', homebrew); +api.set('html', html); +api.set('jenkins', jenkins); +api.set('kubernetes', kubernetes); +api.set('kustomize', kustomize); +api.set('leiningen', leiningen); +api.set('maven', maven); +api.set('meteor', meteor); +api.set('mix', mix); +api.set('nodenv', nodenv); +api.set('npm', npm); +api.set('nuget', nuget); +api.set('nvm', nvm); +api.set('pip_requirements', pip_requirements); +api.set('pip_setup', pip_setup); +api.set('pipenv', pipenv); +api.set('poetry', poetry); +api.set('pre-commit', preCommit); +api.set('pub', pub); +api.set('regex', regex); +api.set('ruby-version', rubyVersion); +api.set('sbt', sbt); +api.set('setup-cfg', setupCfg); +api.set('swift', swift); +api.set('terraform', terraform); +api.set('terraform-version', terraformVersion); +api.set('terragrunt', terragrunt); +api.set('terragrunt-version', terragruntVersion); +api.set('travis', travis); diff --git a/lib/manager/index.spec.ts b/lib/manager/index.spec.ts index 2ba4d073b6..5b213c181a 100644 --- a/lib/manager/index.spec.ts +++ b/lib/manager/index.spec.ts @@ -1,8 +1,9 @@ +import { getName } from '../../test/util'; import { loadModules } from '../util/modules'; -import { ManagerApi } from './common'; +import type { ManagerApi } from './common'; import * as manager from '.'; -describe('manager', () => { +describe(getName(__filename), () => { describe('get()', () => { it('gets something', () => { expect(manager.get('dockerfile', 'extractPackageFile')).not.toBeNull(); diff --git a/lib/manager/index.ts b/lib/manager/index.ts index dd8d987b5d..48f5c8e903 100644 --- a/lib/manager/index.ts +++ b/lib/manager/index.ts @@ -12,7 +12,7 @@ import { LANGUAGE_RUST, } from '../constants/languages'; import { RangeStrategy } from '../types'; -import managers from './api.generated'; +import managers from './api'; import { ExtractConfig, LookupUpdate, diff --git a/lib/platform/__snapshots__/index.spec.ts.snap b/lib/platform/__snapshots__/index.spec.ts.snap index c6720de416..3f2dbd6f9e 100644 --- a/lib/platform/__snapshots__/index.spec.ts.snap +++ b/lib/platform/__snapshots__/index.spec.ts.snap @@ -1,8 +1,8 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`platform escapes names 1`] = `"name [what]"`; +exports[`platform/index escapes names 1`] = `"name [what]"`; -exports[`platform initializes 1`] = ` +exports[`platform/index initializes 1`] = ` Object { "endpoint": "https://api.bitbucket.org/", "gitAuthor": "user@domain.com", @@ -18,7 +18,7 @@ Object { } `; -exports[`platform initializes no author 1`] = ` +exports[`platform/index initializes no author 1`] = ` Object { "endpoint": "https://api.bitbucket.org/", "hostRules": Array [ @@ -33,14 +33,14 @@ Object { } `; -exports[`platform parses bot email 1`] = ` +exports[`platform/index parses bot email 1`] = ` Object { "address": "some[bot]@users.noreply.github.com", "name": "some[bot]", } `; -exports[`platform parses bot name and email 1`] = ` +exports[`platform/index parses bot name and email 1`] = ` Object { "address": "some[bot]@users.noreply.github.com", "name": "some[bot]", diff --git a/lib/platform/api.ts b/lib/platform/api.ts new file mode 100644 index 0000000000..7be6d66a58 --- /dev/null +++ b/lib/platform/api.ts @@ -0,0 +1,17 @@ +import * as azure from './azure'; +import * as bitbucket from './bitbucket'; +import * as bitbucketServer from './bitbucket-server'; +import type { Platform } from './common'; +import * as gitea from './gitea'; +import * as github from './github'; +import * as gitlab from './gitlab'; + +const api = new Map<string, Platform>(); +export default api; + +api.set('azure', azure); +api.set('bitbucket', bitbucket); +api.set('bitbucket-server', bitbucketServer); +api.set('gitea', gitea); +api.set('github', github); +api.set('gitlab', gitlab); diff --git a/lib/platform/index.spec.ts b/lib/platform/index.spec.ts index 6669e8f732..480976cf38 100644 --- a/lib/platform/index.spec.ts +++ b/lib/platform/index.spec.ts @@ -1,13 +1,13 @@ +import { getName } from '../../test/util'; import { PLATFORM_NOT_FOUND } from '../constants/error-messages'; import { PLATFORM_TYPE_BITBUCKET } from '../constants/platforms'; import { loadModules } from '../util/modules'; - +import type { Platform } from './common'; import * as platform from '.'; -import { Platform } from '.'; jest.unmock('.'); -describe('platform', () => { +describe(getName(__filename), () => { beforeEach(() => { jest.resetModules(); }); diff --git a/lib/platform/index.ts b/lib/platform/index.ts index 3cc642d8f3..67df26ecd8 100644 --- a/lib/platform/index.ts +++ b/lib/platform/index.ts @@ -5,7 +5,7 @@ import { PLATFORM_NOT_FOUND } from '../constants/error-messages'; import { logger } from '../logger'; import { setPrivateKey } from '../util/git'; import * as hostRules from '../util/host-rules'; -import platforms from './api.generated'; +import platforms from './api'; import { Platform } from './common'; export * from './common'; diff --git a/lib/versioning/api.ts b/lib/versioning/api.ts new file mode 100644 index 0000000000..c5163d3c8c --- /dev/null +++ b/lib/versioning/api.ts @@ -0,0 +1,45 @@ +import * as cargo from './cargo'; +import type { VersioningApi, VersioningApiConstructor } from './common'; +import * as composer from './composer'; +import * as docker from './docker'; +import * as git from './git'; +import * as gradle from './gradle'; +import * as hashicorp from './hashicorp'; +import * as hex from './hex'; +import * as ivy from './ivy'; +import * as loose from './loose'; +import * as maven from './maven'; +import * as node from './node'; +import * as npm from './npm'; +import * as nuget from './nuget'; +import * as pep440 from './pep440'; +import * as poetry from './poetry'; +import * as regex from './regex'; +import * as ruby from './ruby'; +import * as semver from './semver'; +import * as swift from './swift'; +import * as ubuntu from './ubuntu'; + +const api = new Map<string, VersioningApi | VersioningApiConstructor>(); +export default api; + +api.set('cargo', cargo.api); +api.set('composer', composer.api); +api.set('docker', docker.api); +api.set('git', git.api); +api.set('gradle', gradle.api); +api.set('hashicorp', hashicorp.api); +api.set('hex', hex.api); +api.set('ivy', ivy.api); +api.set('loose', loose.api); +api.set('maven', maven.api); +api.set('node', node.api); +api.set('npm', npm.api); +api.set('nuget', nuget.api); +api.set('pep440', pep440.api); +api.set('poetry', poetry.api); +api.set('regex', regex.api); +api.set('ruby', ruby.api); +api.set('semver', semver.api); +api.set('swift', swift.api); +api.set('ubuntu', ubuntu.api); diff --git a/lib/versioning/index.ts b/lib/versioning/index.ts index 5d872a34a4..429023918a 100644 --- a/lib/versioning/index.ts +++ b/lib/versioning/index.ts @@ -1,5 +1,5 @@ import { logger } from '../logger'; -import versionings from './api.generated'; +import versionings from './api'; import { VersioningApi, VersioningApiConstructor, diff --git a/tools/generate-imports.ts b/tools/generate-imports.ts index 898da74cda..90c2b2009b 100644 --- a/tools/generate-imports.ts +++ b/tools/generate-imports.ts @@ -14,15 +14,6 @@ if (!fs.existsSync('data')) { shell.exit(0); } -function findModules(dirname: string): string[] { - return fs - .readdirSync(dirname, { withFileTypes: true }) - .filter((dirent) => dirent.isDirectory()) - .map((dirent) => dirent.name) - .filter((name) => !name.startsWith('__')) - .sort(); -} - async function updateFile(file: string, code: string): Promise<void> { const oldCode = fs.existsSync(file) ? await fs.readFile(file, 'utf8') : null; if (code !== oldCode) { @@ -31,45 +22,6 @@ async function updateFile(file: string, code: string): Promise<void> { newFiles.add(file); } -function camelCase(input: string): string { - return input - .replace(/(?:^\w|[A-Z]|\b\w)/g, (char, index) => - index === 0 ? char.toLowerCase() : char.toUpperCase() - ) - .replace(/-/g, ''); -} - -async function generate({ - path, - types, - map = '', - excludes = [], -}: { - path: string; - types: string[]; - map?: string; - excludes?: string[]; -}): Promise<void> { - shell.echo(`> lib/${path}/`); - let imports = ''; - let maps = ''; - for (const ds of findModules(`lib/${path}`).filter( - (n) => !excludes?.includes(n) - )) { - const name = camelCase(ds); - imports += `import * as ${name} from './${ds}';\n`; - maps += `api.set('${ds}', ${name}${map});\n`; - } - - const code = `import { ${types.join(', ')} } from './common'; - ${imports}\n - const api = new Map<string, ${types.join(' | ')}>(); - export default api; - ${maps}`; - - await updateFile(`lib/${path}/api.generated.ts`, code.replace(/^\s+/gm, '')); -} - async function generateData(): Promise<void> { const files = fs .readdirSync('data', { withFileTypes: true }) @@ -106,27 +58,6 @@ async function generateData(): Promise<void> { try { // data-files await generateData(); - - // datasources - await generate({ path: 'datasource', types: ['DatasourceApi'] }); - - // managers - await generate({ path: 'manager', types: ['ManagerApi'] }); - - // platform - await generate({ - path: 'platform', - types: ['Platform'], - excludes: ['utils', 'git'], - }); - - // versioning - await generate({ - path: 'versioning', - types: ['VersioningApi', 'VersioningApiConstructor'], - map: '.api', - }); - await Promise.all( shell .find('lib/**/*.generated.ts') -- GitLab