Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
sorenlouv committed Feb 4, 2022
1 parent cb3d7d5 commit 24d689f
Show file tree
Hide file tree
Showing 29 changed files with 756 additions and 389 deletions.
1 change: 1 addition & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"parser": "typescript",
"semi": true,
"singleQuote": true
}
39 changes: 21 additions & 18 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,18 @@
},
"license": "MIT",
"scripts": {
"lint": "tsc --project ./tsconfig.test.json && eslint './**/*.{ts,js}'",
"prepare": "husky install",
"postinstall": "test -f ./dist/scripts/runPostinstall.js && node ./dist/scripts/runPostinstall.js || echo 'Dist folder missing'",
"prepublishOnly": "tsc --project ./tsconfig.prod.json",
"test": "jest",
"test-private": "jest --config ./jest.config.private.js",
"test-mutation": "jest --config ./jest.config.mutation.js",
"postversion": "yarn extractPackageVersion && yarn build",
"prepare": "husky install",
"prepublishOnly": "yarn build",
"build": "tsc --project ./tsconfig.prod.json",
"extractPackageVersion": "node -p \"'export const PACKAGE_VERSION = ' + JSON.stringify(require('./package.json').version) + ';'\" | prettier > src/utils/packageVersion.ts",
"lint": "tsc --project ./tsconfig.test.json && eslint './**/*.{ts,js}'",
"start": "ts-node --transpile-only ./src/entrypoint.cli.ts",
"test-all": "yarn lint && jest --config ./jest.config.all.js",
"start": "ts-node --transpile-only ./src/entrypoint.cli.ts"
"test-mutation": "jest --config ./jest.config.mutation.js",
"test-private": "jest --config ./jest.config.private.js",
"test": "jest"
},
"lint-staged": {
"*.ts": [
Expand Down Expand Up @@ -60,7 +63,7 @@
},
"dependencies": {
"@octokit/rest": "^18.12.0",
"axios": "^0.24.0",
"axios": "^0.25.0",
"dedent": "^0.7.0",
"del": "^6.0.0",
"find-up": "^5.0.0",
Expand All @@ -72,38 +75,38 @@
"strip-json-comments": "^3.1.1",
"terminal-link": "^2.1.1",
"utility-types": "^3.10.0",
"winston": "^3.4.0",
"winston": "^3.5.1",
"yargs": "^17.3.1"
},
"devDependencies": {
"@types/core-js": "^2.5.5",
"@types/dedent": "^0.7.0",
"@types/inquirer": "^8.1.3",
"@types/inquirer": "^8.2.0",
"@types/jest": "^27.4.0",
"@types/lodash": "^4.14.178",
"@types/node": "^17.0.8",
"@types/safe-json-stringify": "^1.1.2",
"@types/yargs": "^17.0.8",
"@types/yargs-parser": "^20.2.1",
"@typescript-eslint/eslint-plugin": "^5.9.1",
"@typescript-eslint/parser": "^5.9.1",
"eslint": "^8.7.0",
"@typescript-eslint/eslint-plugin": "^5.10.2",
"@typescript-eslint/parser": "^5.10.2",
"eslint": "^8.8.0",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-import": "^2.25.4",
"eslint-plugin-jest": "^25.7.0",
"eslint-plugin-jest": "^26.0.0",
"eslint-plugin-prettier": "^4.0.0",
"graphql": "^16.2.0",
"graphql": "^16.3.0",
"graphql-config": "^4.1.0",
"graphql-tag": "^2.12.6",
"husky": "^7.0.4",
"jest": "^27.4.7",
"jest-snapshot-serializer-ansi": "^1.0.0",
"lint-staged": "^12.1.7",
"nock": "^13.2.2",
"lint-staged": "^12.3.3",
"nock": "^13.2.4",
"prettier": "^2.5.1",
"strip-ansi": "^6.0.1",
"ts-jest": "^27.1.3",
"ts-node": "^10.4.0",
"typescript": "^4.5.4"
"typescript": "^4.5.5"
}
}
5 changes: 1 addition & 4 deletions src/entrypoint.cli.e2e.private.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ describe('inquirer cli', () => {
--ci Disable interactive prompts [boolean]
--cherrypickRef Append commit message with \\"(cherry picked from commit...)
[boolean]
--configFile Path to project config [string]
--configFile, --config Path to project config [string]
--since ISO-8601 date for filtering commits [string]
--until ISO-8601 date for filtering commits [string]
--dir Location where the temporary repository will be stored
Expand Down Expand Up @@ -111,9 +111,6 @@ describe('inquirer cli', () => {
devAccessToken,
]);

// eslint-disable-next-line no-console
console.log('res', JSON.stringify(res));

const lineCount = res.split('\n').length;
expect(lineCount).toBeGreaterThan(10);

Expand Down
6 changes: 1 addition & 5 deletions src/entrypoint.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,10 @@ export async function getCommits(options: {
sourceBranch?: string;
dateUntil?: string;
dateSince?: string;
cwd?: string;
}) {
initLogger({ ci: true, accessToken: options.accessToken });

const optionsFromGithub = await getOptionsFromGithub({
cwd: process.cwd(),
...options,
});
const optionsFromGithub = await getOptionsFromGithub(options);

if (options.pullNumber) {
return [
Expand Down
1 change: 1 addition & 0 deletions src/options/cliArgs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ export function getOptionsFromCliArgs(
})

.option('configFile', {
alias: 'config',
description: 'Path to project config',
type: 'string',
})
Expand Down
9 changes: 2 additions & 7 deletions src/options/config/config.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { ConfigFileOptions } from '../ConfigOptions';
import { OptionsFromCliArgs } from '../cliArgs';
import { getOptionsFromGit } from './getOptionsFromGit';
import { getGlobalConfig } from './globalConfig';
import { getProjectConfig } from './projectConfig';

Expand All @@ -22,18 +21,14 @@ export async function getOptionsFromConfigFiles({

// ci: cli and module only flag
const configFile =
optionsFromCliArgs.configFile ??
optionsFromModule.configFile ??
defaultConfigOptions.configFile;
optionsFromCliArgs.configFile ?? optionsFromModule.configFile;

const [gitConfig, projectConfig, globalConfig] = await Promise.all([
getOptionsFromGit({ cwd: process.cwd() }),
const [projectConfig, globalConfig] = await Promise.all([
getProjectConfig({ configFile }),
ci ? undefined : getGlobalConfig(),
]);

return {
...gitConfig,
...globalConfig,
...projectConfig,
...optionsFromModule,
Expand Down
6 changes: 0 additions & 6 deletions src/options/config/getOptionsFromGit.ts

This file was deleted.

70 changes: 58 additions & 12 deletions src/options/options.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import fs from 'fs/promises';
import os from 'os';
import nock from 'nock';
import * as git from '../services/git';
import { GithubConfigOptionsResponse } from '../services/github/v4/getOptionsFromGithub/query';
import { RepoOwnerAndNameResponse } from '../services/github/v4/getRepoOwnerAndName';
import * as logger from '../services/logger';
import { mockConfigFiles } from '../test/mockConfigFiles';
import { mockGqlRequest } from '../test/nockHelpers';
Expand Down Expand Up @@ -67,26 +69,38 @@ describe('getOptions', () => {
`);
});

it('when repoName is missing', async () => {
mockProjectConfig({ repoName: '' });
describe('when repoName and repoOwner are missing', () => {
beforeEach(() => {
mockProjectConfig({ repoName: undefined, repoOwner: undefined });
});

await expect(() => getOptions([], {})).rejects
.toThrowErrorMatchingInlineSnapshot(`
it('should throw if there are no remotes', async () => {
jest.spyOn(git, 'getRepoInfoFromGitRemotes').mockResolvedValue([]);

await expect(() => getOptions([], {})).rejects
.toThrowErrorMatchingInlineSnapshot(`
"Please specify a repo name: \\"--repo-name kibana\\".
Read more: https://github.com/sqren/backport/blob/main/docs/configuration.md#project-config-backportrcjson"
`);
});
});

it('when repoOwner is missing', async () => {
mockProjectConfig({ repoOwner: '' });
it('should get repoName from the remote', async () => {
mockRepoOwnerAndName({
childRepoOwner: 'sqren',
parentRepoOwner: 'elastic',
repoName: 'kibana',
});

await expect(() => getOptions([], {})).rejects
.toThrowErrorMatchingInlineSnapshot(`
"Please specify a repo owner: \\"--repo-owner elastic\\".
jest
.spyOn(git, 'getRepoInfoFromGitRemotes')
.mockResolvedValue([{ repoName: 'kibana', repoOwner: 'sqren' }]);

Read more: https://github.com/sqren/backport/blob/main/docs/configuration.md#project-config-backportrcjson"
`);
const options = await getOptions([], {});

expect(options.repoName).toBe('kibana');
expect(options.repoOwner).toBe('elastic');
});
});
});

Expand Down Expand Up @@ -146,6 +160,7 @@ describe('getOptions', () => {
details: false,
editor: 'code',
fork: true,
gitHostname: 'github.com',
githubApiBaseUrlV4: 'http://localhost/graphql',
historicalBranchLabelMappings: [
{
Expand Down Expand Up @@ -380,3 +395,34 @@ function mockGithubConfigOptions({
},
});
}

function mockRepoOwnerAndName({
repoName,
parentRepoOwner,
childRepoOwner,
}: {
repoName: string;
parentRepoOwner: string;
childRepoOwner: string;
}) {
return mockGqlRequest<RepoOwnerAndNameResponse>({
name: 'RepoOwnerAndName',
statusCode: 200,
body: {
data: {
repository: {
isFork: true,
name: repoName,
owner: {
login: childRepoOwner,
},
parent: {
owner: {
login: parentRepoOwner,
},
},
},
},
},
});
}
71 changes: 45 additions & 26 deletions src/options/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { isEmpty } from 'lodash';
import { HandledError } from '../services/HandledError';
import { getGlobalConfigPath } from '../services/env';
import { getOptionsFromGithub } from '../services/github/v4/getOptionsFromGithub/getOptionsFromGithub';
import { getRepoOwnerAndName } from '../services/github/v4/getRepoOwnerAndName';
import { updateLogger } from './../services/logger';
import { ConfigFileOptions, TargetBranchChoiceOrString } from './ConfigOptions';
import { getOptionsFromCliArgs, OptionsFromCliArgs } from './cliArgs';
Expand All @@ -10,7 +11,7 @@ import {
OptionsFromConfigFiles,
} from './config/config';

const PROJECT_CONFIG_DOCS_LINK =
export const PROJECT_CONFIG_DOCS_LINK =
'https://github.com/sqren/backport/blob/main/docs/configuration.md#project-config-backportrcjson';

const GLOBAL_CONFIG_DOCS_LINK =
Expand All @@ -34,6 +35,7 @@ export const defaultConfigOptions = {
dateUntil: null,
details: false,
fork: true,
gitHostname: 'github.com',
maxNumber: 10,
multipleBranches: true,
multipleCommits: false,
Expand Down Expand Up @@ -65,18 +67,17 @@ export async function getOptions(
optionsFromCliArgs,
});

// update logger
updateLogger(combined);
const { accessToken, repoName, repoOwner } = await getRequiredOptions(
combined
);

// required
const accessToken = requireAccessToken(combined);
const repoName = requireRepoName(combined);
const repoOwner = requireRepoOwner(combined);
// update logger
updateLogger({ accessToken, verbose: combined.verbose });

const optionsFromGithub = await getOptionsFromGithub({
...combined,

// required props
// required options
accessToken,
repoName,
repoOwner,
Expand Down Expand Up @@ -109,6 +110,42 @@ export async function getOptions(
return res;
}

async function getRequiredOptions(combined: CombinedOptions) {
const accessToken = requireAccessToken(combined);

if (combined.repoName && combined.repoOwner) {
return {
accessToken,
repoName: combined.repoName,
repoOwner: combined.repoOwner,
};
}

const { repoName, repoOwner } = await getRepoOwnerAndName({
cwd: combined.cwd,
githubApiBaseUrlV4: combined.githubApiBaseUrlV4,
accessToken,
});

if (!repoName) {
throw new HandledError(
`Please specify a repo name: "--repo-name kibana".\n\nRead more: ${PROJECT_CONFIG_DOCS_LINK}`
);
}

if (!repoOwner) {
throw new HandledError(
`Please specify a repo owner: "--repo-owner elastic".\n\nRead more: ${PROJECT_CONFIG_DOCS_LINK}`
);
}

return {
accessToken,
repoName,
repoOwner,
};
}

type CombinedOptions = ReturnType<typeof getCombinedOptions>;
function getCombinedOptions({
optionsFromConfigFiles,
Expand All @@ -135,24 +172,6 @@ function requireAccessToken(combinedOptions: CombinedOptions): string {
return combinedOptions.accessToken;
}

function requireRepoName(combinedOptions: CombinedOptions): string {
if (!combinedOptions.repoName) {
throw new HandledError(
`Please specify a repo name: "--repo-name kibana".\n\nRead more: ${PROJECT_CONFIG_DOCS_LINK}`
);
}
return combinedOptions.repoName;
}

function requireRepoOwner(combinedOptions: CombinedOptions): string {
if (!combinedOptions.repoOwner) {
throw new HandledError(
`Please specify a repo owner: "--repo-owner elastic".\n\nRead more: ${PROJECT_CONFIG_DOCS_LINK}`
);
}
return combinedOptions.repoOwner;
}

function requireTargetBranch(config: {
targetBranches: CombinedOptions['targetBranches'];
targetBranchChoices: CombinedOptions['targetBranchChoices'];
Expand Down
Loading

0 comments on commit 24d689f

Please sign in to comment.