mirror of
https://github.com/cypress-io/cypress.git
synced 2025-12-21 14:21:13 -06:00
* migrate cli scripts to TypeScript * convert all javascript source files in the CLI to TypeScript rebase into first * chore: refactor all tests to TypeScript rebase into second * add npmignore for cli for typescript files * update build process * fix publically available exports * Fix cy-in-cy tests * add ts-expect-error to failing files * fix projectConfigIpc failures as there are now multiple installs of tsx * fix after-pack hook * fix binary script * chore: update publish binary to account for CLI being an ESModule compiled down to CommonJS * does this work? * fix the verify spec by making the listr2 renderer silent as it behaves differently since the refactor and is printing non deterministic outputs into our tests that do not have a large impact on the area we are testing and mostly served to actually test the renders of the listr2 framework itself * empty commit * additional refactor to code to remove strange any typing and exporting * bump cache and build binaries * fix CLI exports to keep backwards compatibility * fix unit-tests * turn on mac jobs * fix group name rename in CLI * remove babel deps from cli and explicitly install typescript * address feedback from code review * dont just falsy check results and instead explicitly check for null or undefined * add ts-expect-error * additional pass on cleaning up dynamic require / import from global lib references * annotate ts-expect-errors with reason for why error is expected * add rest of ts-expect-error comments * removing hardcoded branch to publish binary chore/migrate_cli_to_typescript
170 lines
3.8 KiB
TypeScript
170 lines
3.8 KiB
TypeScript
import state from './state'
|
|
import logger from '../logger'
|
|
import fs from '../fs'
|
|
import util from '../util'
|
|
|
|
import { join } from 'path'
|
|
import Table from 'cli-table3'
|
|
import dayjs from 'dayjs'
|
|
import relativeTime from 'dayjs/plugin/relativeTime'
|
|
import chalk from 'chalk'
|
|
import _ from 'lodash'
|
|
import getFolderSize from './get-folder-size'
|
|
|
|
dayjs.extend(relativeTime)
|
|
|
|
// output colors for the table
|
|
const colors = {
|
|
titles: chalk.white,
|
|
dates: chalk.cyan,
|
|
values: chalk.green,
|
|
size: chalk.gray,
|
|
}
|
|
|
|
const logCachePath = (): undefined => {
|
|
logger.always(state.getCacheDir())
|
|
|
|
return undefined
|
|
}
|
|
|
|
const clear = (): Promise<void> => {
|
|
return fs.removeAsync(state.getCacheDir())
|
|
}
|
|
|
|
const prune = async (): Promise<void> => {
|
|
const cacheDir = state.getCacheDir()
|
|
const checkedInBinaryVersion = util.pkgVersion()
|
|
|
|
let deletedBinary = false
|
|
|
|
try {
|
|
const versions = await fs.readdirAsync(cacheDir)
|
|
|
|
for (const version of versions) {
|
|
if (version !== checkedInBinaryVersion) {
|
|
deletedBinary = true
|
|
|
|
const versionDir = join(cacheDir, version)
|
|
|
|
await fs.removeAsync(versionDir)
|
|
}
|
|
}
|
|
|
|
if (deletedBinary) {
|
|
logger.always(`Deleted all binary caches except for the ${checkedInBinaryVersion} binary cache.`)
|
|
} else {
|
|
logger.always(`No binary caches found to prune.`)
|
|
}
|
|
} catch (e: any) {
|
|
if (e.code === 'ENOENT') {
|
|
logger.always(`No Cypress cache was found at ${cacheDir}. Nothing to prune.`)
|
|
|
|
return
|
|
}
|
|
|
|
throw e
|
|
}
|
|
}
|
|
|
|
const fileSizeInMB = (size: number): string => {
|
|
return `${(size / 1024 / 1024).toFixed(1)}MB`
|
|
}
|
|
|
|
/**
|
|
* Collects all cached versions, finds when each was used
|
|
* and prints a table with results to the terminal
|
|
*/
|
|
const list = (showSize: boolean = false): any => {
|
|
return getCachedVersions(showSize)
|
|
.then((binaries: any) => {
|
|
const head = [colors.titles('version'), colors.titles('last used')]
|
|
|
|
if (showSize) {
|
|
head.push(colors.titles('size'))
|
|
}
|
|
|
|
const table = new Table({
|
|
head,
|
|
})
|
|
|
|
binaries.forEach((binary: any) => {
|
|
const versionString = colors.values(binary.version)
|
|
const lastUsed = binary.accessed ? colors.dates(binary.accessed) : 'unknown'
|
|
const row = [versionString, lastUsed]
|
|
|
|
if (showSize) {
|
|
const size = colors.size(fileSizeInMB(binary.size))
|
|
|
|
row.push(size)
|
|
}
|
|
|
|
return table.push(row)
|
|
})
|
|
|
|
logger.always(table.toString())
|
|
})
|
|
}
|
|
|
|
const getCachedVersions = (showSize: boolean): Promise<any> => {
|
|
const cacheDir = state.getCacheDir()
|
|
|
|
return fs
|
|
.readdirAsync(cacheDir)
|
|
.filter(util.isSemver)
|
|
.map((version: any) => {
|
|
return {
|
|
version,
|
|
folderPath: join(cacheDir, version),
|
|
}
|
|
})
|
|
.mapSeries((binary: any) => {
|
|
// last access time on the folder is different from last access time
|
|
// on the Cypress binary
|
|
const binaryDir = state.getBinaryDir(binary.version)
|
|
const executable = state.getPathToExecutable(binaryDir)
|
|
|
|
return fs.statAsync(executable).then((stat: any) => {
|
|
const lastAccessedTime = _.get(stat, 'atime')
|
|
|
|
if (!lastAccessedTime) {
|
|
// the test runner has never been opened
|
|
// or could be a test simulating missing timestamp
|
|
return binary
|
|
}
|
|
|
|
const accessed = dayjs(lastAccessedTime).fromNow()
|
|
|
|
binary.accessed = accessed
|
|
|
|
return binary
|
|
}, (e: any) => {
|
|
// could not find the binary or gets its stats
|
|
return binary
|
|
})
|
|
})
|
|
.mapSeries((binary: any) => {
|
|
if (showSize) {
|
|
const binaryDir = state.getBinaryDir(binary.version)
|
|
|
|
return getFolderSize(binaryDir).then((size: number) => {
|
|
return {
|
|
...binary,
|
|
size,
|
|
}
|
|
})
|
|
}
|
|
|
|
return binary
|
|
})
|
|
}
|
|
|
|
const cacheModule = {
|
|
path: logCachePath,
|
|
clear,
|
|
prune,
|
|
list,
|
|
getCachedVersions,
|
|
}
|
|
|
|
export default cacheModule
|