Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: raineorshine/npm-check-updates
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v16.3.18
Choose a base ref
...
head repository: raineorshine/npm-check-updates
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v16.3.19
Choose a head ref
  • 5 commits
  • 8 files changed
  • 1 contributor

Commits on Nov 11, 2022

  1. Copy the full SHA
    b1d7e73 View commit details
  2. Copy the full SHA
    051a50d View commit details
  3. Copy the full SHA
    88a508a View commit details
  4. Copy the full SHA
    87acdd8 View commit details
  5. 16.3.19

    raineorshine committed Nov 11, 2022
    Copy the full SHA
    32d48fa View commit details
Showing with 457 additions and 422 deletions.
  1. +2 −2 package-lock.json
  2. +1 −1 package.json
  3. +8 −6 src/lib/cache.ts
  4. +12 −14 src/lib/queryVersions.ts
  5. +2 −3 src/types/Cacher.ts
  6. +92 −0 test/cache.test.ts
  7. +1 −396 test/index.test.ts
  8. +339 −0 test/target.test.ts
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "npm-check-updates",
"version": "16.3.18",
"version": "16.3.19",
"author": "Tomas Junnonen <tomas1@gmail.com>",
"license": "Apache-2.0",
"contributors": [
14 changes: 8 additions & 6 deletions src/lib/cache.ts
Original file line number Diff line number Diff line change
@@ -5,6 +5,8 @@ import { CacheData, Cacher } from '../types/Cacher'
import { Options } from '../types/Options'
import { print } from './logging'

export const CACHE_DELIMITER = '___'

/**
* Check if cache is expired if timestamp is set
*
@@ -25,7 +27,6 @@ function checkCacheExpiration(cacheData: CacheData, cacheExpiration = 10) {
export const defaultCacheFilename = '.ncu-cache.json'
export const defaultCacheFile = `~/${defaultCacheFilename}`
export const resolvedDefaultCacheFile = path.join(os.homedir(), defaultCacheFilename)
const cacheKeyDivider = '###'

/**
* The cacher stores key (name + version) - value (new version) pairs
@@ -63,19 +64,20 @@ export default async function cacher(options: Omit<Options, 'cacher'>): Promise<
}

return {
key: (name, version) => name + cacheKeyDivider + version,
get: key => {
get: (name: string, target: string) => {
const key = `${name}${CACHE_DELIMITER}${target}`
if (!key || !cacheData.packages) return
const cached = cacheData.packages[key]
if (cached && !key.includes(cached)) {
const [name] = key.split(cacheKeyDivider)
const [name] = key.split(CACHE_DELIMITER)
cacheUpdates[name] = cached
}
return cached
},
set: (key, value) => {
set: (name: string, target: string, version: string) => {
const key = `${name}${CACHE_DELIMITER}${target}`
if (!key || !cacheData.packages) return
cacheData.packages[key] = value
cacheData.packages[key] = version
},
save: async () => {
await fs.promises.writeFile(cacheFile, JSON.stringify(cacheData))
26 changes: 12 additions & 14 deletions src/lib/queryVersions.ts
Original file line number Diff line number Diff line change
@@ -24,7 +24,6 @@ const supportedVersionTargets = ['latest', 'newest', 'greatest', 'minor', 'patch
async function queryVersions(packageMap: Index<VersionSpec>, options: Options = {}): Promise<Index<VersionResult>> {
const { default: chalkDefault, Chalk } = await import('chalk')
const chalk = options.color ? new Chalk({ level: 1 }) : chalkDefault
const target = options.target || 'latest'
const packageList = Object.keys(packageMap)
const globalPackageManager = getPackageManager(options.packageManager)

@@ -44,9 +43,16 @@ async function queryVersions(packageMap: Index<VersionSpec>, options: Options =
async function getPackageVersionProtected(dep: VersionSpec): Promise<VersionResult> {
const npmAlias = parseNpmAlias(packageMap[dep])
const [name, version] = npmAlias || [dep, packageMap[dep]]
let distTag = 'latest'
const targetOption = options.target || 'latest'
let target = typeof targetOption === 'string' ? targetOption : targetOption(name, parseRange(version))

if (target[0] === '@') {
distTag = target.slice(1)
target = 'distTag'
}

const cacheKey = options.cacher?.key(name, version)
const cached = options.cacher?.get(cacheKey)
const cached = options.cacher?.get(name, target)
if (cached) {
bar?.tick()

@@ -55,28 +61,20 @@ async function queryVersions(packageMap: Index<VersionSpec>, options: Options =
}
}

let targetResult = typeof target === 'string' ? target : target(name, parseRange(version))
let distTag = 'latest'

if (targetResult[0] === '@') {
distTag = targetResult.slice(1)
targetResult = 'distTag'
}

let versionNew: Version | null = null
const isGithubDependency = isGithubUrl(packageMap[dep])

// use gitTags package manager for git urls (for this dependency only)
const packageManager = isGithubDependency ? packageManagers.gitTags : globalPackageManager
const packageManagerName = isGithubDependency ? 'github urls' : options.packageManager || 'npm'

const getPackageVersion = packageManager[targetResult as keyof typeof packageManager] as GetVersion
const getPackageVersion = packageManager[target as keyof typeof packageManager] as GetVersion

if (!getPackageVersion) {
const packageManagerSupportedVersionTargets = supportedVersionTargets.filter(t => t in packageManager)
return Promise.reject(
new Error(
`Unsupported target "${targetResult}" for ${packageManagerName}. Supported version targets are: ` +
`Unsupported target "${target}" for ${packageManagerName}. Supported version targets are: ` +
packageManagerSupportedVersionTargets.join(', ') +
(!isGithubDependency ? ' and custom distribution tags, following "@" (example: @next)' : ''),
),
@@ -123,7 +121,7 @@ async function queryVersions(packageMap: Index<VersionSpec>, options: Options =
bar?.tick()

if (versionNew) {
options.cacher?.set(cacheKey, versionNew)
options.cacher?.set(name, target, versionNew)
}

return {
5 changes: 2 additions & 3 deletions src/types/Cacher.ts
Original file line number Diff line number Diff line change
@@ -4,9 +4,8 @@ export interface CacheData {
}

export type Cacher = {
key(name: string, version: string): string
get(key: string | undefined): string | undefined
set(key: string | undefined, value: string): void
get(name: string, target: string): string | undefined
set(name: string, target: string, version: string): void
save(): Promise<void>
log(): void
}
92 changes: 92 additions & 0 deletions test/cache.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import chai, { expect } from 'chai'
import chaiString from 'chai-string'
import fs from 'fs/promises'
import rimraf from 'rimraf'
import * as ncu from '../src/'
import { CACHE_DELIMITER, resolvedDefaultCacheFile } from '../src/lib/cache'
import { CacheData } from '../src/types/Cacher'

chai.should()
chai.use(chaiString)

process.env.NCU_TESTS = 'true'

describe('cache', () => {
it('cache latest versions', async () => {
try {
const packageData = {
dependencies: {
// major version upgrade → 2.0.0
'ncu-test-v2': '^1.0.0',
// latest: minor version upgrade → 1.1.0
// greatest: prerelease → 1.2.0-dev.0
'ncu-test-tag': '1.0.0',
// latest: no upgrade
// greatest: prerelease → 2.0.0-alpha.2
'ncu-test-alpha': '1.0.0',
},
}

await ncu.run({ packageData, cache: true })

const cacheData: CacheData = await fs.readFile(resolvedDefaultCacheFile, 'utf-8').then(JSON.parse)

expect(cacheData.timestamp).lessThanOrEqual(Date.now())
expect(cacheData.packages).deep.eq({
[`ncu-test-v2${CACHE_DELIMITER}latest`]: '2.0.0',
[`ncu-test-tag${CACHE_DELIMITER}latest`]: '1.1.0',
[`ncu-test-alpha${CACHE_DELIMITER}latest`]: '1.0.0',
})
} finally {
rimraf.sync(resolvedDefaultCacheFile)
}
})

it('use different cache key for different target', async () => {
try {
const packageData = {
dependencies: {
// major version upgrade → 2.0.0
'ncu-test-v2': '^1.0.0',
// minor version upgrade → 1.1.0
'ncu-test-tag': '1.0.0',
// latest: no upgrade
// greatest: prerelease → 2.0.0.alpha.2
'ncu-test-alpha': '1.0.0',
},
}

// first run caches latest
await ncu.run({ packageData, cache: true })

const cacheData1: CacheData = await fs.readFile(resolvedDefaultCacheFile, 'utf-8').then(JSON.parse)

expect(cacheData1.packages).deep.eq({
[`ncu-test-v2${CACHE_DELIMITER}latest`]: '2.0.0',
[`ncu-test-tag${CACHE_DELIMITER}latest`]: '1.1.0',
[`ncu-test-alpha${CACHE_DELIMITER}latest`]: '1.0.0',
})

// second run has a different target so should not use the cache
const result2 = await ncu.run({ packageData, cache: true, target: 'greatest' })
expect(result2).deep.eq({
'ncu-test-v2': '^2.0.0',
'ncu-test-tag': '1.2.0-dev.0',
'ncu-test-alpha': '2.0.0-alpha.2',
})

const cacheData2: CacheData = await fs.readFile(resolvedDefaultCacheFile, 'utf-8').then(JSON.parse)

expect(cacheData2.packages).deep.eq({
[`ncu-test-v2${CACHE_DELIMITER}latest`]: '2.0.0',
[`ncu-test-tag${CACHE_DELIMITER}latest`]: '1.1.0',
[`ncu-test-alpha${CACHE_DELIMITER}latest`]: '1.0.0',
[`ncu-test-v2${CACHE_DELIMITER}greatest`]: '2.0.0',
[`ncu-test-tag${CACHE_DELIMITER}greatest`]: '1.2.0-dev.0',
[`ncu-test-alpha${CACHE_DELIMITER}greatest`]: '2.0.0-alpha.2',
})
} finally {
rimraf.sync(resolvedDefaultCacheFile)
}
})
})
Loading