diff --git a/lib/platform/git/storage.js b/lib/platform/git/storage.ts similarity index 85% rename from lib/platform/git/storage.js rename to lib/platform/git/storage.ts index 2e418d735ec170babdf8251c0cc063d58255f0ab..a01974d8b56fb50bc0fbbc590b04e169ce718bc6 100644 --- a/lib/platform/git/storage.js +++ b/lib/platform/git/storage.ts @@ -1,16 +1,31 @@ -const fs = require('fs-extra'); -const { join } = require('path'); -const path = require('path'); -const URL = require('url'); -const Git = require('simple-git/promise'); -const convertHrtime = require('convert-hrtime'); +import convertHrtime from 'convert-hrtime'; +import fs from 'fs-extra'; +import { join } from 'path'; +import Git from 'simple-git/promise'; +import URL from 'url'; + +declare module 'fs-extra' { + export function exists(pathLike: string): Promise<boolean>; +} + +interface IStorageConfig { + localDir: string; + baseBranch?: string; + url: string; + gitPrivateKey?: string; +} + +interface ILocalConfig extends IStorageConfig { + baseBranch: string; + baseBranchSha: string; + branchExists: { [branch: string]: boolean }; +} class Storage { constructor() { - let config = {}; - /** @type {Git.SimpleGit} */ - let git = null; - let cwd = null; + let config: ILocalConfig = {} as any; + let git: Git.SimpleGit; + let cwd: string; Object.assign(this, { initRepo, @@ -32,7 +47,7 @@ class Storage { }); // istanbul ignore next - async function resetToBranch(branchName) { + async function resetToBranch(branchName: string) { logger.debug(`resetToBranch(${branchName})`); await git.raw(['reset', '--hard']); await git.checkout(branchName); @@ -53,13 +68,13 @@ class Storage { } } - async function initRepo(args) { + async function initRepo(args: IStorageConfig) { cleanRepo(); - config = { ...args }; + config = { ...args } as any; cwd = config.localDir; config.branchExists = {}; logger.info('Initialising git repository into ' + cwd); - const gitHead = path.join(cwd, '.git/HEAD'); + const gitHead = join(cwd, '.git/HEAD'); let clone = true; async function determineBaseBranch() { // see https://stackoverflow.com/a/44750379/1438522 @@ -153,7 +168,7 @@ class Storage { return git.status(); } - async function createBranch(branchName, sha) { + async function createBranch(branchName: string, sha: string) { logger.debug(`createBranch(${branchName})`); await git.reset('hard'); await git.raw(['clean', '-fd']); @@ -163,7 +178,7 @@ class Storage { } // Return the commit SHA for a branch - async function getBranchCommit(branchName) { + async function getBranchCommit(branchName: string) { const res = await git.revparse(['origin/' + branchName]); return res.trim(); } @@ -177,7 +192,7 @@ class Storage { return res.all.map(commit => commit.message); } - async function setBaseBranch(branchName) { + async function setBaseBranch(branchName: string) { if (branchName) { logger.debug(`Setting baseBranch to ${branchName}`); config.baseBranch = branchName; @@ -192,7 +207,7 @@ class Storage { } } - async function getFileList(branchName) { + async function getFileList(branchName?: string) { const branch = branchName || config.baseBranch; const exists = await branchExists(branch); if (!exists) { @@ -211,7 +226,7 @@ class Storage { return files.split('\n').filter(Boolean); } - async function branchExists(branchName) { + async function branchExists(branchName: string) { // First check cache if (config.branchExists[branchName] !== undefined) { return config.branchExists[branchName]; @@ -226,14 +241,14 @@ class Storage { } } - async function getAllRenovateBranches(branchPrefix) { + async function getAllRenovateBranches(branchPrefix: string) { const branches = await git.branch(['--remotes', '--verbose']); return branches.all .map(localName) .filter(branchName => branchName.startsWith(branchPrefix)); } - async function isBranchStale(branchName) { + async function isBranchStale(branchName: string) { const branches = await git.branch([ '--remotes', '--verbose', @@ -243,11 +258,11 @@ class Storage { return !branches.all.map(localName).includes(branchName); } - async function deleteLocalBranch(branchName) { + async function deleteLocalBranch(branchName: string) { await git.branch(['-D', branchName]); } - async function deleteBranch(branchName) { + async function deleteBranch(branchName: string) { try { await git.raw(['push', '--delete', 'origin', branchName]); logger.debug({ branchName }, 'Deleted remote branch'); @@ -271,7 +286,7 @@ class Storage { config.branchExists[branchName] = false; } - async function mergeBranch(branchName) { + async function mergeBranch(branchName: string) { await git.reset('hard'); await git.checkout(['-B', branchName, 'origin/' + branchName]); await git.checkout(config.baseBranch); @@ -279,7 +294,7 @@ class Storage { await git.push('origin', config.baseBranch); } - async function getBranchLastCommitTime(branchName) { + async function getBranchLastCommitTime(branchName: string) { try { const time = await git.show([ '-s', @@ -292,7 +307,7 @@ class Storage { } } - async function getFile(filePath, branchName) { + async function getFile(filePath: string, branchName?: string) { if (branchName) { const exists = await branchExists(branchName); if (!exists) { @@ -311,9 +326,9 @@ class Storage { } async function commitFilesToBranch( - branchName, - files, - message, + branchName: string, + files: any[], + message: string, parentBranch = config.baseBranch ) { logger.debug(`Committing files to branch ${branchName}`); @@ -371,7 +386,19 @@ class Storage { function cleanRepo() {} } - static getUrl({ gitFs, auth, hostname, host, repository }) { + static getUrl({ + gitFs, + auth, + hostname, + host, + repository, + }: { + gitFs: 'ssh' | 'http' | 'https'; + auth: string; + hostname: string; + host: string; + repository: string; + }) { let protocol = gitFs || 'https'; // istanbul ignore if if (protocol.toString() === 'true') { @@ -390,8 +417,8 @@ class Storage { } } -function localName(branchName) { +function localName(branchName: string) { return branchName.replace(/^origin\//, ''); } -module.exports = Storage; +export = Storage; diff --git a/lib/types.d.ts b/lib/types.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..331a2b54c8b16ea0826c8ea7122f41c406d2d7f7 --- /dev/null +++ b/lib/types.d.ts @@ -0,0 +1,23 @@ +declare namespace Renovate { + // TODO: refactor logger + interface ILogger { + trace(...args: any[]): void; + debug(...args: any[]): void; + info(...args: any[]): void; + warn(...args: any[]): void; + error(...args: any[]): void; + fatal(...args: any[]): void; + child(...args: any[]): void; + + setMeta(obj: any): void; + } +} + +declare var logger: Renovate.ILogger; + +declare namespace NodeJS { + interface Global { + gitAuthor?: { name: string; email: string }; + logger: Renovate.ILogger; + } +} diff --git a/package.json b/package.json index a37e38a7a94f41c0adc36e5667909f648255d1fe..6c88ce2b223edea5c7536209036d3bce8f81bf4c 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "renovate-config-validator": "bin/config-validator.js" }, "scripts": { - "build": "yarn clean && tsc && yarn copy-static-files", + "build": "yarn clean && tsc -p tsconfig.app.json && yarn copy-static-files", "clean": "rimraf dist", "clean-cache": "node bin/clean-cache.js", "copy-static-files": "copyfiles -u 1 lib/**/*.json lib/**/*.py dist/", @@ -152,6 +152,8 @@ }, "devDependencies": { "@types/bunyan": "1.8.6", + "@types/convert-hrtime": "2.0.0", + "@types/fs-extra": "5.1.0", "@types/jest": "24.0.13", "@types/node": "11.13.10", "@typescript-eslint/eslint-plugin": "1.7.0", @@ -196,6 +198,7 @@ ] }, "jest": { + "globals": { "ts-jest": { "isolatedModules": true } }, "cacheDirectory": ".cache/jest", "coverageDirectory": "./coverage", "collectCoverage": true, diff --git a/tsconfig.app.json b/tsconfig.app.json new file mode 100644 index 0000000000000000000000000000000000000000..10a65a43840c0979df5b247ff0657fc4ac13e7dc --- /dev/null +++ b/tsconfig.app.json @@ -0,0 +1,6 @@ +{ + "extends": "./tsconfig", + "compilerOptions": { + "resolveJsonModule": false + } +} diff --git a/tsconfig.json b/tsconfig.json index a21aba9e3a2989237d7434843c229e69c1123604..4f4b2cf665e7b0bae085505d7785f594824461b6 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -6,8 +6,13 @@ "allowJs": true, "checkJs": false, "module": "commonjs", - "sourceMap": false + "sourceMap": false, + "allowSyntheticDefaultImports": true, + "esModuleInterop": true, + "resolveJsonModule": true, + "lib": ["es2018"], + "types": ["node"] }, - "include": ["./lib/**/*"], + "include": ["lib/**/*"], "exclude": ["node_modules", "./.cache", "./dist"] } diff --git a/yarn.lock b/yarn.lock index 2c15690b76cc0b8f2dceec9ede7051e568342cca..6853192730c2cebb92352b827693bff3d471e4c1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -496,11 +496,23 @@ dependencies: "@types/node" "*" +"@types/convert-hrtime@2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@types/convert-hrtime/-/convert-hrtime-2.0.0.tgz#48d8215750e602a8ea439591c741cc927c116bb1" + integrity sha512-0+5xvZlHD4Hp2K1yamMvcT8Rq3sQnujafL0PaVg0Q90jWZcK+zF2A+5vJQw0P8F5oOY11l1d5/hF6s4UQEGDdA== + "@types/events@*": version "3.0.0" resolved "https://registry.yarnpkg.com/@types/events/-/events-3.0.0.tgz#2862f3f58a9a7f7c3e78d79f130dd4d71c25c2a7" integrity sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g== +"@types/fs-extra@5.1.0": + version "5.1.0" + resolved "https://registry.yarnpkg.com/@types/fs-extra/-/fs-extra-5.1.0.tgz#2a325ef97901504a3828718c390d34b8426a10a1" + integrity sha512-AInn5+UBFIK9FK5xc9yP5e3TQSPNNgjHByqYcj9g5elVBnDQcQL7PlO1CIRy2gWlbwK7UPYqi7vRvFA44dCmYQ== + dependencies: + "@types/node" "*" + "@types/glob@^7.1.1": version "7.1.1" resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.1.tgz#aa59a1c6e3fbc421e07ccd31a944c30eba521575"