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

Effekt Version Manager: automatic installer and updater #20

Merged
merged 32 commits into from
Oct 1, 2024

Conversation

jiribenes
Copy link
Contributor

@jiribenes jiribenes commented Aug 9, 2024

This is a somewhat rough draft of an automatic installer & updater for Effekt (addresses effekt-lang/effekt#289)
I cannot test this locally, my local setup is quite weird and I can't really use npm for Effekt distribution.

This PR will require extensive testing on various platforms.

Features

  • new status bar shows the state of the LSP server, current Effekt version and the selected backend (useful for debugging)
    • clicking on the status bar checks for Effekt updates (in npm)
  • updated dependencies to allow newer VSCode features
  • on startup, check if we can find the effekt binary:
    • if not and if it's a custom executable by the user, report a specific error
    • if not, offer the user to install the newest version of Effekt from npm
    • if we have effekt, take a look at its version: if it's older than the latest version on npm, offer updating to a newer version of Effekt via npm
  • if the user wants to install/update and they don't have nodejs or npm, report a specific error
  • if effekt isn't found after installation, check the places npm installs into if the binary is there and if it works (in order to debug PATH issues)
  • also add a specific command to explicitly install/update (again useful for debugging installations)
  • the Effekt Version Manager has its own output log, separate from the server (offered to the user when something errors)

Problems

Screenshots

Status bar

Screenshot 2024-08-10 at 11 59 10 Screenshot 2024-08-10 at 12 00 34

effekt-status-bar

Installation pop-ups

Screenshot 2024-08-10 at 12 00 53 Screenshot 2024-08-10 at 12 01 14

src/effektManager.ts Outdated Show resolved Hide resolved
@jiribenes jiribenes changed the title Automatic installer & updater Effekt Version Manager: automatic installer and updater Aug 10, 2024
Comment on lines 95 to 136
/**
* Locates the Effekt executable.
*/
public async getEffektExecutable(): Promise<EffektExecutableInfo> {
const customPath = this.config.get<string>("executable");
if (customPath) {
try {
const version = await this.execCommand(`"${customPath}" --version`);
return { path: customPath, version };
} catch (error) {
this.showErrorWithLogs(`Custom Effekt executable not working: ${customPath}. ${error}`);
}
}

for (const name of this.possibleEffektExecutables) {
try {
const version = await this.execCommand(`${name} --version`);
return { path: name, version };
} catch {
// Try next option
}
}

throw new Error('Effekt executable not found');
}
Copy link
Contributor Author

@jiribenes jiribenes Aug 26, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Technically in case --version fails, we also might want to try --help as that ought to work universally across all Effekt versions, whereas --version is only being added as of writing this comment (effekt-lang/effekt#556).

src/semver.d.ts Outdated Show resolved Hide resolved
Copy link
Collaborator

@b-studios b-studios left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks beautiful! The implementation is exemplary!

One thing that I noticed is that we check for node, but not the JVM. Maybe checking and reporting: "Hey, maybe you want to install a JVM > X" would help some users?

]
}
"configurations": [
{
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does everybody suddenly start to use tabs?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I actually took these files from the VSCode template extension, just to update the structure :)

}
}

private handleInstallationResult(result: InstallationResult, action: 'install' | 'update'): void {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is funny how stringly typed things become ok with singleton types and unions...

@jiribenes
Copy link
Contributor Author

This looks beautiful! The implementation is exemplary!

Thanks! I'll forward the praise to Claude 3.5 Sonnet ;)

One thing that I noticed is that we check for node, but not the JVM. Maybe checking and reporting: "Hey, maybe you want to install a JVM > X" would help some users?

I used to have the check there, it should be easy to re-add. :)
Note that these checks only run when the user chooses to update.

@jiribenes jiribenes force-pushed the jiribenes/installer branch 3 times, most recently from a390c14 to 236de6f Compare September 11, 2024 08:37
@jiribenes
Copy link
Contributor Author

Rebased on current master so that I can have this version together with the cool syntax highlighting :)

@jiribenes
Copy link
Contributor Author

Rebased on current master yet again.

Comment on lines 187 to 206
"scripts": {
"vscode:prepublish": "npm run compile",
"compile": "tsc -p ./",
"watch": "tsc -watch -p ./",
"postinstall": "node ./node_modules/vscode/bin/install",
"test": "npm run compile && node ./node_modules/vscode/bin/test"
"compile": "tsc -b",
"watch": "tsc -b -w",
"lint": "eslint ./client/src ./server/src --ext .ts,.tsx"
},
"dependencies": {
"compare-versions": "^6.1.1",
"vscode-languageclient": "^5.2.1"
},
"devDependencies": {
"typescript": "^2.6.1",
"vscode": "^1.1.37",
"tslint": "^5.8.0",
"@types/node": "^7.0.43",
"@types/mocha": "^2.2.42"
"@types/mocha": "^10.0.6",
"@types/node": "^18.14.6",
"@types/vscode": "^1.30.0",
"@typescript-eslint/eslint-plugin": "^7.1.0",
"@typescript-eslint/parser": "^7.1.0",
"eslint": "^8.57.0",
"mocha": "^10.3.0",
"typescript": "^5.3.3"
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to be clear, the changes here and in .vscode are taken directly from the official VSCode extension template https://github.com/microsoft/vscode-extension-samples (from the LSP sample)

@jiribenes
Copy link
Contributor Author

I added some code to detect the JRE version, not sure it works too well (can't test it properly right now).
The only caveat is that this check only runs when we try to install/update Effekt.

@jiribenes

This comment was marked as resolved.

Comment on lines +203 to +216
private async runNpmInstall(): Promise<void> {
// 1) Check if the npm root is managed by Nix in order to produce a better error
const npmRoot = await this.execCommand('npm root -g');
if (npmRoot.startsWith("/nix/store")) {
this.logMessage('ERROR', 'NPM root is in the read-only Nix store. Installation is not possible.')
throw new Error('Detected Nix environment: NPM global modules are stored in a read-only directory managed by Nix. Installation cannot proceed.');
}

// 2) Actually run `npm install -g ...`
const npmInstallCommand = `npm install -g ${this.effektNPMPackage}@latest`;
const npmOutput = await this.execCommand(npmInstallCommand);

this.logMessage('INFO', `Ran '${npmInstallCommand}'; stdout: ${npmOutput}`);
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added Nix detection here just to have a nicer error message for myself :)
No idea if it's actually useful for anybody else than me (and I also have no idea whether this is correct)
image

@jiribenes
Copy link
Contributor Author

jiribenes commented Sep 17, 2024

Current state of testing: seems to work for all Linux (N ≥ 4) and MacOS (N = 2) testers so far.
One reported permissions issues on Linux when calling npm install -g.
Two people tried on Windows without WSL: installation goes well, but then the server crashes, see #25. With WSL, everything seems to work perfectly fine for one of them, but not the other. => Further testing on Windows is required.

From feedback: It would be nice to display the full path to the Effekt executable in the status bar on hover (we have the info anyways! EDIT: No, we don't, we use PATH...)

@jiribenes jiribenes marked this pull request as ready for review September 18, 2024 13:33
src/effektManager.ts Outdated Show resolved Hide resolved
@jiribenes jiribenes linked an issue Sep 29, 2024 that may be closed by this pull request
@jiribenes jiribenes requested a review from b-studios September 29, 2024 12:50
@b-studios b-studios merged commit b24a821 into master Oct 1, 2024
1 check passed
@b-studios b-studios deleted the jiribenes/installer branch October 1, 2024 14:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Investigate LSP support on Windows
2 participants