Skip to content
Open
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
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

## [Unreleased]

- Fixed `~` not being resolved to the home folder when used in CLI flags, such as `--config=~/some/path` (`--config ~/some/path` worked correctly).
This was an issue for `--config`, `--ignore-dirs`, `--ignore-files`, `--elmjson`, `--compiler` and `--elm-format-path`.

## [2.13.5] - 2025-12-30

- Added `--elmjson` and `--config` to the help text for `prepare-offline`.
Expand Down
32 changes: 25 additions & 7 deletions lib/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,10 @@ async function cachedBuild(

const reviewElmJsonHash = hashElement(reviewElmJsonPath, {algo: 'md5'});

const localElmReviewSourceHashes = options.localElmReviewSrc
const localElmReviewSourceHashes = options.localElmReview
? [
hashElement(path.resolve(userSrc, options.localElmReviewSrc), {
folders: {exclude: ['.*', 'elm-stuff']},
hashElement(path.resolve(userSrc, options.localElmReview), {
folders: {exclude: ['.*', 'elm-stuff', 'node_modules']},
files: {include: ['*.elm']},
algo: 'md5'
})
Expand Down Expand Up @@ -178,6 +178,7 @@ please use ${chalk.greenBright('--config some/path/to/review')}`,

const cleanupSymlink = createSymLinkForLocalElmReview(
options,
buildFolder,
reviewElmJson
);

Expand Down Expand Up @@ -224,11 +225,12 @@ please use ${chalk.greenBright('--config some/path/to/review')}`,
* Build a review application from a local configuration.
*
* @param {Options} options
* @param {Path} buildFolder
* @param {ApplicationElmJson} reviewElmJson
* @returns {() => void}
*/
function createSymLinkForLocalElmReview(options, reviewElmJson) {
if (!options.localElmReviewSrc) {
function createSymLinkForLocalElmReview(options, buildFolder, reviewElmJson) {
if (!options.localElmReview) {
return () => {};
}

Expand All @@ -242,13 +244,24 @@ function createSymLinkForLocalElmReview(options, reviewElmJson) {
version
)
);
// Elm-stuff folder we'd like to delete before and after using LOCAL_ELM_REVIEW
// because the cache may cause using a different version than expected.
const elmStuffForBuild = path.join(buildFolder, 'elm-stuff');
FS.mkdirpSync(path.dirname(packagePath));
try {
fs.rmSync(packagePath, {recursive: true});
} catch {}

try {
fs.symlinkSync(path.dirname(options.localElmReviewSrc), packagePath, 'dir');
fs.rmSync(path.join(options.localElmReview, 'artifacts.dat'));
} catch {}

try {
fs.rmSync(elmStuffForBuild, {recursive: true});
} catch {}

try {
fs.symlinkSync(options.localElmReview, packagePath, 'dir');
} catch {
return () => {};
}
Expand All @@ -257,6 +270,10 @@ function createSymLinkForLocalElmReview(options, reviewElmJson) {
try {
fs.rmSync(packagePath);
} catch {}

try {
fs.rmSync(elmStuffForBuild, {recursive: true});
} catch {}
};
}

Expand Down Expand Up @@ -326,6 +343,7 @@ async function buildFromGitHubTemplate(options, template) {

const cleanupSymlink = createSymLinkForLocalElmReview(
options,
buildFolder,
reviewElmJson
);

Expand Down Expand Up @@ -584,7 +602,7 @@ function compilationError(options, stderr) {
* @returns {void}
*/
function validateElmReviewVersion(options, reviewElmJsonPath, reviewElmJson) {
if (options.localElmReviewSrc) {
if (options.localElmReview) {
return;
}

Expand Down
36 changes: 30 additions & 6 deletions lib/options.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
* @import {Flag, Multi} from './types/flag';
* @import {Options, Subcommand, Template} from './types/options';
*/
const os = require('node:os');
const path = require('node:path');
const chalk = require('chalk');
const levenshtein = require('fastest-levenshtein');
Expand Down Expand Up @@ -85,6 +86,10 @@ function compute(processArgv, cwd) {
const readmePath =
elmJsonPath && path.join(path.dirname(elmJsonPath), 'README.md');

args.config = resolveHomePath(args.config);
args.compiler = resolveHomePath(args.compiler);
const elmFormatPath = resolveHomePath(args['elm-format-path']);

/**
* @returns {Path}
*/
Expand Down Expand Up @@ -184,7 +189,7 @@ try re-running it with ${chalk.cyan('--elmjson <path-to-elm.json>')}.`,

const gitHubPat = parseGitHubAuth(subcommand, args['github-auth']);

const localElmReviewSrc = process.env.LOCAL_ELM_REVIEW_SRC;
const localElmReview = process.env.LOCAL_ELM_REVIEW;

/** @type {string} */
const prefilled = args.prefill;
Expand All @@ -204,6 +209,8 @@ try re-running it with ${chalk.cyan('--elmjson <path-to-elm.json>')}.`,
* @returns {Path}
*/
function absolutePathsToRelative(filePath) {
filePath = resolveHomePath(filePath);

if (path.isAbsolute(filePath)) {
return path.relative(projectToReview(), filePath);
}
Expand Down Expand Up @@ -233,10 +240,10 @@ try re-running it with ${chalk.cyan('--elmjson <path-to-elm.json>')}.`,
subcommand,
namespace,
compiler: args.compiler,
elmFormatPath: args['elm-format-path'],
elmFormatPath,
packageJsonVersion: packageJson.version,
localElmReviewSrc,
forceBuild: args['force-build'] || Boolean(localElmReviewSrc),
localElmReview,
forceBuild: args['force-build'] || Boolean(localElmReview),
offline: args.offline,
report: args.report === 'json' || args.report === 'ndjson' ? 'json' : null,
reportOnOneLine: args.report === 'ndjson',
Expand Down Expand Up @@ -292,7 +299,7 @@ try re-running it with ${chalk.cyan('--elmjson <path-to-elm.json>')}.`,
[
commit,
args.debug ? '-debug' : '',
localElmReviewSrc ? '-local' : ''
localElmReview ? '-local' : ''
].join('') + '.js'
);
},
Expand Down Expand Up @@ -397,7 +404,7 @@ ${Flags.buildFlag(subcommand, Flags.templateFlag)}`
*/
function findElmJsonPath(args, subcommand, cwd) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-return -- Casting is ugly.
if (args.elmjson) return args.elmjson;
if (args.elmjson) return resolveHomePath(args.elmjson);
// Shortcutting the search for elm.json when `--help` since we won't need it
if (args.help) return null;
// Same when a subcommand is used, since we won't need it.
Expand Down Expand Up @@ -676,6 +683,23 @@ ${Flags.buildFlag(subcommand, Flags.gitHubAuthFlag)}`
return split.length === 2 ? split[1] : split[0];
}

/** Replace a leading `~/` by the user's home folder.
* This is necessary because while terminals will replace
* `--xyz ~/path/` by `--xyz /home/user/path/`
* they won't do it when called with `--xyz=~/path/`.
*
* @param {Path | undefined} p
* @returns {Path | undefined | any} Can't figure out how to type this correctly so added `any`
*/
function resolveHomePath(p) {
if (!p) return p;
if (p.startsWith('~/') || p.startsWith('~\\')) {
return path.join(os.homedir(), p.slice(2));
}

return p;
}

/**
* Report error and crash gracefully.
*
Expand Down
2 changes: 1 addition & 1 deletion lib/types/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export type Options = OptionsBase & {
compiler: string | undefined;
elmFormatPath: string | undefined;
packageJsonVersion: string;
localElmReviewSrc: string | undefined;
localElmReview: string | undefined;
forceBuild: boolean;
offline: boolean;
reportOnOneLine: boolean;
Expand Down
Loading
Loading