feat: add support for including matching changed files when dir_names is set to true (#1464)
Co-authored-by: tj-actions[bot] <109116665+tj-actions-bot@users.noreply.github.com> Co-authored-by: GitHub Action <action@github.com>
This commit is contained in:
@@ -2,6 +2,7 @@ import * as core from '@actions/core'
|
||||
import * as github from '@actions/github'
|
||||
import type {RestEndpointMethodTypes} from '@octokit/rest'
|
||||
import flatten from 'lodash/flatten'
|
||||
import mm from 'micromatch'
|
||||
import * as path from 'path'
|
||||
|
||||
import {DiffResult} from './commitSha'
|
||||
@@ -9,8 +10,10 @@ import {Inputs} from './inputs'
|
||||
import {
|
||||
getAllChangedFiles,
|
||||
getDirnameMaxDepth,
|
||||
getDirNamesIncludeFilesPattern,
|
||||
gitRenamedFiles,
|
||||
gitSubmoduleDiffSHA,
|
||||
isWindows,
|
||||
jsonOutput
|
||||
} from './utils'
|
||||
|
||||
@@ -155,6 +158,35 @@ export const getAllDiffFiles = async ({
|
||||
return files
|
||||
}
|
||||
|
||||
function* getFilePaths({
|
||||
inputs,
|
||||
filePaths,
|
||||
dirNamesIncludeFilePatterns
|
||||
}: {
|
||||
inputs: Inputs
|
||||
filePaths: string[]
|
||||
dirNamesIncludeFilePatterns: string[]
|
||||
}): Generator<string> {
|
||||
for (const filePath of filePaths) {
|
||||
if (inputs.dirNames) {
|
||||
if (dirNamesIncludeFilePatterns.length > 0) {
|
||||
const isWin = isWindows()
|
||||
const matchOptions = {dot: true, windows: isWin, noext: true}
|
||||
if (mm.isMatch(filePath, dirNamesIncludeFilePatterns, matchOptions)) {
|
||||
yield filePath
|
||||
}
|
||||
}
|
||||
yield getDirnameMaxDepth({
|
||||
relativePath: filePath,
|
||||
dirNamesMaxDepth: inputs.dirNamesMaxDepth,
|
||||
excludeCurrentDir: inputs.dirNamesExcludeCurrentDir
|
||||
})
|
||||
} else {
|
||||
yield filePath
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function* getChangeTypeFilesGenerator({
|
||||
inputs,
|
||||
changedFiles,
|
||||
@@ -164,18 +196,21 @@ function* getChangeTypeFilesGenerator({
|
||||
changedFiles: ChangedFiles
|
||||
changeTypes: ChangeTypeEnum[]
|
||||
}): Generator<string> {
|
||||
const dirNamesIncludeFilePatterns = getDirNamesIncludeFilesPattern({inputs})
|
||||
core.debug(
|
||||
`Dir names include file patterns: ${JSON.stringify(
|
||||
dirNamesIncludeFilePatterns
|
||||
)}`
|
||||
)
|
||||
|
||||
for (const changeType of changeTypes) {
|
||||
const files = changedFiles[changeType] || []
|
||||
for (const filePath of files) {
|
||||
if (inputs.dirNames) {
|
||||
yield getDirnameMaxDepth({
|
||||
relativePath: filePath,
|
||||
dirNamesMaxDepth: inputs.dirNamesMaxDepth,
|
||||
excludeCurrentDir: inputs.dirNamesExcludeCurrentDir
|
||||
})
|
||||
} else {
|
||||
yield filePath
|
||||
}
|
||||
const filePaths = changedFiles[changeType] || []
|
||||
for (const filePath of getFilePaths({
|
||||
inputs,
|
||||
filePaths,
|
||||
dirNamesIncludeFilePatterns
|
||||
})) {
|
||||
yield filePath
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -213,16 +248,21 @@ function* getAllChangeTypeFilesGenerator({
|
||||
inputs: Inputs
|
||||
changedFiles: ChangedFiles
|
||||
}): Generator<string> {
|
||||
for (const filePath of flatten(Object.values(changedFiles))) {
|
||||
if (inputs.dirNames) {
|
||||
yield getDirnameMaxDepth({
|
||||
relativePath: filePath,
|
||||
dirNamesMaxDepth: inputs.dirNamesMaxDepth,
|
||||
excludeCurrentDir: inputs.dirNamesExcludeCurrentDir
|
||||
})
|
||||
} else {
|
||||
yield filePath
|
||||
}
|
||||
const dirNamesIncludeFilePatterns = getDirNamesIncludeFilesPattern({inputs})
|
||||
core.debug(
|
||||
`Dir names include file patterns: ${JSON.stringify(
|
||||
dirNamesIncludeFilePatterns
|
||||
)}`
|
||||
)
|
||||
|
||||
const filePaths = flatten(Object.values(changedFiles))
|
||||
|
||||
for (const filePath of getFilePaths({
|
||||
inputs,
|
||||
filePaths,
|
||||
dirNamesIncludeFilePatterns
|
||||
})) {
|
||||
yield filePath
|
||||
}
|
||||
}
|
||||
|
||||
@@ -309,5 +349,6 @@ export const getChangedFilesFromGithubAPI = async ({
|
||||
changedFiles[changeType].push(item.filename)
|
||||
}
|
||||
}
|
||||
|
||||
return changedFiles
|
||||
}
|
||||
|
||||
@@ -29,6 +29,8 @@ export type Inputs = {
|
||||
dirNames: boolean
|
||||
dirNamesMaxDepth?: number
|
||||
dirNamesExcludeCurrentDir: boolean
|
||||
dirNamesIncludeFiles: string
|
||||
dirNamesIncludeFilesSeparator: string
|
||||
json: boolean
|
||||
escapeJson: boolean
|
||||
fetchDepth?: number
|
||||
@@ -135,6 +137,16 @@ export const getInputs = (): Inputs => {
|
||||
required: false
|
||||
}
|
||||
)
|
||||
const dirNamesIncludeFiles = core.getInput('dir_names_include_files', {
|
||||
required: false
|
||||
})
|
||||
const dirNamesIncludeFilesSeparator = core.getInput(
|
||||
'dir_names_include_files_separator',
|
||||
{
|
||||
required: false,
|
||||
trimWhitespace: false
|
||||
}
|
||||
)
|
||||
const json = core.getBooleanInput('json', {required: false})
|
||||
const escapeJson = core.getBooleanInput('escape_json', {required: false})
|
||||
const fetchDepth = core.getInput('fetch_depth', {required: false})
|
||||
@@ -212,17 +224,19 @@ export const getInputs = (): Inputs => {
|
||||
includeAllOldNewRenamedFiles,
|
||||
oldNewSeparator,
|
||||
oldNewFilesSeparator,
|
||||
skipInitialFetch,
|
||||
// End Not Supported via REST API
|
||||
dirNames,
|
||||
dirNamesExcludeCurrentDir,
|
||||
dirNamesIncludeFiles,
|
||||
dirNamesIncludeFilesSeparator,
|
||||
json,
|
||||
escapeJson,
|
||||
writeOutputFiles,
|
||||
outputDir,
|
||||
outputRenamedFilesAsDeletedAndAdded,
|
||||
token,
|
||||
apiUrl,
|
||||
skipInitialFetch
|
||||
apiUrl
|
||||
}
|
||||
|
||||
if (fetchDepth) {
|
||||
|
||||
16
src/main.ts
16
src/main.ts
@@ -11,8 +11,8 @@ import {
|
||||
import {setChangedFilesOutput} from './changedFilesOutput'
|
||||
import {
|
||||
DiffResult,
|
||||
getSHAForPullRequestEvent,
|
||||
getSHAForNonPullRequestEvent
|
||||
getSHAForNonPullRequestEvent,
|
||||
getSHAForPullRequestEvent
|
||||
} from './commitSha'
|
||||
import {Env, getEnv} from './env'
|
||||
import {getInputs, Inputs} from './inputs'
|
||||
@@ -311,10 +311,20 @@ export async function run(): Promise<void> {
|
||||
'baseSha',
|
||||
'since',
|
||||
'until',
|
||||
'path',
|
||||
'quotePath',
|
||||
'diffRelative',
|
||||
'sinceLastRemoteCommit',
|
||||
'recoverDeletedFiles',
|
||||
'recoverDeletedFilesToDestination',
|
||||
'includeAllOldNewRenamedFiles'
|
||||
'recoverFiles',
|
||||
'recoverFilesSeparator',
|
||||
'recoverFilesIgnore',
|
||||
'recoverFilesIgnoreSeparator',
|
||||
'includeAllOldNewRenamedFiles',
|
||||
'oldNewSeparator',
|
||||
'oldNewFilesSeparator',
|
||||
'skipInitialFetch'
|
||||
]
|
||||
|
||||
for (const input of unsupportedInputs) {
|
||||
|
||||
48
src/utils.ts
48
src/utils.ts
@@ -38,15 +38,6 @@ export const normalizeSeparators = (p: string): string => {
|
||||
return p.replace(/\/\/+/g, '/')
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize file path separators to '/' on all platforms
|
||||
* @param p - file path
|
||||
* @returns file path with normalized separators
|
||||
*/
|
||||
const normalizePath = (p: string): string => {
|
||||
return p.replace(/\\/g, '/')
|
||||
}
|
||||
|
||||
/**
|
||||
* Trims unnecessary trailing slash from file path
|
||||
* @param p - file path
|
||||
@@ -365,7 +356,7 @@ export const getSubmodulePath = async ({
|
||||
return stdout
|
||||
.trim()
|
||||
.split('\n')
|
||||
.map((line: string) => normalizePath(line.trim().split(' ')[1]))
|
||||
.map((line: string) => normalizeSeparators(line.trim().split(' ')[1]))
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -478,13 +469,15 @@ export const gitRenamedFiles = async ({
|
||||
core.debug(`Renamed file: ${line}`)
|
||||
const [, oldPath, newPath] = line.split('\t')
|
||||
if (isSubmodule) {
|
||||
return `${normalizePath(
|
||||
return `${normalizeSeparators(
|
||||
path.join(parentDir, oldPath)
|
||||
)}${oldNewSeparator}${normalizePath(path.join(parentDir, newPath))}`
|
||||
)}${oldNewSeparator}${normalizeSeparators(
|
||||
path.join(parentDir, newPath)
|
||||
)}`
|
||||
}
|
||||
return `${normalizePath(oldPath)}${oldNewSeparator}${normalizePath(
|
||||
newPath
|
||||
)}`
|
||||
return `${normalizeSeparators(
|
||||
oldPath
|
||||
)}${oldNewSeparator}${normalizeSeparators(newPath)}`
|
||||
})
|
||||
}
|
||||
|
||||
@@ -564,11 +557,11 @@ export const getAllChangedFiles = async ({
|
||||
for (const line of lines) {
|
||||
const [changeType, filePath, newPath = ''] = line.split('\t')
|
||||
const normalizedFilePath = isSubmodule
|
||||
? normalizePath(path.join(parentDir, filePath))
|
||||
: normalizePath(filePath)
|
||||
? normalizeSeparators(path.join(parentDir, filePath))
|
||||
: normalizeSeparators(filePath)
|
||||
const normalizedNewPath = isSubmodule
|
||||
? normalizePath(path.join(parentDir, newPath))
|
||||
: normalizePath(newPath)
|
||||
? normalizeSeparators(path.join(parentDir, newPath))
|
||||
: normalizeSeparators(newPath)
|
||||
|
||||
if (changeType.startsWith('R')) {
|
||||
if (outputRenamedFilesAsDeletedAndAdded) {
|
||||
@@ -607,13 +600,14 @@ export const getFilteredChangedFiles = async ({
|
||||
[ChangeTypeEnum.Unknown]: []
|
||||
}
|
||||
const hasFilePatterns = filePatterns.length > 0
|
||||
const isWin = isWindows()
|
||||
|
||||
for (const changeType of Object.keys(allDiffFiles)) {
|
||||
const files = allDiffFiles[changeType as ChangeTypeEnum]
|
||||
if (hasFilePatterns) {
|
||||
changedFiles[changeType as ChangeTypeEnum] = mm(files, filePatterns, {
|
||||
dot: true,
|
||||
windows: isWindows(),
|
||||
windows: isWin,
|
||||
noext: true
|
||||
})
|
||||
} else {
|
||||
@@ -873,7 +867,7 @@ export const getDirnameMaxDepth = ({
|
||||
return ''
|
||||
}
|
||||
|
||||
return normalizePath(output)
|
||||
return normalizeSeparators(output)
|
||||
}
|
||||
|
||||
export const jsonOutput = ({
|
||||
@@ -888,6 +882,16 @@ export const jsonOutput = ({
|
||||
return shouldEscape ? result.replace(/"/g, '\\"') : result
|
||||
}
|
||||
|
||||
export const getDirNamesIncludeFilesPattern = ({
|
||||
inputs
|
||||
}: {
|
||||
inputs: Inputs
|
||||
}): string[] => {
|
||||
return inputs.dirNamesIncludeFiles
|
||||
.split(inputs.dirNamesIncludeFilesSeparator)
|
||||
.filter(Boolean)
|
||||
}
|
||||
|
||||
export const getFilePatterns = async ({
|
||||
inputs,
|
||||
workingDirectory
|
||||
@@ -897,7 +901,7 @@ export const getFilePatterns = async ({
|
||||
}): Promise<string[]> => {
|
||||
let filePatterns = inputs.files
|
||||
.split(inputs.filesSeparator)
|
||||
.filter(p => p !== '')
|
||||
.filter(Boolean)
|
||||
.join('\n')
|
||||
|
||||
if (inputs.filesFromSourceFile !== '') {
|
||||
|
||||
Reference in New Issue
Block a user