Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -454,7 +454,7 @@ jobs:
gcloud pubsub topics publish $GCLOUD_UPLOADER_PUBSUB_TOPIC --message '{"release":"'"$RELEASE_TAG"'", "latest":true}'

standards-coverage-comparison:
machine:
machine:
image: ubuntu-2004:202201-02
steps:
- checkout
Expand All @@ -478,12 +478,12 @@ workflows:

'Build and Test':
jobs:
# - standards-coverage-comparison:
# context:
# - 'DockerHub Push Context'
# - 'Github Checkout'
# requires:
# - build-alpine
# - standards-coverage-comparison:
# context:
# - 'DockerHub Push Context'
# - 'Github Checkout'
# requires:
# - build-alpine
- build-linux-and-osx
- build-alpine:
requires:
Expand Down
6 changes: 6 additions & 0 deletions src/helpers/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,12 @@ const args: ICLIArgument[] = [
type: 'string',
description: 'Target file(s) to upload',
},
{
alias: 'full',
name: 'fullReport',
type: 'string',
description: 'Specify the path to a previously uploaded Codecov report'
},
{
alias: 'F',
name: 'flags',
Expand Down
302 changes: 158 additions & 144 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { UploaderArgs, UploaderInputs } from './types'

import fs from 'fs'
import zlib from 'zlib'
import { version } from '../package.json'
import { detectProvider } from './helpers/provider'
Expand Down Expand Up @@ -154,189 +155,202 @@ export async function main(
// #region == Step 4: get network
const uploadFileChunks: Buffer[] = []

if (!args.feature || args.feature.split(',').includes('network') === false) {
UploadLogger.verbose('Start of network processing...')
let fileListing = ''
try {
fileListing = await getFileListing(projectRoot, args)
} catch (error) {
throw new Error(`Error getting file listing: ${error}`)
}
if (!args.fullReport) {
if (!args.feature || args.feature.split(',').includes('network') === false) {
UploadLogger.verbose('Start of network processing...')
let fileListing = ''
try {
fileListing = await getFileListing(projectRoot, args)
} catch (error) {
throw new Error(`Error getting file listing: ${error}`)
}

uploadFileChunks.push(Buffer.from(fileListing))
uploadFileChunks.push(Buffer.from(MARKER_NETWORK_END))
}
uploadFileChunks.push(Buffer.from(fileListing))
uploadFileChunks.push(Buffer.from(MARKER_NETWORK_END))
}

// #endregion
// #region == Step 5: select coverage files (search or specify)
// #endregion
// #region == Step 5: select coverage files (search or specify)

let requestedPaths: string[] = []
let requestedPaths: string[] = []

// Look for files
// Look for files

if (args.gcov) {
const gcovInclude: string[] = argAsArray(args.gcovInclude)
const gcovIgnore: string[] = argAsArray(args.gcovIgnore)
const gcovArgs: string[] = argAsArray(args.gcovArgs)
const gcovExecutable: string = args.gcovExecutable || 'gcov'
if (args.gcov) {
const gcovInclude: string[] = argAsArray(args.gcovInclude)
const gcovIgnore: string[] = argAsArray(args.gcovIgnore)
const gcovArgs: string[] = argAsArray(args.gcovArgs)
const gcovExecutable: string = args.gcovExecutable || 'gcov'

UploadLogger.verbose(`Running ${gcovExecutable}...`)
const gcovLogs = await generateGcovCoverageFiles(projectRoot, gcovInclude, gcovIgnore, gcovArgs, gcovExecutable)
UploadLogger.verbose(`${gcovLogs}`)
}
UploadLogger.verbose(`Running ${gcovExecutable}...`)
const gcovLogs = await generateGcovCoverageFiles(projectRoot, gcovInclude, gcovIgnore, gcovArgs, gcovExecutable)
UploadLogger.verbose(`${gcovLogs}`)
}

if (args.swift) {
await generateSwiftCoverageFiles(args.swiftProject || '')
}
if (args.swift) {
await generateSwiftCoverageFiles(args.swiftProject || '')
}

if (args.xcode) {
if (!args.xcodeArchivePath) {
throw new Error('Please specify xcodeArchivePath to run the Codecov uploader with xcode support')
} else {
const xcodeArchivePath: string = args.xcodeArchivePath
const xcodeLogs = await generateXcodeCoverageFiles(xcodeArchivePath)
UploadLogger.verbose(`${xcodeLogs}`)
if (args.xcode) {
if (!args.xcodeArchivePath) {
throw new Error('Please specify xcodeArchivePath to run the Codecov uploader with xcode support')
} else {
const xcodeArchivePath: string = args.xcodeArchivePath
const xcodeLogs = await generateXcodeCoverageFiles(xcodeArchivePath)
UploadLogger.verbose(`${xcodeLogs}`)
}
}
}

let coverageFilePaths: string[] = []
if (args.file !== undefined) {
if (typeof args.file === 'string') {
requestedPaths = args.file.split(',')
} else {
requestedPaths = args.file // Already an array
let coverageFilePaths: string[] = []
if (args.file !== undefined) {
if (typeof args.file === 'string') {
requestedPaths = args.file.split(',')
} else {
requestedPaths = args.file // Already an array
}

requestedPaths = requestedPaths.filter((path) => {
return Boolean(path) || info('Warning: Skipping an empty path passed to `-f`')
})
}

requestedPaths = requestedPaths.filter((path) => {
return Boolean(path) || info('Warning: Skipping an empty path passed to `-f`')
})
}
try {
const coveragePyLogs = await generateCoveragePyFile(projectRoot, requestedPaths)
UploadLogger.verbose(`${coveragePyLogs}`)
} catch (error) {
UploadLogger.verbose(`Skipping coveragepy conversion: ${error}`)
}

try {
const coveragePyLogs = await generateCoveragePyFile(projectRoot, requestedPaths)
UploadLogger.verbose(`${coveragePyLogs}`)
} catch (error) {
UploadLogger.verbose(`Skipping coveragepy conversion: ${error}`)
}
coverageFilePaths = requestedPaths

coverageFilePaths = requestedPaths
if (!args.feature || args.feature.split(',').includes('search') === false) {
info('Searching for coverage files...')
const isNegated = (path: string) => path.startsWith('!')
coverageFilePaths = coverageFilePaths.concat(await getCoverageFiles(
args.dir || projectRoot,
(() => {
const numOfNegatedPaths = coverageFilePaths.filter(isNegated).length

if (!args.feature || args.feature.split(',').includes('search') === false) {
info('Searching for coverage files...')
const isNegated = (path: string) => path.startsWith('!')
coverageFilePaths = coverageFilePaths.concat(await getCoverageFiles(
args.dir || projectRoot,
(() => {
const numOfNegatedPaths = coverageFilePaths.filter(isNegated).length
if (coverageFilePaths.length > numOfNegatedPaths) {
return coverageFilePaths
} else {
return coverageFilePaths.concat(coverageFilePatterns())
}
})(),
))

if (coverageFilePaths.length > numOfNegatedPaths) {
return coverageFilePaths
} else {
return coverageFilePaths.concat(coverageFilePatterns())
}
})(),
))
// Generate what the file listing would be after the blocklist is applied

// Generate what the file listing would be after the blocklist is applied
let coverageFilePathsAfterFilter = coverageFilePaths

let coverageFilePathsAfterFilter = coverageFilePaths
if (coverageFilePaths.length > 0) {
coverageFilePathsAfterFilter = filterFilesAgainstBlockList(coverageFilePaths, getBlocklist())
}

if (coverageFilePaths.length > 0) {
coverageFilePathsAfterFilter = filterFilesAgainstBlockList(coverageFilePaths, getBlocklist())
}



// If args.file was passed, emit warning for 'filtered' filess

// If args.file was passed, emit warning for 'filtered' filess
if (requestedPaths.length > 0) {
if (coverageFilePathsAfterFilter.length !== requestedPaths.length) {
info('Warning: Some files passed via the -f flag would normally be excluded from search.')
info('If Codecov encounters issues processing your reports, please review https://docs.codecov.com/docs/supported-report-formats')
}
} else {
// Overwrite coverageFilePaths with coverageFilePathsAfterFilter
info('Warning: Some files located via search were excluded from upload.')
info('If Codecov did not locate your files, please review https://docs.codecov.com/docs/supported-report-formats')

if (requestedPaths.length > 0) {
if (coverageFilePathsAfterFilter.length !== requestedPaths.length) {
info('Warning: Some files passed via the -f flag would normally be excluded from search.')
info('If Codecov encounters issues processing your reports, please review https://docs.codecov.com/docs/supported-report-formats')
coverageFilePaths = coverageFilePathsAfterFilter
}
} else {
// Overwrite coverageFilePaths with coverageFilePathsAfterFilter
info('Warning: Some files located via search were excluded from upload.')
info('If Codecov did not locate your files, please review https://docs.codecov.com/docs/supported-report-formats')

coverageFilePaths = coverageFilePathsAfterFilter
}

}
let coverageFilePathsThatExist: string[] = []

let coverageFilePathsThatExist: string[] = []
if (coverageFilePaths.length > 0) {
coverageFilePathsThatExist = cleanCoverageFilePaths(args.dir || projectRoot, coverageFilePaths)
}

if (coverageFilePaths.length > 0) {
coverageFilePathsThatExist = cleanCoverageFilePaths(args.dir || projectRoot, coverageFilePaths)
}
if (coverageFilePathsThatExist.length > 0) {
info(`=> Found ${coverageFilePathsThatExist.length} possible coverage files:\n ` +
coverageFilePathsThatExist.join('\n '))
} else {
const noFilesError = args.file ?
'No coverage files found, exiting.' :
'No coverage files located, please try use `-f`, or change the project root with `-R`'
throw new Error(noFilesError)
}

if (coverageFilePathsThatExist.length > 0) {
info(`=> Found ${coverageFilePathsThatExist.length} possible coverage files:\n ` +
coverageFilePathsThatExist.join('\n '))
} else {
const noFilesError = args.file ?
'No coverage files found, exiting.' :
'No coverage files located, please try use `-f`, or change the project root with `-R`'
throw new Error(noFilesError)
}
UploadLogger.verbose('End of network processing')
// #endregion
// #region == Step 6: generate upload file
// TODO: capture envs

UploadLogger.verbose('End of network processing')
// #endregion
// #region == Step 6: generate upload file
// TODO: capture envs
// Get coverage report contents
let coverageFileAdded = false
for (const coverageFile of coverageFilePathsThatExist) {
let fileContents
try {
info(`Processing ${getFilePath(args.dir || projectRoot, coverageFile)}...`),
(fileContents = await readCoverageFile(
args.dir || projectRoot,
coverageFile,
))
} catch (err) {
info(`Could not read coverage file (${coverageFile}): ${err}`)
continue
}

// Get coverage report contents
let coverageFileAdded = false
for (const coverageFile of coverageFilePathsThatExist) {
let fileContents
try {
info(`Processing ${getFilePath(args.dir || projectRoot, coverageFile)}...`),
(fileContents = await readCoverageFile(
args.dir || projectRoot,
coverageFile,
))
} catch (err) {
info(`Could not read coverage file (${coverageFile}): ${err}`)
continue
uploadFileChunks.push(Buffer.from(fileHeader(coverageFile)))
uploadFileChunks.push(Buffer.from(fileContents))
uploadFileChunks.push(Buffer.from(MARKER_FILE_END))
coverageFileAdded = true
}
if (!coverageFileAdded) {
throw new Error( 'No coverage files could be found to upload, exiting.')
}

uploadFileChunks.push(Buffer.from(fileHeader(coverageFile)))
uploadFileChunks.push(Buffer.from(fileContents))
uploadFileChunks.push(Buffer.from(MARKER_FILE_END))
coverageFileAdded = true
}
if (!coverageFileAdded) {
throw new Error( 'No coverage files could be found to upload, exiting.')
}
// Environment variables
if (args.env || envs.CODECOV_ENV) {
const environmentVars = args.env || envs.CODECOV_ENV || ''
const vars = environmentVars
.split(',')
.filter(Boolean)
.map(evar => `${evar}=${process.env[evar] || ''}\n`)
.join('')
uploadFileChunks.push(Buffer.from(vars))
uploadFileChunks.push(Buffer.from(MARKER_ENV_END))
}

// Cleanup
if (args.clean) {
for (const coverageFile of coverageFilePathsThatExist) {
removeFile(args.dir || projectRoot, coverageFile)
// Fixes
if (args.feature && args.feature.split(',').includes('fixes') === true) {
info('Generating file fixes...')
const fixes = await generateFixes(projectRoot)
uploadFileChunks.push(Buffer.from(FIXES_HEADER))
uploadFileChunks.push(Buffer.from(fixes))
uploadFileChunks.push(Buffer.from(MARKER_FILE_END))
info('Finished generating file fixes')
}
}

// Environment variables
if (args.env || envs.CODECOV_ENV) {
const environmentVars = args.env || envs.CODECOV_ENV || ''
const vars = environmentVars
.split(',')
.filter(Boolean)
.map(evar => `${evar}=${process.env[evar] || ''}\n`)
.join('')
uploadFileChunks.push(Buffer.from(vars))
uploadFileChunks.push(Buffer.from(MARKER_ENV_END))
}
// Cleanup
if (args.clean) {
for (const coverageFile of coverageFilePathsThatExist) {
removeFile(args.dir || projectRoot, coverageFile)
}
}
} else {
const fullPath = getFilePath(args.dir || projectRoot, args.fullReport)
if (!fs.existsSync(fullPath)) {
throw new Error(`Error uploading to Codecov: Path to ${args.fullReport} does not exist and no coverage report could be uploaded`)
}
uploadFileChunks.push(fs.readFileSync(fullPath))

// Fixes
if (args.feature && args.feature.split(',').includes('fixes') === true) {
info('Generating file fixes...')
const fixes = await generateFixes(projectRoot)
uploadFileChunks.push(Buffer.from(FIXES_HEADER))
uploadFileChunks.push(Buffer.from(fixes))
uploadFileChunks.push(Buffer.from(MARKER_FILE_END))
info('Finished generating file fixes')
// Cleanup
if (args.clean) {
removeFile(args.dir || projectRoot, args.fullReport)
}
}

const uploadFile = Buffer.concat(uploadFileChunks)
Expand Down
Loading