-
-
Notifications
You must be signed in to change notification settings - Fork 4
feat: show warning for dist tags #38
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
nitodeco
wants to merge
1
commit into
npmx-dev:main
Choose a base branch
from
nitodeco:show-warning-for-latest
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| import type { DiagnosticRule } from '..' | ||
| import { COMMON_DIST_TAGS } from '#constants' | ||
| import { npmxPackageUrl } from '#utils/links' | ||
| import { isSupportedProtocol, parseVersion } from '#utils/package' | ||
| import { DiagnosticSeverity, Uri } from 'vscode' | ||
|
|
||
| export const checkDistTag: DiagnosticRule = (dep, pkg) => { | ||
| const parsed = parseVersion(dep.version) | ||
| if (!parsed || !isSupportedProtocol(parsed.protocol)) | ||
| return | ||
|
|
||
| const tag = parsed.semver | ||
| const isPublishedDistTag = tag in (pkg.distTags ?? {}) | ||
| const isCommonDistTag = COMMON_DIST_TAGS.has(tag.toLowerCase()) | ||
| if (!isPublishedDistTag && !isCommonDistTag) | ||
| return | ||
|
|
||
| return { | ||
| node: dep.versionNode, | ||
| message: `"${dep.name}" uses the "${tag}" version tag. This may lead to unexpected breaking changes. Consider pinning to a specific version.`, | ||
| severity: DiagnosticSeverity.Warning, | ||
| code: { | ||
| value: 'dist-tag', | ||
| target: Uri.parse(npmxPackageUrl(dep.name)), | ||
| }, | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,104 @@ | ||
| import { describe, expect, it } from 'vitest' | ||
| import { checkDistTag } from '../src/providers/diagnostics/rules/dist-tag' | ||
|
|
||
| type DistTagDependency = Parameters<typeof checkDistTag>[0] | ||
| type DistTagPackageInfo = Parameters<typeof checkDistTag>[1] | ||
|
|
||
| function createDependency(name: string, version: string): DistTagDependency { | ||
| return { | ||
| name, | ||
| version, | ||
| nameNode: {}, | ||
| versionNode: {}, | ||
| } | ||
| } | ||
|
|
||
| function createPackageInfo(distTags: Record<string, string>): DistTagPackageInfo { | ||
| return { distTags } as DistTagPackageInfo | ||
| } | ||
|
|
||
| describe('checkDistTag', () => { | ||
| it('should flag "latest" as a dist tag', async () => { | ||
| const dependency = createDependency('lodash', 'latest') | ||
| const packageInfo = createPackageInfo({ latest: '2.0.0' }) | ||
|
|
||
| const result = await checkDistTag(dependency, packageInfo) | ||
|
|
||
| expect(result).toBeDefined() | ||
| }) | ||
|
|
||
| it('should flag "next" as a dist tag', async () => { | ||
| const dependency = createDependency('vue', 'next') | ||
| const packageInfo = createPackageInfo({ latest: '2.0.0', next: '3.0.0-beta' }) | ||
|
|
||
| const result = await checkDistTag(dependency, packageInfo) | ||
|
|
||
| expect(result).toBeDefined() | ||
| }) | ||
|
|
||
| it('should flag common dist tags even when metadata does not include them', async () => { | ||
| const distTagNames = ['next', 'beta', 'canary', 'stable'] | ||
|
|
||
| for (const distTagName of distTagNames) { | ||
| const dependency = createDependency('lodash', distTagName) | ||
| const packageInfo = createPackageInfo({}) | ||
| const result = await checkDistTag(dependency, packageInfo) | ||
|
|
||
| expect(result).toBeDefined() | ||
| } | ||
| }) | ||
|
|
||
| it('should flag "npm:latest" as a dist tag', async () => { | ||
| const dependency = createDependency('lodash', 'npm:latest') | ||
| const packageInfo = createPackageInfo({ latest: '2.0.0' }) | ||
|
|
||
| const result = await checkDistTag(dependency, packageInfo) | ||
|
|
||
| expect(result).toBeDefined() | ||
| }) | ||
|
|
||
| it('should not flag pinned semver', async () => { | ||
| const dependency = createDependency('lodash', '1.0.0') | ||
| const packageInfo = createPackageInfo({ latest: '2.0.0' }) | ||
|
|
||
| const result = await checkDistTag(dependency, packageInfo) | ||
|
|
||
| expect(result).toBeUndefined() | ||
| }) | ||
|
|
||
| it('should not flag unknown tag-like versions', async () => { | ||
| const dependency = createDependency('lodash', 'edge-channel') | ||
| const packageInfo = createPackageInfo({}) | ||
|
|
||
| const result = await checkDistTag(dependency, packageInfo) | ||
|
|
||
| expect(result).toBeUndefined() | ||
| }) | ||
|
|
||
| it('should not flag non-common tags when package metadata does not include them', async () => { | ||
| const dependency = createDependency('lodash', 'preview') | ||
| const packageInfo = createPackageInfo({ latest: '1.0.0' }) | ||
|
|
||
| const result = await checkDistTag(dependency, packageInfo) | ||
|
|
||
| expect(result).toBeUndefined() | ||
| }) | ||
|
|
||
| it('should not flag workspace packages', async () => { | ||
| const dependency = createDependency('lodash', 'workspace:*') | ||
| const packageInfo = createPackageInfo({ latest: '1.0.0' }) | ||
|
|
||
| const result = await checkDistTag(dependency, packageInfo) | ||
|
|
||
| expect(result).toBeUndefined() | ||
| }) | ||
|
|
||
| it('should not flag URL-based version', async () => { | ||
| const dependency = createDependency('lodash', 'https://github.com/user/repo') | ||
| const packageInfo = createPackageInfo({ latest: '1.0.0' }) | ||
|
|
||
| const result = await checkDistTag(dependency, packageInfo) | ||
|
|
||
| expect(result).toBeUndefined() | ||
| }) | ||
| }) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,18 +1,18 @@ | ||
| import { join } from 'node:path' | ||
| import { fileURLToPath } from 'node:url' | ||
| import tsconfigPaths from 'vite-tsconfig-paths' | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We could put the vite-tsconfig-paths change in its own PR. |
||
| import { defineConfig } from 'vitest/config' | ||
|
|
||
| const rootDir = fileURLToPath(new URL('.', import.meta.url)) | ||
|
|
||
| export default defineConfig({ | ||
| test: { | ||
| plugins: [tsconfigPaths()], | ||
| resolve: { | ||
| alias: { | ||
| '#constants': join(rootDir, '/src/constants.ts'), | ||
| '#state': join(rootDir, '/src/state.ts'), | ||
| '#types/*': join(rootDir, '/src/types/*'), | ||
| '#utils/*': join(rootDir, '/src/utils/*'), | ||
| 'vscode': join(rootDir, '/tests/__mocks__/vscode.ts'), | ||
| vscode: join(rootDir, '/tests/__mocks__/vscode.ts'), | ||
| }, | ||
| }, | ||
| test: { | ||
| include: ['tests/**/*.test.ts'], | ||
| }, | ||
| }) | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we check for
COMMON_DIST_TAGS? I might be missing some specific use cases here.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In pretty much every project I've worked on before, using a dist tag for a version was considered bad practice because it can lead to all sorts of problems (stale installations, keeping track of changes in deps, package updates breaking apps, etc.). It would be nice to get a warning about this, because a lot of boilerplate/starter apps use dist tags in their package.json (for example when setting up a project with
pnpm create).This might not be the general expectation or experience shared by other developers, and I'm curious what your opinion on this is. I think having the option for a warning would be nice, and I'm fine with it being off by default :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I totally agree that using dist‑tags for version pinning is not a good practice.
Just curious why do we check for
isCommonDistTagrather than warning on any dist‑tag?