Skip to content

Commit

Permalink
refactor(env): read CWD from env
Browse files Browse the repository at this point in the history
  • Loading branch information
JamieMason committed Aug 21, 2023
1 parent 0608605 commit 0b604c8
Show file tree
Hide file tree
Showing 28 changed files with 157 additions and 146 deletions.
4 changes: 2 additions & 2 deletions src/bin-fix-mismatches/effects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,8 @@ function logNonSemverMismatch({ ctx, report }: Input<VersionGroupReport.NonSemve

/** Remove empty objects such as `{"dependencies": {}}` left after deleting */
function deleteEmptyObjects(ctx: Ctx) {
ctx.packageJsonFiles.forEach((packageJsonFile) => {
const contents = packageJsonFile.contents;
ctx.packageJsonFiles.forEach((file) => {
const contents = file.jsonFile.contents;
Object.keys(contents).forEach((key) => {
const value = contents[key];
if (isObject(value) && Object.values(value).every(isUndefined)) {
Expand Down
4 changes: 2 additions & 2 deletions src/bin-format/format.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ export function format(ctx: Ctx): Effect.Effect<never, never, Ctx> {
const sortAz = getSortAz(ctx.config);
const sortFirst = getSortFirst(ctx.config);

packageJsonFiles.forEach((packageJsonFile) => {
const { contents } = packageJsonFile;
packageJsonFiles.forEach((file) => {
const { contents } = file.jsonFile;
const sortedKeys = Object.keys(contents).sort();
const keys = new Set<string>(sortFirst.concat(sortedKeys));

Expand Down
2 changes: 1 addition & 1 deletion src/bin-lint-semver-ranges/effects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ function logRangeMismatch({ report, ctx }: Input<SemverGroupReport.FixableCases>
ICON.rightArrow,
report.expectedVersion,
report.instance.strategy.path,
report.instance.packageJsonFile.shortPath,
report.instance.packageJsonFile.jsonFile.shortPath,
);
}

Expand Down
16 changes: 8 additions & 8 deletions src/bin-list-mismatches/effects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ function logBanned({ report, ctx }: Input<VersionGroupReport.Banned>) {
chalk` {red %s} {dim in %s of %s}`,
instance.specifier,
instance.strategy.path,
instance.packageJsonFile.shortPath,
instance.packageJsonFile.jsonFile.shortPath,
);
});
}
Expand All @@ -84,7 +84,7 @@ function logHighLowSemverMismatch({
chalk` {red %s} {dim in %s of %s}`,
instance.specifier,
instance.strategy.path,
instance.packageJsonFile.shortPath,
instance.packageJsonFile.jsonFile.shortPath,
);
}
});
Expand All @@ -104,7 +104,7 @@ function logPinnedMismatch({ report, ctx }: Input<VersionGroupReport.PinnedMisma
chalk` {red %s} {dim in %s of %s}`,
instance.specifier,
instance.strategy.path,
instance.packageJsonFile.shortPath,
instance.packageJsonFile.jsonFile.shortPath,
);
}
});
Expand All @@ -125,7 +125,7 @@ function logSnappedToMismatch({ report, ctx }: Input<VersionGroupReport.SnappedT
chalk` {red %s} {dim in %s of %s}`,
instance.specifier,
instance.strategy.path,
instance.packageJsonFile.shortPath,
instance.packageJsonFile.jsonFile.shortPath,
);
}
});
Expand All @@ -144,7 +144,7 @@ function logSameRangeMismatch({ report, ctx }: Input<VersionGroupReport.SameRang
chalk` {yellow %s} {dim in %s of %s}`,
instance.specifier,
instance.strategy.path,
instance.packageJsonFile.shortPath,
instance.packageJsonFile.jsonFile.shortPath,
);
});
}
Expand All @@ -162,7 +162,7 @@ function logNonSemverMismatch({ report, ctx }: Input<VersionGroupReport.NonSemve
chalk` {yellow %s} {dim in %s of %s}`,
instance.specifier,
instance.strategy.path,
instance.packageJsonFile.shortPath,
instance.packageJsonFile.jsonFile.shortPath,
);
});
}
Expand All @@ -174,15 +174,15 @@ function logLocalPackageMismatch({ report, ctx }: Input<VersionGroupReport.Local
ICON.cross,
report.name,
report.expectedVersion,
report.localPackageInstance.packageJsonFile.shortPath,
report.localPackageInstance.packageJsonFile.jsonFile.shortPath,
);
report.instances.forEach((instance) => {
if (instance.specifier !== report.expectedVersion) {
console.log(
chalk` {red %s} {dim in %s of %s}`,
instance.specifier,
instance.strategy.path,
instance.packageJsonFile.shortPath,
instance.packageJsonFile.jsonFile.shortPath,
);
}
});
Expand Down
33 changes: 33 additions & 0 deletions src/env/create-env.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
import { pipe } from '@effect/data/Function';
import * as Effect from '@effect/io/Effect';
import { dirname, relative } from 'path';
import type { O } from 'ts-toolbelt';
import type { RcConfig } from '../config/types';
import type { DefaultEnv } from './default-env';
import type { JsonFile } from './tags';
import {
AskForChoiceError,
AskForInputError,
GlobError,
JsonParseError,
ReadConfigFileError,
ReadFileError,
ReadYamlFileError,
Expand All @@ -20,12 +24,16 @@ export interface Env {
readonly askForInput: (opts: {
message: string;
}) => Effect.Effect<never, AskForInputError, string>;
readonly CWD: string;
readonly exitProcess: (code: number) => Effect.Effect<never, never, void>;
readonly globSync: (patterns: string[]) => Effect.Effect<never, GlobError, string[]>;
readonly readConfigFileSync: (
configPath?: string,
) => Effect.Effect<never, ReadConfigFileError, O.Partial<RcConfig, 'deep'>>;
readonly readFileSync: (filePath: string) => Effect.Effect<never, ReadFileError, string>;
readonly readJsonFileSync: <T>(
filePath: string,
) => Effect.Effect<never, ReadFileError | JsonParseError, JsonFile<T>>;
readonly readYamlFileSync: <T = unknown>(
filePath: string,
) => Effect.Effect<never, ReadYamlFileError, T>;
Expand Down Expand Up @@ -55,6 +63,7 @@ export function createEnv(env: DefaultEnv): Env {
env.exitProcess(code);
});
},
CWD: env.CWD,
globSync(patterns) {
return Effect.try({
try: () => env.globSync(patterns),
Expand All @@ -73,6 +82,30 @@ export function createEnv(env: DefaultEnv): Env {
catch: (err) => new ReadFileError({ filePath, error: String(err) }),
});
},
readJsonFileSync(filePath) {
return pipe(
Effect.Do,
Effect.bind('json', () =>
Effect.try({
try: () => env.readFileSync(filePath),
catch: (err) => new ReadFileError({ filePath, error: String(err) }),
}),
),
Effect.bind('contents', ({ json }) =>
Effect.try({
try: () => JSON.parse(json),
catch: (err) => new JsonParseError({ error: String(err), filePath, json }),
}),
),
Effect.map(({ contents, json }) => ({
contents,
dirPath: dirname(filePath),
filePath,
json,
shortPath: relative(env.CWD, filePath),
})),
);
},
readYamlFileSync(filePath) {
return Effect.try({
try: () => env.readYamlFileSync(filePath),
Expand Down
21 changes: 8 additions & 13 deletions src/env/default-env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { logVerbose } from '../lib/log-verbose';
export interface DefaultEnv {
readonly askForChoice: (opts: { message: string; choices: string[] }) => Promise<string>;
readonly askForInput: (opts: { message: string }) => Promise<string>;
readonly CWD: string;
readonly exitProcess: (code: number) => void;
readonly globSync: (patterns: string[]) => string[];
readonly readConfigFileSync: (configPath?: string) => O.Partial<RcConfig, 'deep'>;
Expand All @@ -29,7 +30,6 @@ export interface DefaultEnv {
}

export const defaultEnv: DefaultEnv = {
/* istanbul ignore next */
askForChoice({ message, choices }) {
return prompt({
type: 'select',
Expand All @@ -38,34 +38,32 @@ export const defaultEnv: DefaultEnv = {
choices,
});
},
/* istanbul ignore next */
askForInput({ message }) {
return prompt({
name: 'version',
type: 'input',
message,
});
},
/* istanbul ignore next */
CWD,
exitProcess(code) {
logVerbose('exit(', code, ')');
process.exit(code);
},
globSync(patterns) {
logVerbose('globSync(', patterns, ')');
return globby.sync(patterns, {
ignore: ['**/node_modules/**'],
absolute: true,
cwd: CWD,
cwd: defaultEnv.CWD,
});
},
/* istanbul ignore next */
exitProcess(code) {
logVerbose('exit(', code, ')');
process.exit(code);
},
readConfigFileSync(configPath) {
logVerbose('readConfigFileSync(', configPath, ')');
const client = cosmiconfigSync('syncpack');
const result = configPath ? client.load(configPath) : client.search();
if (!isNonEmptyObject(result)) {
const rcPath = join(CWD, 'package.json');
const rcPath = join(defaultEnv.CWD, 'package.json');
return pipe(
fromTry(() => readFileSync(rcPath, { encoding: 'utf8' })),
map(JSON.parse),
Expand All @@ -84,17 +82,14 @@ export const defaultEnv: DefaultEnv = {
logVerbose('.syncpackrc contents:', rcConfig);
return rcConfig;
},
/* istanbul ignore next */
readFileSync(filePath) {
logVerbose('readFileSync(', filePath, ')');
return readFileSync(filePath, { encoding: 'utf8' });
},
/* istanbul ignore next */
readYamlFileSync<T = unknown>(filePath: string): T {
logVerbose('readYamlFileSync(', filePath, ')');
return readYamlFile.sync<T>(filePath);
},
/* istanbul ignore next */
writeFileSync(filePath, contents) {
logVerbose('writeFileSync(', filePath, contents, ')');
writeFileSync(filePath, contents);
Expand Down
19 changes: 19 additions & 0 deletions src/env/tags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,22 @@ export class WriteFileError extends Data.TaggedClass('WriteFileError')<{
readonly filePath: string;
readonly error: string;
}> {}

export interface JsonFile<T> {
/** absolute path on disk to the directory of this file */
readonly dirPath: string;
/** absolute path on disk to this file */
readonly filePath: string;
/** relative path on disk to this file */
readonly shortPath: string;
/** parsed JSON contents of the file */
contents: T;
/** raw file contents of the file */
readonly json: string;
}

export class JsonParseError extends Data.TaggedClass('JsonParseError')<{
readonly error: string;
readonly filePath: string;
readonly json: string;
}> {}
14 changes: 8 additions & 6 deletions src/env/write-if-changed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,21 @@ export function writeIfChanged(ctx: Ctx): Effect.Effect<Env, WriteFileError, Ctx
pipe(
Effect.Do,
Effect.bind('nextJson', () => toJson(file)),
Effect.bind('hasChanged', ({ nextJson }) => Effect.succeed(file.json !== nextJson)),
Effect.bind('hasChanged', ({ nextJson }) =>
Effect.succeed(file.jsonFile.json !== nextJson),
),
Effect.flatMap(({ hasChanged, nextJson }) =>
hasChanged
? pipe(
env.writeFileSync(file.filePath, nextJson),
env.writeFileSync(file.jsonFile.filePath, nextJson),
Effect.flatMap(() =>
Effect.sync(() => {
console.log(chalk`{green ${ICON.tick}}`, file.shortPath);
console.log(chalk`{green ${ICON.tick}}`, file.jsonFile.shortPath);
}),
),
)
: Effect.sync(() => {
console.log(chalk.dim(ICON.skip), chalk.dim(file.shortPath));
console.log(chalk.dim(ICON.skip), chalk.dim(file.jsonFile.shortPath));
}),
),
),
Expand All @@ -42,9 +44,9 @@ export function writeIfChanged(ctx: Ctx): Effect.Effect<Env, WriteFileError, Ctx
);

function toJson(file: PackageJsonFile): Effect.Effect<never, never, string> {
const contents = file.contents;
const contents = file.jsonFile.contents;
const indent = getIndent(ctx.config);
const EOL = newlines.detect(file.json);
const EOL = newlines.detect(file.jsonFile.json);
const source = `${JSON.stringify(contents, null, indent)}${EOL}`;
return Effect.succeed(newlines.fix(source, EOL));
}
Expand Down
9 changes: 7 additions & 2 deletions src/error-handlers/create-error-handlers.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
import * as Effect from '@effect/io/Effect';
import type { DeprecatedTypesError, RenamedWorkspaceTypeError } from '../config/get-enabled-types';
import type { GlobError, ReadConfigFileError, ReadFileError, WriteFileError } from '../env/tags';
import type {
GlobError,
JsonParseError,
ReadConfigFileError,
ReadFileError,
WriteFileError,
} from '../env/tags';
import type { NoSourcesFoundError } from '../get-package-json-files/get-file-paths';
import type { JsonParseError } from '../get-package-json-files/get-patterns/read-json-safe';
import type { SemverGroupConfigError } from '../get-semver-groups';
import type { VersionGroupConfigError } from '../get-version-groups';

Expand Down
12 changes: 7 additions & 5 deletions src/get-context/get-context.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,14 @@ describe('getContext', () => {
expect.objectContaining({
packageJsonFiles: [
{
contents,
dirPath: CWD,
filePath,
json,
config: expect.toBeNonEmptyObject(),
shortPath: 'package.json',
jsonFile: {
contents,
dirPath: CWD,
filePath,
json,
shortPath: 'package.json',
},
},
],
}),
Expand Down
3 changes: 1 addition & 2 deletions src/get-context/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,10 @@ import type { O } from 'ts-toolbelt';
import { CliConfigTag } from '../config/tag';
import { type CliConfig, type RcConfig } from '../config/types';
import type { Env } from '../env/create-env';
import type { GlobError, ReadConfigFileError, ReadFileError } from '../env/tags';
import type { GlobError, JsonParseError, ReadConfigFileError, ReadFileError } from '../env/tags';
import { EnvTag } from '../env/tags';
import { getPackageJsonFiles } from '../get-package-json-files';
import type { NoSourcesFoundError } from '../get-package-json-files/get-file-paths';
import type { JsonParseError } from '../get-package-json-files/get-patterns/read-json-safe';
import type { PackageJsonFile } from '../get-package-json-files/package-json-file';

export interface Ctx {
Expand Down

0 comments on commit 0b604c8

Please sign in to comment.