mirror of
https://github.com/theoludwig/programming-challenges.git
synced 2024-12-08 00:45:29 +01:00
feat(cli): add --ci option to run test
command
This commit is contained in:
parent
b098e04cdc
commit
c55c67e0a5
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
@ -108,4 +108,4 @@ jobs:
|
||||
run: 'npm install --global'
|
||||
|
||||
- name: 'Test'
|
||||
run: 'programming-challenges run test --affected'
|
||||
run: 'programming-challenges run test --affected --ci'
|
||||
|
@ -4,7 +4,7 @@ import * as typanion from 'typanion'
|
||||
import chalk from 'chalk'
|
||||
|
||||
import { Solution } from '../../services/Solution'
|
||||
import { gitAffected } from '../../services/GitAffected'
|
||||
import { GitAffected } from '../../services/GitAffected'
|
||||
|
||||
const successMessage = `${chalk.bold.green('Success:')} Tests passed! 🎉`
|
||||
|
||||
@ -35,10 +35,17 @@ export class RunTestCommand extends Command {
|
||||
description: 'Only run the tests for the affected files in `git`.'
|
||||
})
|
||||
|
||||
public isContinuousIntegration = Option.Boolean('--ci', false, {
|
||||
description: 'Run the tests for the Continuous Integration (CI).'
|
||||
})
|
||||
|
||||
async execute (): Promise<number> {
|
||||
console.log()
|
||||
try {
|
||||
if (this.affected) {
|
||||
const gitAffected = new GitAffected({
|
||||
isContinuousIntegration: this.isContinuousIntegration
|
||||
})
|
||||
const solutions = await gitAffected.getAffectedSolutions()
|
||||
for (const solution of solutions) {
|
||||
await solution.test()
|
||||
|
@ -1,20 +1,66 @@
|
||||
import simpleGit from 'simple-git'
|
||||
import execa from 'execa'
|
||||
|
||||
import { Challenge } from './Challenge'
|
||||
import { Solution } from './Solution'
|
||||
|
||||
const git = simpleGit()
|
||||
|
||||
const solutionsRegex = new RegExp(
|
||||
/challenges\/[\s\S]*\/solutions\/(c|cpp|cs|dart|java|javascript|python|rust|typescript)\/[\s\S]*\/(solution|Solution).(c|cpp|cs|dart|java|js|py|rs|ts)/
|
||||
)
|
||||
|
||||
class GitAffected {
|
||||
export interface GitAffectedOptions {
|
||||
isContinuousIntegration: boolean
|
||||
}
|
||||
|
||||
export class GitAffected implements GitAffectedOptions {
|
||||
public isContinuousIntegration: boolean
|
||||
|
||||
constructor (options: GitAffectedOptions) {
|
||||
this.isContinuousIntegration = options.isContinuousIntegration
|
||||
}
|
||||
|
||||
public parseGitOutput (output: string): string[] {
|
||||
return output
|
||||
.split('\n')
|
||||
.map((line) => line.trim())
|
||||
.filter((line) => line.length > 0)
|
||||
}
|
||||
|
||||
public async getFilesUsingBaseAndHead (
|
||||
base: string,
|
||||
head: string
|
||||
): Promise<string[]> {
|
||||
const { stdout } = await execa.command(
|
||||
`git diff --name-only --relative ${base} ${head}`
|
||||
)
|
||||
return this.parseGitOutput(stdout)
|
||||
}
|
||||
|
||||
public async getUncommittedFiles (): Promise<string[]> {
|
||||
return await this.getFilesUsingBaseAndHead('HEAD', '.')
|
||||
}
|
||||
|
||||
public async getLatestPushedCommit (): Promise<string> {
|
||||
const latestCommit = this.isContinuousIntegration ? '~1' : ''
|
||||
const { stdout } = await execa.command(`git rev-parse origin/master${latestCommit}`)
|
||||
return stdout
|
||||
}
|
||||
|
||||
public async getUnpushedFiles (): Promise<string[]> {
|
||||
return await this.getFilesUsingBaseAndHead(
|
||||
await this.getLatestPushedCommit(),
|
||||
'.'
|
||||
)
|
||||
}
|
||||
|
||||
public async getAffectedSolutions (): Promise<Solution[]> {
|
||||
await git.add('.')
|
||||
const diff = await git.diff(['--name-only', '--staged'])
|
||||
const affectedSolutionsPaths = diff.split('\n').filter((currentDiff) => {
|
||||
return solutionsRegex.test(currentDiff)
|
||||
const files = Array.from(
|
||||
new Set([
|
||||
...(await this.getUnpushedFiles()),
|
||||
...(await this.getUncommittedFiles())
|
||||
])
|
||||
)
|
||||
const affectedSolutionsPaths = files.filter((filePath) => {
|
||||
return solutionsRegex.test(filePath)
|
||||
})
|
||||
return affectedSolutionsPaths.map((solution) => {
|
||||
const [, challengeName, , programmingLanguageName, solutionName] =
|
||||
@ -29,5 +75,3 @@ class GitAffected {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export const gitAffected = new GitAffected()
|
||||
|
55
package-lock.json
generated
55
package-lock.json
generated
@ -14,7 +14,6 @@
|
||||
"execa": "5.1.1",
|
||||
"ora": "5.4.0",
|
||||
"replace-in-file": "6.2.0",
|
||||
"simple-git": "2.39.1",
|
||||
"table": "6.7.1",
|
||||
"typanion": "3.3.1",
|
||||
"validate-npm-package-name": "3.0.0"
|
||||
@ -1190,19 +1189,6 @@
|
||||
"node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@kwsites/file-exists": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@kwsites/file-exists/-/file-exists-1.1.1.tgz",
|
||||
"integrity": "sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw==",
|
||||
"dependencies": {
|
||||
"debug": "^4.1.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@kwsites/promise-deferred": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@kwsites/promise-deferred/-/promise-deferred-1.1.1.tgz",
|
||||
"integrity": "sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw=="
|
||||
},
|
||||
"node_modules/@nodelib/fs.scandir": {
|
||||
"version": "2.1.5",
|
||||
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
|
||||
@ -2445,6 +2431,7 @@
|
||||
"version": "4.3.1",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
|
||||
"integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ms": "2.1.2"
|
||||
},
|
||||
@ -6356,7 +6343,8 @@
|
||||
"node_modules/ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/natural-compare": {
|
||||
"version": "1.4.0",
|
||||
@ -7527,16 +7515,6 @@
|
||||
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz",
|
||||
"integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA=="
|
||||
},
|
||||
"node_modules/simple-git": {
|
||||
"version": "2.39.1",
|
||||
"resolved": "https://registry.npmjs.org/simple-git/-/simple-git-2.39.1.tgz",
|
||||
"integrity": "sha512-+kEAkyQHsWejYxQNCzTrjvCxJOcijpB49RSs7HV+TK9B9prUq7YBNpFstQvjfGBn4Hecywp4tm+breGGGHlHwA==",
|
||||
"dependencies": {
|
||||
"@kwsites/file-exists": "^1.1.1",
|
||||
"@kwsites/promise-deferred": "^1.1.1",
|
||||
"debug": "^4.3.1"
|
||||
}
|
||||
},
|
||||
"node_modules/sisteransi": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz",
|
||||
@ -9473,19 +9451,6 @@
|
||||
"chalk": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"@kwsites/file-exists": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@kwsites/file-exists/-/file-exists-1.1.1.tgz",
|
||||
"integrity": "sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw==",
|
||||
"requires": {
|
||||
"debug": "^4.1.1"
|
||||
}
|
||||
},
|
||||
"@kwsites/promise-deferred": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@kwsites/promise-deferred/-/promise-deferred-1.1.1.tgz",
|
||||
"integrity": "sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw=="
|
||||
},
|
||||
"@nodelib/fs.scandir": {
|
||||
"version": "2.1.5",
|
||||
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
|
||||
@ -10420,6 +10385,7 @@
|
||||
"version": "4.3.1",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
|
||||
"integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ms": "2.1.2"
|
||||
}
|
||||
@ -13314,7 +13280,8 @@
|
||||
"ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
|
||||
"dev": true
|
||||
},
|
||||
"natural-compare": {
|
||||
"version": "1.4.0",
|
||||
@ -14163,16 +14130,6 @@
|
||||
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz",
|
||||
"integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA=="
|
||||
},
|
||||
"simple-git": {
|
||||
"version": "2.39.1",
|
||||
"resolved": "https://registry.npmjs.org/simple-git/-/simple-git-2.39.1.tgz",
|
||||
"integrity": "sha512-+kEAkyQHsWejYxQNCzTrjvCxJOcijpB49RSs7HV+TK9B9prUq7YBNpFstQvjfGBn4Hecywp4tm+breGGGHlHwA==",
|
||||
"requires": {
|
||||
"@kwsites/file-exists": "^1.1.1",
|
||||
"@kwsites/promise-deferred": "^1.1.1",
|
||||
"debug": "^4.3.1"
|
||||
}
|
||||
},
|
||||
"sisteransi": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz",
|
||||
|
@ -42,7 +42,6 @@
|
||||
"execa": "5.1.1",
|
||||
"ora": "5.4.0",
|
||||
"replace-in-file": "6.2.0",
|
||||
"simple-git": "2.39.1",
|
||||
"table": "6.7.1",
|
||||
"typanion": "3.3.1",
|
||||
"validate-npm-package-name": "3.0.0"
|
||||
|
Loading…
Reference in New Issue
Block a user