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

Detect external AGLint installations, support for extension settings #90

Merged
merged 10 commits into from
May 5, 2023
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
2 changes: 1 addition & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
"!**/node_modules/**"
],
"autoAttachChildProcesses": true,
"preLaunchTask": "npm: build"
"preLaunchTask": "npm: dev"
}
]
}
2 changes: 1 addition & 1 deletion .vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"tasks": [
{
"type": "npm",
"script": "esbuild",
"script": "dev",
"group": "build",
"presentation": {
"panel": "dedicated",
Expand Down
28 changes: 26 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ Table of Contents:
- [Introduction](#introduction)
- [Features](#features)
- [Syntax highlighting](#syntax-highlighting)
- [Adblock rule linter](#adblock-rule-linter)
- [AGLint integration (linter)](#aglint-integration-linter)
- [Configuration](#configuration)
- [GitHub Linguist support](#github-linguist-support)
- [Ideas \& Questions](#ideas--questions)
- [Reporting Issues](#reporting-issues)
Expand Down Expand Up @@ -73,14 +74,27 @@ syntaxes. Nowadays it is unimaginable to work with code without highlighting,
which helps you to distinguish different parts of the code and makes it easier
to read.

### Adblock rule linter
### AGLint integration (linter)

We integrated [AGLint][aglint] into this
extension, that makes it able to check your rules for various issues, such as
invalid syntax, invalid domains, invalid / incompatible CSS selectors,
unknown / incompatible scriptlets, bad practices, etc. For more information
about AGLint, please refer to its [repository][aglint].

AGLint integration is done in the following way:
1. Extension will search local AGLint installation (if it is installed) and use
it for linting. First, it will search for local installation in the current
workspace, and if it is not found, it will search for a global installation.
This is an ideal behavior, because if you have a local installation, it
guarantees that you will use the same version of AGLint, and the results will
be the same.
2. If the extension doesn't find any installation, it will use the bundled
version of AGLint, which is included in the extension itself. Usually, it is
the latest version of AGLint. The advantage of this approach is that you
don't need to install AGLint manually, and you can start using the extension
immediately after installation.

> :warning: Please note that the linter is under active development, so it may
> not work properly for some rules. If you find any issues, please report them
> [here][aglintissues]. We look forward to your feedback, your help is very
Expand All @@ -89,6 +103,16 @@ about AGLint, please refer to its [repository][aglint].
[aglint]: https://github.com/AdguardTeam/AGLint
[aglintissues]: https://github.com/AdguardTeam/AGLint/issues

### Configuration

This extension provides the following configuration options:

| Option | Description | Default value | Possible values |
| ------ | ----------- | ------------- | --------------- |
| `adblock.enableAglint` | Enable or disable AGLint integration. If disabled, only syntax highlighting and other language features will be available. | `true` | `true`, `false` |
| `adblock.useExternalAglintPackages` | If enabled, extension will search for AGLint installations in the system. If disabled, extension will use its own AGLint installation, which is included in the extension (integrated AGLint bundle). If you have AGLint installed in your system / project, it is recommended to enable this option in order to provide consistent results. | `true` | `true`, `false` |
| `adblock.packageManager` | Package manager to use for searching global AGLint installations. Set it to your preferred package manager. | `npm` | `npm`, `yarn`, `pnpm` |

### GitHub Linguist support

GitHub supports adblock syntax officially via the [Linguist][linguist] library.
Expand Down
18 changes: 17 additions & 1 deletion client/src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ export function activate(context: ExtensionContext) {
// Notify the server if the configuration has changed (such as .aglintrc, .aglintignore, etc.)
// We define these files as glob patterns here
fileEvents: [
workspace.createFileSystemWatcher('**/*.{txt,adblock,ublock,adguard}', false, true, false),
workspace.createFileSystemWatcher(`**/{${CONFIG_FILE_NAMES.join(',')}}`),
workspace.createFileSystemWatcher(`**/{${IGNORE_FILE_NAME}}`),
],
Expand Down Expand Up @@ -124,14 +125,27 @@ export function activate(context: ExtensionContext) {
if (params?.error) {
// We have an error, so change the status bar background to red
statusBarItem.backgroundColor = new ThemeColor('statusBarItem.warningBackground');

// Show warning icon
statusBarItem.text = '$(warning) AGLint';
} else {
// Everything is fine, so change the status bar background to the default color
// In this case, params is null
statusBarItem.backgroundColor = undefined;

if (params?.aglintEnabled === false) {
// Show a blocked icon if AGLint is disabled
statusBarItem.text = '$(debug-pause) AGLint';
} else {
// Reset the status bar text
statusBarItem.text = 'AGLint';
}
}
});

client.outputChannel.appendLine('AGLint extension client activated');
// Notify the user if the extension is activated. Show the version of the VSCode plugin,
// maybe it will be useful for debugging / support
client.info(`AGLint extension client activated. Extension version: ${context.extension.packageJSON.version}`);

// Start the client. This will also launch the server.
client.start();
Expand All @@ -148,5 +162,7 @@ export function deactivate(): Thenable<void> | undefined {
return undefined;
}

client.info('Deactivating AGLint extension client...');

return client.stop();
}
66 changes: 42 additions & 24 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,34 +55,52 @@
"source.js": "javascript"
}
}
]
],
"configuration": {
"type": "object",
"title": "Adblock",
"properties": {
"adblock.enableAglint": {
"scope": "resource",
"type": "boolean",
"default": true,
"description": "Enable or disable AGLint integration. If disabled, only syntax highlighting and other language features will be available."
},
"adblock.useExternalAglintPackages": {
"scope": "resource",
"type": "boolean",
"default": true,
"description": "If enabled, extension will search for AGLint installations in the system. If disabled, extension will use its own AGLint installation, which is included in the extension (integrated AGLint bundle). If you have AGLint installed in your system / project, it is recommended to enable this option in order to provide consistent results."
},
"adblock.packageManager": {
"scope": "resource",
"type": "string",
"enum": [
"npm",
"yarn",
"pnpm"
],
"enumDescriptions": [
"Node Package Manager",
"Yarn Package Manager",
"pnpm Package Manager"
],
"default": "npm",
"description": "Package manager to use for searching global AGLint installations. Set it to your preferred package manager."
}
}
}
},
"scripts": {
"client:esbuild-prod": "yarn client:esbuild-base --minify",
"client:esbuild-base": "esbuild ./client/src/extension.ts --bundle --outfile=client/out/extension.js --external:vscode --format=cjs --platform=node",
"client:esbuild": "yarn client:esbuild-base --sourcemap",
"client:esbuild-watch": "yarn client:esbuild-base --sourcemap --watch",
"client:test-compile": "tsc -p ./client",
"client:lint": "eslint ./client/src --ext .ts",
"client:clean": "rimraf client/out",
"server:esbuild-prod": "yarn server:esbuild-base --minify",
"server:esbuild-base": "esbuild ./server/src/server.ts --bundle --outfile=server/out/server.js --external:vscode --format=cjs --platform=node",
"server:esbuild": "yarn server:esbuild-base --sourcemap",
"server:esbuild-watch": "yarn server:esbuild-base --sourcemap --watch",
"server:test-compile": "tsc -p ./server",
"server:lint": "eslint ./server/src --ext .ts",
"server:clean": "rimraf server/out",
"esbuild-prod": "yarn client:esbuild-prod && yarn server:esbuild-prod",
"esbuild": "yarn client:esbuild && yarn server:esbuild",
"build": "yarn grammar:build && yarn esbuild",
"esbuild-watch": "yarn concurrently \"yarn server:esbuild-watch\" \"yarn client:esbuild-watch\"",
"test-compile": "yarn client:test-compile && yarn server:test-compile",
"clean": "yarn client:clean && yarn server:clean",
"dev": "yarn concurrently -n grammar,client,server,aglint \"ts-node tools/grammar-builder.ts\" \"esbuild ./client/src/extension.ts --bundle --outfile=client/out/extension.js --external:vscode --format=cjs --platform=node --sourcemap\" \"esbuild ./server/src/server.ts --bundle --outfile=server/out/server.js --external:vscode --external:./integrated-aglint --format=cjs --platform=node --sourcemap\" \"esbuild ./server/src/aglint.ts --bundle --outfile=server/out/aglint.js --format=cjs --platform=node --sourcemap\"",
"dev-watch": "concurrently -n watch-client,watch-server,watch-aglint \"esbuild ./client/src/extension.ts --bundle --outfile=client/out/extension.js --external:vscode --format=cjs --platform=node --sourcemap --watch\" \"esbuild ./server/src/server.ts --bundle --outfile=server/out/server.js --external:vscode --external:./integrated-aglint --format=cjs --platform=node --sourcemap --watch\" \"esbuild ./server/src/aglint.ts --bundle --outfile=server/out/aglint.js --format=cjs --platform=node --sourcemap --watch\"",
"prod": "yarn clean && ts-node tools/grammar-builder.ts && esbuild ./client/src/extension.ts --bundle --outfile=client/out/extension.js --external:vscode --format=cjs --platform=node --minify && yarn esbuild ./server/src/server.ts --bundle --outfile=server/out/server.js --external:vscode --external:\"./integrated-aglint\" --format=cjs --platform=node --minify && yarn esbuild ./server/src/aglint.ts --bundle --outfile=server/out/aglint.js --format=cjs --platform=node --minify",
"clean": "rimraf ./client/out && rimraf ./server/out && rimraf ./syntaxes/out",
"test-compile": "tsc -p ./client --noEmit && tsc -p ./server --noEmit",
"lint": "eslint . --ext .ts",
"postinstall": "cd client && yarn && cd ../server && yarn && cd ..",
"generate-vsix": "yarn grammar:build && yarn esbuild-prod && vsce package --yarn --out vscode-adblock.vsix",
"test": "jest",
"grammar:build": "ts-node tools/grammar-builder.ts",
"generate-vsix": "vsce package --yarn --out vscode-adblock.vsix",
"postinstall": "cd client && yarn && cd ../server && yarn && cd ..",
"prepare": "husky install"
},
"devDependencies": {
Expand Down
6 changes: 5 additions & 1 deletion server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@
"vscode-languageserver-textdocument": "^1.0.8"
},
"devDependencies": {
"@adguard/aglint": "1.0.11"
"@adguard/aglint": "1.0.11",
"@types/clone-deep": "^4.0.1",
"@types/semver": "^7.3.13",
"clone-deep": "^4.0.1",
"semver": "^7.5.0"
}
}
13 changes: 13 additions & 0 deletions server/src/aglint.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/**
* @file Integrated version of AGLint
*
* In this file, we simply re-export the AGLint API from the @adguard/aglint
* package, which is a dev dependency of this server package, so we simply call
* it "integrated" / "bundled" version.
*
* We always make a separate bundle for this file, so the server bundle can
* import it as a fallback if it doesn't found any other AGLint installation
* with module finder.
*/

export * from '@adguard/aglint';
16 changes: 16 additions & 0 deletions server/src/common/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/**
* @file General constant values used across the server
*/

/**
* Name of the AGLint package, probably will never change
*/
export const AGLINT_PACKAGE_NAME = '@adguard/aglint';

/**
* URL to the AGLint GitHub repository
*/
export const AGLINT_REPO_URL = 'https://github.com/AdguardTeam/AGLint';

export const LF = '\n';
export const EMPTY = '';
Loading