Skip to content

Commit

Permalink
Remove the need for "entrypoints" in elm-tooling.json (#629)
Browse files Browse the repository at this point in the history
Co-authored-by: lydell <[email protected]>
  • Loading branch information
lydell and lydell authored Sep 27, 2021
1 parent 0fa8698 commit b22398b
Show file tree
Hide file tree
Showing 10 changed files with 275 additions and 184 deletions.
20 changes: 3 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,25 +94,11 @@ Or use local versions from your `node_modules` directory, if you want to do that

## Configuration

Create an [elm-tooling.json](https://elm-tooling.github.io/elm-tooling-cli/spec) file next to your `elm.json` to configure the language server.
We used to have a file called `elm-tooling.json` where you could specifiy `"entrypoints"`. That’s not needed anymore – the language server finds the entrypoints automatically.

Currently there’s just one thing that you can configure: entrypoints. The language server runs `elm make` to get type errors. By default `elm make` is run on the current file only. To get errors for the entire project you can specify your entrypoint files – basically, those with `main =` in them. Then the language server will run `elm make` on those instead.
If all you had in `elm-tooling.json` was `"entrypoints"`, you can safely remove that file.

Example `elm-tooling.json`:

```json
{
"entrypoints": ["./src/Main.elm"]
}
```

The entrypoints are relative to the directory where your `elm.json` and `elm-tooling.json` is and must start with `./`.

Check out the [elm-tooling](https://elm-tooling.github.io/elm-tooling-cli/) CLI for creating and validating your `elm-tooling.json`! You can run it without installing:

```
npx elm-tooling init
```
Currently, no configuration at all is needed.

## Features

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"out"
],
"engines": {
"node": ">=12.0.0"
"node": ">=12.9.0"
},
"repository": {
"type": "git",
Expand Down
4 changes: 4 additions & 0 deletions src/compiler/forest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export interface ISourceFile {
tree: Tree;
project: ElmProject; // The project this source file is associated with
isTestFile: boolean;
isDependency: boolean;

parseDiagnostics: Diagnostic[];
bindDiagnostics: Diagnostic[];
Expand All @@ -38,6 +39,7 @@ export interface IForest {
referenced: boolean,
tree: Tree,
isTestFile: boolean,
isDependency: boolean,
project?: ElmProject,
packageName?: string,
): ISourceFile;
Expand Down Expand Up @@ -65,6 +67,7 @@ export class Forest implements IForest {
referenced: boolean,
tree: Tree,
isTestFile: boolean,
isDependency: boolean,
project: ElmProject = this.rootProject,
maintainerAndPackageName?: string,
): ISourceFile {
Expand All @@ -78,6 +81,7 @@ export class Forest implements IForest {
writeable,
project,
isTestFile,
isDependency,
parseDiagnostics: [],
bindDiagnostics: [],
};
Expand Down
9 changes: 9 additions & 0 deletions src/compiler/program.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ interface IElmFile {
maintainerAndPackageName?: string;
project: ElmProject;
isTestFile: boolean;
isDependency: boolean;
}

export type ElmJson = IElmApplicationJson | IElmPackageJson;
Expand Down Expand Up @@ -133,6 +134,7 @@ interface IElmPackage extends IElmProject {
type: "package";
maintainerAndPackageName: string;
exposedModules: Set<string>;
isDependency: boolean;
}

export interface IProgramHost {
Expand Down Expand Up @@ -496,6 +498,7 @@ export class Program implements IProgram {
moduleToUriMap: new Map<string, string>(),
maintainerAndPackageName: elmJson.name,
testModuleToUriMap: new Map<string, string>(),
isDependency: false,
} as IElmPackage;
}
}
Expand Down Expand Up @@ -545,6 +548,7 @@ export class Program implements IProgram {
moduleToUriMap: new Map<string, string>(),
maintainerAndPackageName: elmJson.name,
testModuleToUriMap: new Map<string, string>(),
isDependency: true,
} as IElmPackage;

this.resolvedPackageCache.set(cacheKey, resolvedPackage);
Expand Down Expand Up @@ -618,6 +622,9 @@ export class Program implements IProgram {
const maintainerAndPackageName =
project.type === "package" ? project.maintainerAndPackageName : undefined;

const isDependency =
project.type === "package" ? project.isDependency : false;

this.connection.console.info(`Glob ${sourceDir}/**/*.elm`);

(await this.host.readDirectory(sourceDir)).forEach((matchingPath) => {
Expand Down Expand Up @@ -645,6 +652,7 @@ export class Program implements IProgram {
path: matchingPath,
project,
isTestFile,
isDependency,
});
});

Expand Down Expand Up @@ -684,6 +692,7 @@ export class Program implements IProgram {
true,
tree,
filePath.isTestFile,
filePath.isDependency,
filePath.project,
filePath.maintainerAndPackageName,
);
Expand Down
60 changes: 54 additions & 6 deletions src/compiler/utils/elmUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,14 @@ import { URI } from "vscode-uri";
import { IElmPackageCache } from "../elmPackageCache";
import { IClientSettings } from "../../util/settings";
import { ElmProject } from "../program";
import { NonEmptyArray } from "../../util/utils";

export const isWindows = process.platform === "win32";

/** Options for execCmdSync */
export interface IExecCmdOptions {
export interface IExecCmdSyncOptions {
/** Any arguments */
cmdArguments?: string[];
/** Shows a message if an error occurs (in particular the command not being */
/* found), instead of rejecting. If this happens, the promise never resolves */
showMessageOnError?: boolean;
/** Text to add when command is not found (maybe helping how to install) */
notFoundText?: string;
}
Expand All @@ -23,7 +21,7 @@ export interface IExecCmdOptions {
export function execCmdSync(
cmdFromUser: string,
cmdStatic: string,
options: IExecCmdOptions = {},
options: IExecCmdSyncOptions = {},
cwd: string,
connection: Connection,
input?: string,
Expand All @@ -42,7 +40,7 @@ export function execCmdSync(
});
} catch (error: any) {
connection.console.warn(JSON.stringify(error));
if (error.code && error.code === "ENOENT") {
if (error.code === "ENOENT") {
connection.window.showErrorMessage(
options.notFoundText
? options.notFoundText + ` I'm looking for '${cmd}' at '${cwd}'`
Expand All @@ -55,6 +53,56 @@ export function execCmdSync(
}
}

/** Options for execCmd */
export interface IExecCmdOptions {
/** Text to add when command is not found (maybe helping how to install)
* Unlike the sync version, it’s required here (since `cmdStatic` has fallbacks).
*/
notFoundText: string;
}

export async function execCmd(
cmdFromUser: [string, string[]],
cmdStatic: NonEmptyArray<[string, string[]]>,
options: IExecCmdOptions,
cwd: string,
connection: Connection,
input?: string,
): Promise<ExecaSyncReturnValue<string>> {
const [cmd, args] = cmdFromUser[0] === "" ? cmdStatic[0] : cmdFromUser;
const preferLocal = cmdFromUser[0] === "";

try {
return await execa(cmd, args, {
cwd,
input,
preferLocal,
stripFinalNewline: false,
});
} catch (error) {
const notFound = error.code === "ENOENT";
if (notFound && cmdStatic.length > 1) {
return execCmd(
cmdFromUser,
cmdStatic.slice(1) as NonEmptyArray<[string, string[]]>,
options,
cwd,
connection,
input,
);
}
connection.console.warn(JSON.stringify(error));
if (notFound) {
connection.window.showErrorMessage(
options.notFoundText + ` I'm looking for commands at '${cwd}'`,
);
throw "Executable not found";
} else {
throw error;
}
}
}

// Special type that has no core mock https://github.com/elm/compiler/blob/51e20357137ebc9c3f6136cf0a3fe21c24027f39/compiler/src/Canonicalize/Environment/Foreign.hs#L62
export function getEmptyTypes(): {
markdown: string;
Expand Down
84 changes: 0 additions & 84 deletions src/elmToolingJsonManager.ts

This file was deleted.

5 changes: 5 additions & 0 deletions src/providers/astProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -174,12 +174,17 @@ export class ASTProvider {
.getSourceDirectoryOfFile(document.uri)
?.endsWith("tests") ?? false;

const isDependency = params.sourceFile
? params.sourceFile.isDependency
: false;

const sourceFile = forest.setTree(
pendingRenameUri ?? document.uri,
true,
true,
tree,
isTestFile,
isDependency,
);

// The program now needs to be synchronized
Expand Down
Loading

0 comments on commit b22398b

Please sign in to comment.