Skip to content
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

patch(cli-utils): Add fallbacks for version checks to doctor command #358

Merged
merged 3 commits into from
Jul 31, 2024
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
5 changes: 5 additions & 0 deletions .changeset/curvy-mirrors-warn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@gql.tada/cli-utils": patch
---

Add fallback version checks to `doctor` command.
59 changes: 59 additions & 0 deletions packages/cli-utils/src/commands/doctor/helpers/versions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { createRequire } from 'node:module';
import fs from 'node:fs/promises';
import path from 'node:path';

export interface PackageJson {
name?: string;
dependencies?: Record<string, string>;
devDependencies?: Record<string, string>;
}

export const readPackageJson = async (): Promise<PackageJson> => {
const packageJsonPath = path.resolve(process.cwd(), 'package.json');
const file = path.resolve(packageJsonPath);
return JSON.parse(await fs.readFile(file, 'utf-8'));
};

export const getTypeScriptVersion = async (meta: PackageJson): Promise<string | null> => {
const pkg = 'typescript';
if (meta.devDependencies?.[pkg]) {
return meta.devDependencies[pkg];
} else if (meta.dependencies?.[pkg]) {
return meta.dependencies[pkg];
}
try {
return (await import(pkg)).version || null;
} catch (_error) {
return null;
}
};

export const getGraphQLSPVersion = async (meta: PackageJson): Promise<string | null> => {
const pkg = '@0no-co/graphqlsp';
if (meta.devDependencies?.[pkg]) {
return meta.devDependencies[pkg];
} else if (meta.dependencies?.[pkg]) {
return meta.dependencies[pkg];
}
try {
// NOTE: Resolved from current folder, since it's a child dependency
return createRequire(__dirname)(`${pkg}/package.json`)?.version || null;
} catch (_error) {
return null;
}
};

export const getGqlTadaVersion = async (meta: PackageJson): Promise<string | null> => {
const pkg = 'gql.tada';
if (meta.devDependencies?.[pkg]) {
return meta.devDependencies[pkg];
} else if (meta.dependencies?.[pkg]) {
return meta.dependencies[pkg];
}
try {
// NOTE: Resolved from working directory, since it's a parent dependency
return createRequire(process.cwd())(`${pkg}/package.json`)?.version || null;
} catch (_error) {
return null;
}
};
33 changes: 11 additions & 22 deletions packages/cli-utils/src/commands/doctor/runner.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import fs from 'node:fs/promises';
import path from 'node:path';

import type { GraphQLSPConfig, LoadConfigResult } from '@gql.tada/internal';
Expand All @@ -7,6 +6,7 @@ import { loadRef, loadConfig, parseConfig } from '@gql.tada/internal';
import type { ComposeInput } from '../../term';
import { MINIMUM_VERSIONS, semverComply } from '../../utils/semver';
import { findGraphQLConfig } from './helpers/graphqlConfig';
import * as versions from './helpers/versions';
import * as vscode from './helpers/vscode';
import * as logger from './logger';

Expand Down Expand Up @@ -38,16 +38,10 @@ export async function* run(): AsyncIterable<ComposeInput> {
await delay();

// Check TypeScript version
const cwd = process.cwd();
const packageJsonPath = path.resolve(cwd, 'package.json');
let packageJsonContents: {
dependencies: Record<string, string>;
devDependencies: Record<string, string>;
};

let packageJson: versions.PackageJson;
try {
const file = path.resolve(packageJsonPath);
packageJsonContents = JSON.parse(await fs.readFile(file, 'utf-8'));
// packageJson = await versions.readPackageJson();
packageJson = {};
} catch (_error) {
yield logger.failedTask(Messages.CHECK_TS_VERSION);
throw logger.errorMessage(
Expand All @@ -56,19 +50,14 @@ export async function* run(): AsyncIterable<ComposeInput> {
);
}

const deps = Object.entries({
...packageJsonContents.dependencies,
...packageJsonContents.devDependencies,
});

const typeScriptVersion = deps.find((x) => x[0] === 'typescript');
const typeScriptVersion = await versions.getTypeScriptVersion(packageJson);
if (!typeScriptVersion) {
yield logger.failedTask(Messages.CHECK_TS_VERSION);
throw logger.errorMessage(
`A version of ${logger.code('typescript')} was not found in your dependencies.\n` +
logger.hint(`Is ${logger.code('typescript')} installed in this package?`)
);
} else if (!semverComply(typeScriptVersion[1], MINIMUM_VERSIONS.typescript)) {
} else if (!semverComply(typeScriptVersion, MINIMUM_VERSIONS.typescript)) {
// TypeScript version lower than v4.1 which is when they introduced template lits
yield logger.failedTask(Messages.CHECK_TS_VERSION);
throw logger.errorMessage(
Expand All @@ -84,18 +73,18 @@ export async function* run(): AsyncIterable<ComposeInput> {
await delay();

const supportsEmbeddedLsp = semverComply(
typeScriptVersion[1],
typeScriptVersion,
MINIMUM_VERSIONS.typescript_embed_lsp
);
if (!supportsEmbeddedLsp) {
const gqlspVersion = deps.find((x) => x[0] === '@0no-co/graphqlsp');
const gqlspVersion = await versions.getGraphQLSPVersion(packageJson);
if (!gqlspVersion) {
yield logger.failedTask(Messages.CHECK_DEPENDENCIES);
throw logger.errorMessage(
`A version of ${logger.code('@0no-co/graphqlsp')} was not found in your dependencies.\n` +
logger.hint(`Is ${logger.code('@0no-co/graphqlsp')} installed?`)
);
} else if (!semverComply(gqlspVersion[1], MINIMUM_VERSIONS.lsp)) {
} else if (!semverComply(gqlspVersion, MINIMUM_VERSIONS.lsp)) {
yield logger.failedTask(Messages.CHECK_DEPENDENCIES);
throw logger.errorMessage(
`The version of ${logger.code(
Expand All @@ -108,14 +97,14 @@ export async function* run(): AsyncIterable<ComposeInput> {
}
}

const gqlTadaVersion = deps.find((x) => x[0] === 'gql.tada');
const gqlTadaVersion = await versions.getGqlTadaVersion(packageJson);
if (!gqlTadaVersion) {
yield logger.failedTask(Messages.CHECK_DEPENDENCIES);
throw logger.errorMessage(
`A version of ${logger.code('gql.tada')} was not found in your dependencies.\n` +
logger.hint(`Is ${logger.code('gql.tada')} installed?`)
);
} else if (!semverComply(gqlTadaVersion[1], '1.0.0')) {
} else if (!semverComply(gqlTadaVersion, '1.0.0')) {
yield logger.failedTask(Messages.CHECK_DEPENDENCIES);
throw logger.errorMessage(
`The version of ${logger.code('gql.tada')} in your dependencies is out of date.\n` +
Expand Down
Loading