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

Use deps.clj to launch deps.edn projects on Windows #1004

Merged
merged 5 commits into from
Feb 1, 2021
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
1 change: 1 addition & 0 deletions .vscodeignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@
!CHANGELOG.md
!LICENSE.txt
!clojure-lsp.jar
!deps.clj.jar
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ Changes to Calva.
- [Add command for copying jack-in command to clipboard](https://github.com/BetterThanTomorrow/calva/pull/995)
- [Change default shortcuts for Paredit forward/backward sexp, expand/shrink selection, and for slurping and barfing](https://github.com/BetterThanTomorrow/calva/issues/950)
- [Add Custom Commands variables for current form and more](https://github.com/BetterThanTomorrow/calva/issues/986)
- Fix: [Jack-in fails to launch deps.edn projects for some Windows users](https://github.com/BetterThanTomorrow/calva/issues/1000)

## [2.0.156] - 2021-01-28
- Fix: [Debug instrumentation decoration not working correctly anymore on Windows](https://github.com/BetterThanTomorrow/calva/issues/969)
Expand Down
Binary file added bb.exe
Binary file not shown.
Binary file added deps.clj.jar
Binary file not shown.
12 changes: 6 additions & 6 deletions docs/site/connect-sequences.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ NB: _Connect sequence configuration affects Calva's Jack-in menu in the followin
A connect sequence configures the following:

* `name`: (required) This will show up in the Jack-in quick-pick menu when you start Jack-in (see above).
* `projectType`: (required) This is either "Leiningen”, ”Clojure CLI”, ”shadow-cljs”, ”lein-shadow”, or ”generic".
* `projectType`: (required) This is either "Leiningen”, ”deps.edn”, ”shadow-cljs”, ”lein-shadow”, or ”generic".
* `nReplPortFile`: An array of path segments with the project root-relative path to the nREPL port file for this connect sequence. E.g. For shadow-cljs this would be `[".shadow-cljs", "nrepl.port"]`.
* `afterCLJReplJackInCode`: Here you can give Calva some Clojure code to evaluate in the CLJ REPL, once it has been created.
* `cljsType`: This can be either "Figwheel Main", "lein-figwheel", "shadow-cljs", "Nashorn", "none", or a dictionary configuring a custom type. If set to "none", Calva will skip connecting a ClojureScript repl. A custom type has the following fields:
Expand All @@ -29,7 +29,7 @@ A connect sequence configures the following:
* `menuSelections`: a dictionary with pre-filled-in selections for the Jack-in and Connect prompts, making Calva not prompt for that particular selection:
* `leinProfiles`: At Jack-in to a Leiningen project, use these profiles to launch the repl.
* `leinAlias`: At Jack-in to a Leiningen project, launch with this alias. Set to `null` to launch with Calva's default task (a headless repl), w/o prompting.
* `cljAliases`: At Jack-in to a Clojure CLI project, use these aliases to launch the repl.
* `cljAliases`: At Jack-in to a deps.edn project, use these aliases to launch the repl.
* `cljsLaunchBuilds`: The cljs builds to start/watch at Jack-in/connect.
* `cljsDefaultBuild`: Which cljs build to attach to at the initial connect.

Expand Down Expand Up @@ -65,11 +65,11 @@ Here is an example from the [JUXT Edge](https://juxt.pro/blog/posts/edge.html) p
"calva.replConnectSequences": [
{
"name": "Edge backend only",
"projectType": "Clojure CLI"
"projectType": "deps.edn"
},
{
"name": "Edge backend + frontend",
"projectType": "Clojure CLI",
"projectType": "deps.edn",
"cljsType": {
"dependsOn": "Figwheel Main",
"startCode": "(do (require 'dev-extras) (dev-extras/go) (println \"Edge Figwheel Main started\") ((resolve 'dev-extras/cljs-repl)))",
Expand All @@ -93,14 +93,14 @@ Here is an example from the [JUXT Edge](https://juxt.pro/blog/posts/edge.html) p
}
```

A Clojure CLI sequence that does not promote the ClojureScript repl at all (leaving it a Clojure REPL), and leaves that up to you to do interactively. (Could be useful while you are developing a custom cljs repl.) The example is for when adapting a Figwheel Main repl.
A deps.edn sequence that does not promote the ClojureScript repl at all (leaving it a Clojure REPL), and leaves that up to you to do interactively. (Could be useful while you are developing a custom cljs repl.) The example is for when adapting a Figwheel Main repl.

```json
{
"calva.replConnectSequences": [
{
"name": "Do not promote to cljs",
"projectType": "Clojure CLI",
"projectType": "deps.edn",
"cljsType": {
"dependsOn": "Figwheel Main",
"connectCode": "\"Don't promote me bro!\"",
Expand Down
4 changes: 2 additions & 2 deletions docs/site/connect.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ The recommended way is to:

This way Calva can make sure it is started with the dependencies needed for a working Clojure and/or ClojureScript session. This is often referred to as **Jack in** (because that is what it is called in CIDER).

Jack-in supports both CLJ and for CLJS, and has built-in configurations for **Leiningen**, **Clojure CLI**, and **shadow-cljs** projects, as well as for the CLJS repl types: **Figwheel Main**, **lein-figwheel** (legacy Figwheel), **shadow-cljs**, and Nashorn. Using jack-in provides your development environment with all the dependencies you need for Calva to work.
Jack-in supports both CLJ and for CLJS, and has built-in configurations for **Leiningen**, **deps.edn**, and **shadow-cljs** projects, as well as for the CLJS repl types: **Figwheel Main**, **lein-figwheel** (legacy Figwheel), **shadow-cljs**, and Nashorn. Using jack-in provides your development environment with all the dependencies you need for Calva to work.

It works like so:

Expand All @@ -17,7 +17,7 @@ It works like so:
See also: [Workspace Layouts](workspace-layouts.md)

!!! Note
You must have a project file, such as `project.clj` for Leiningen or `deps.edn` for Clojure CLI, in the directory opened in VS Code in order for jack-in to work. If, after adding the project file, you experience an error during jack-in that says something could not be located, make sure you have the correct dependencies in your project file. For example, when using the **Figwheel Main** project type, you should have `com.bhauman/figwheel-main` in your project dependencies.
You must have a project file, such as `project.clj` for Leiningen or `deps.edn` for deps.edn, in the directory opened in VS Code in order for jack-in to work. If, after adding the project file, you experience an error during jack-in that says something could not be located, make sure you have the correct dependencies in your project file. For example, when using the **Figwheel Main** project type, you should have `com.bhauman/figwheel-main` in your project dependencies.

### Aliases, profiles, builds

Expand Down
2 changes: 1 addition & 1 deletion docs/site/quirks.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ See [Using Calva with the VIM Extension](vim.md).

[Jack-in](jack-in-guide.md) starts by running a command in a new terminal. You will need the commands used installed on your computer:

* `clojure` for tools.deps/Clojure CLI
* `clojure` for tools.deps/deps.edn
* `lein` for Leiningen
* `npx` for shadow-cljs

Expand Down
4 changes: 2 additions & 2 deletions docs/site/rebl.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

[REBL](https://github.com/cognitect-labs/REBL-distro) is a graphical, interactive tool for browsing Clojure data.

## Clojure CLI
## deps.edn

Add the following aliases to your deps.edn file. Use the deps.edn file in the `~/.clojure` directory to enable alias reuse across multiple projects. This is the configuration for REBL on openjdk 12. Check out the [REBL github page](https://github.com/cognitect-labs/REBL-distro) for more info.

Expand Down Expand Up @@ -40,7 +40,7 @@ Create a Calva custom connect sequence for your VSCode editor. (Read [Custom REP
"calva.replConnectSequences": [
{
"name": "Rebl Connect",
"projectType": "Clojure CLI",
"projectType": "deps.edn",
"menuSelections": {
"cljAliases": [
"rebl",
Expand Down
2 changes: 1 addition & 1 deletion docs/site/reveal.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ In your project's `deps.edn` file add a `:reveal` alias:

```

And then jack-in choosing the Clojure CLI option and then pick the `:reveal` alias.
And then jack-in choosing the deps.edn option and then pick the `:reveal` alias.

If you find the font to small you can add a `:jvm-opts` key to make it a little bigger:

Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,7 @@
"description": "Select one of the project types supported by Calva.",
"enum": [
"Leiningen",
"Clojure CLI",
"deps.edn",
"shadow-cljs",
"lein-shadow",
"generic"
Expand Down Expand Up @@ -387,7 +387,7 @@
},
"cljAliases": {
"type": "array",
"description": "At Jack-in to a Clojure CLI project, use these aliases to launch the repl.",
"description": "At Jack-in to a deps.edn project, use these aliases to launch the repl.",
"items": {
"type": "string"
}
Expand Down
25 changes: 14 additions & 11 deletions src/nrepl/connectSequence.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import * as utilities from '../utilities';

enum ProjectTypes {
"Leiningen" = "Leiningen",
"Clojure CLI" = "Clojure CLI",
"deps.edn" = "deps.edn",
"shadow-cljs" = "shadow-cljs",
"lein-shadow" = "lein-shadow",
'generic' = 'generic'
Expand Down Expand Up @@ -80,29 +80,29 @@ const leiningenDefaults: ReplConnectSequence[] =

const cljDefaults: ReplConnectSequence[] =
[{
name: "Clojure CLI",
projectType: ProjectTypes["Clojure CLI"],
name: "deps.edn",
projectType: ProjectTypes["deps.edn"],
cljsType: CljsTypes.none
},
{
name: "Clojure CLI + Figwheel Main",
projectType: ProjectTypes["Clojure CLI"],
name: "deps.edn + Figwheel Main",
projectType: ProjectTypes["deps.edn"],
cljsType: CljsTypes["Figwheel Main"]
},
{
name: "Clojure CLI + shadow-cljs",
projectType: ProjectTypes["Clojure CLI"],
name: "deps.edn + shadow-cljs",
projectType: ProjectTypes["deps.edn"],
cljsType: CljsTypes["shadow-cljs"],
nReplPortFile: [".shadow-cljs", "nrepl.port"]
},
{
name: "Clojure CLI + Legacy Figwheel",
projectType: ProjectTypes["Clojure CLI"],
name: "deps.edn + Legacy Figwheel",
projectType: ProjectTypes["deps.edn"],
cljsType: CljsTypes["lein-figwheel"]
},
{
name: "Clojure CLI + Nashorn",
projectType: ProjectTypes["Clojure CLI"],
name: "deps.edn + Nashorn",
projectType: ProjectTypes["deps.edn"],
cljsType: CljsTypes["Nashorn"]
}];

Expand Down Expand Up @@ -191,6 +191,9 @@ function getCustomConnectSequences(): ReplConnectSequence[] {

return [];
}
if (sequence.projectType as string === 'Clojure CLI') {
sequence.projectType = ProjectTypes['deps.edn'];
}
}

return sequences;
Expand Down
5 changes: 3 additions & 2 deletions src/nrepl/jack-in-terminal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ export interface JackInTerminalOptions extends vscode.TerminalOptions {
env: { [key: string]: string },
executable: string,
args: string[],
isWin: boolean
isWin: boolean,
useShell: boolean
};

export function createCommandLine(executable: string, args: string[]) {
Expand Down Expand Up @@ -67,7 +68,7 @@ export class JackInTerminal implements vscode.Pseudoterminal {
this.process = child.spawn(this.options.executable, this.options.args, {
env: this.options.env,
cwd: this.options.cwd,
shell: !this.options.isWin
shell: this.options.useShell
});
this.process.on('exit', (status) => {
this.writeEmitter.fire(`Jack-in process exited. Status: ${status}\r\n`);
Expand Down
20 changes: 17 additions & 3 deletions src/nrepl/jack-in.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as vscode from "vscode";
import * as path from 'path';
import * as utilities from "../utilities";
import * as _ from "lodash";
import * as state from "../state"
Expand Down Expand Up @@ -136,9 +137,21 @@ async function getJackInTerminalOptions(projectConnectSequence: ReplConnectSeque
}

const projectType = projectTypes.getProjectTypeForName(projectTypeName);
const executable = projectTypes.isWin ? projectType.winCmd : projectType.cmd;
// Ask the project type to build up the command line. This may prompt for further information.
const args = await projectType.commandLine(projectConnectSequence, selectedCljsType);
let executable: string;
let args: string[] = await projectType.commandLine(projectConnectSequence, selectedCljsType);
if (projectTypes.isWin) {
if (projectType.name === 'deps.edn') {
const depsJarPath = path.join(state.extensionContext.extensionPath, 'deps.clj.jar')
executable = 'java';
args = ['-jar', depsJarPath, ...args];
} else {
executable = projectType.winCmd[0];
args = [...projectType.winCmd.slice(1), ...args];
}
} else {
executable = projectType.cmd[0];
args = [...projectType.cmd.slice(1), ...args];
}

const terminalOptions: JackInTerminalOptions = {
name: `Calva Jack-in: ${projectConnectSequence.name}`,
Expand All @@ -147,6 +160,7 @@ async function getJackInTerminalOptions(projectConnectSequence: ReplConnectSeque
env: getJackInEnv(),
isWin: projectTypes.isWin,
cwd: state.getProjectRootLocal(),
useShell: projectTypes.isWin ? projectType.processShellWin : projectType.processShellUnix
};
return terminalOptions;
}
Expand Down
45 changes: 26 additions & 19 deletions src/nrepl/project-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@ export const isWin = /^win/.test(process.platform);
export type ProjectType = {
name: string;
cljsTypes: string[];
cmd: string;
winCmd: string;
cmd: string[];
winCmd: string[];
processShellWin: boolean;
processShellUnix: boolean;
commandLine: (connectSequence: ReplConnectSequence, cljsType: CljsTypes) => any;
useWhenExists: string;
nReplPortFile: string[];
Expand Down Expand Up @@ -245,8 +247,10 @@ const projectTypes: { [id: string]: ProjectType } = {
"lein": {
name: "Leiningen",
cljsTypes: ["Figwheel", "Figwheel Main"],
cmd: "lein",
winCmd: "cmd.exe",
cmd: ["lein"],
winCmd: ["cmd.exe", "/d", "/c", "lein"],
processShellUnix: true,
processShellWin: false,
useWhenExists: "project.clj",
nReplPortFile: [".nrepl-port"],
/** Build the command line args for a lein-project.
Expand Down Expand Up @@ -276,10 +280,12 @@ const projectTypes: { [id: string]: ProjectType } = {
},
*/
"clj": {
name: "Clojure CLI",
name: "deps.edn",
cljsTypes: ["Figwheel", "Figwheel Main"],
cmd: "clojure",
winCmd: "powershell.exe",
cmd: ["clojure"],
winCmd: [], // this will be determined at jack-in
processShellUnix: true,
processShellWin: true,
useWhenExists: "deps.edn",
nReplPortFile: [".nrepl-port"],
/** Build the command line args for a clj-project.
Expand Down Expand Up @@ -338,29 +344,29 @@ const projectTypes: { [id: string]: ProjectType } = {
if (aliasHasMain)
break;
}
const q = isWin ? '"' : "'";
const dQ = isWin ? '""' : '"';
for (let dep in dependencies)
out.push(dep + ` {:mvn/version ${dQ}${dependencies[dep]}${dQ}}`)
out.push(dep + ` {:mvn/version,${dQ}${dependencies[dep]}${dQ}}`)

let args = ["-Sdeps", `'${"{:deps {" + out.join(' ') + "}}"}'`];
let args = ["-Sdeps", `${q}${"{:deps {" + out.join(',') + "}}"}${q}`];

if (aliasHasMain) {
args.push(aliasesOption);
} else {
args.push(aliasesOption, "-m", "nrepl.cmdline", "--middleware", `"[${useMiddleware.join(' ')}]"`);
}

if (isWin) {
args.unshift("clojure");
}
return args;
}
},
"shadow-cljs": {
name: "shadow-cljs",
cljsTypes: [],
cmd: "npx",
winCmd: "npx.cmd",
cmd: ["npx"],
winCmd: ["npx.cmd"],
processShellUnix: true,
processShellWin: false,
useWhenExists: "shadow-cljs.edn",
nReplPortFile: [".shadow-cljs", "nrepl.port"],
/**
Expand Down Expand Up @@ -391,8 +397,10 @@ const projectTypes: { [id: string]: ProjectType } = {
"lein-shadow": {
name: "lein-shadow",
cljsTypes: [],
cmd: "lein",
winCmd: "cmd.exe",
cmd: ["lein"],
winCmd: ["cmd.exe", "/d", "/c", "lein"],
processShellUnix: true,
processShellWin: false,
useWhenExists: "project.clj",
nReplPortFile: [".shadow-cljs", "nrepl.port"],
/**
Expand Down Expand Up @@ -420,6 +428,8 @@ const projectTypes: { [id: string]: ProjectType } = {
cljsTypes: [],
cmd: undefined,
winCmd: undefined,
processShellUnix: true,
processShellWin: false,
useWhenExists: undefined,
nReplPortFile: [".nrepl-port"],
commandLine: async (connectSequence: ReplConnectSequence, cljsType: CljsTypes) => {
Expand All @@ -438,9 +448,6 @@ async function leinCommandLine(command: string[], cljsType: CljsTypes, connectSe
let keys = Object.keys(dependencies);
const defproject = await leinDefProject();
const { profiles, alias } = await leinProfilesAndAlias(defproject, connectSequence);
if (isWin) {
out.push("/d", "/c", "lein");
}
const q = isWin ? '' : "'", dQ = '"';
for (let i = 0; i < keys.length; i++) {
let dep = keys[i];
Expand Down