Skip to content

Commit

Permalink
Add support for Pacman *.install files
Browse files Browse the repository at this point in the history
Fixes #32.

Link: #32
  • Loading branch information
claui committed Sep 11, 2024
1 parent ce17df3 commit dd9f1cc
Show file tree
Hide file tree
Showing 9 changed files with 227 additions and 29 deletions.
13 changes: 11 additions & 2 deletions extension/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,14 @@ extension in the following ways:

- Will not affect regular shell scripts, only `PKGBUILD`s

### Pacman \*.install files

The Packaging extension adds syntax highlighting to Pacman `*.install`
files.

It also sets Bash as the shell, removing an unnecessary Shellcheck
warning.

### customizepkg syntax highlighting

The Packaging extension provides syntax highlighting for
Expand All @@ -75,7 +83,8 @@ ever.
## FAQ

- Q. Why does this extension set Bash as the shell?
A. `makepkg`, the program that sources `PKGBUILD`s, runs in Bash.
A. `makepkg`, the program that sources `PKGBUILD`s, runs in Bash.
The same goes for Pacman `*.install` files.

- Q. Why does this extension disable rule SC2164 for `PKGBUILD`s?
A. `makepkg` first configures `shopt -o -s errexit`, which is
Expand Down Expand Up @@ -122,7 +131,7 @@ A shout-out to these amazing people:

## License

Copyright (c) 2022 Claudia Pellegrino
Copyright (c) 2022–2024 Claudia Pellegrino

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down
3 changes: 3 additions & 0 deletions extension/examples/debian/foo.install
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
foo
bar
baz
37 changes: 37 additions & 0 deletions extension/examples/foo.install
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# The function is run right before files are extracted.
# One argument is passed: new package version.
pre_install() {
:
}

# The function is run right after files are extracted.
# One argument is passed: new package version.
post_install() {
:
}

# The function is run right before files are extracted.
# Two arguments are passed in the following order:
# new package version, old package version.
pre_upgrade() {
:
}

# The function is run right after files are extracted.
# Two arguments are passed in the following order:
# new package version, old package version.
post_upgrade() {
:
}

# The function is run right before files are removed.
# One argument is passed: old package version.
pre_remove() {
:
}

# The function is run right after files are removed.
# One argument is passed: old package version.
post_remove() {
:
}
25 changes: 25 additions & 0 deletions extension/share/dist/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,16 @@
"2154",
"2164"
]
},
"[pacman-install-script]": {
"shellcheck.customArgs": [
"--external-sources",
"--shell",
"bash"
]
},
"files.associations": {
"**/debian/*.install": "plain"
}
},
"grammars": [
Expand All @@ -38,6 +48,11 @@
"scopeName": "source.shell.pkgbuild.aur",
"path": "language/aur-pkgbuild.tmLanguage.json"
},
{
"language": "pacman-install-script",
"scopeName": "source.shell.install-script.pacman",
"path": "language/pacman-install-script.tmLanguage.json"
},
{
"language": "customizepkg-patch",
"scopeName": "source.customizepkg-patch",
Expand All @@ -55,6 +70,16 @@
],
"configuration": "language/aur-pkgbuild.language-configuration.json"
},
{
"id": "pacman-install-script",
"aliases": [
"Pacman *.install script"
],
"filenamePatterns": [
"**/*.install"
],
"configuration": "language/pacman-install-script.language-configuration.json"
},
{
"id": "customizepkg-patch",
"aliases": [
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
{
"comments": {
"lineComment": "#"
},
"brackets": [
[
"{",
"}"
],
[
"[",
"]"
],
[
"(",
")"
]
],
"autoClosingPairs": [
[
"{",
"}"
],
[
"[",
"]"
],
[
"(",
")"
],
{
"open": "\"",
"close": "\"",
"notIn": [
"string"
]
},
{
"open": "'",
"close": "'",
"notIn": [
"string"
]
},
{
"open": "`",
"close": "`",
"notIn": [
"string"
]
}
],
"surroundingPairs": [
[
"{",
"}"
],
[
"[",
"]"
],
[
"(",
")"
],
[
"\"",
"\""
],
[
"'",
"'"
],
[
"`",
"`"
]
],
"folding": {
"markers": {
"start": "^\\s*#\\s*#?region\\b.*",
"end": "^\\s*#\\s*#?endregion\\b.*"
}
}
}
11 changes: 11 additions & 0 deletions extension/share/language/pacman-install-script.tmLanguage.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"name": "pacman-install-script",
"scopeName": "source.shell.install-script.pacman",
"uuid": "04125485-6333-4e94-aad4-6b5983795a02",
"comment": "Pacman *.install script",
"patterns": [
{
"include": "source.shell"
}
]
}
33 changes: 22 additions & 11 deletions extension/src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,12 @@ import {
extensions,
} from "vscode";

import { statusItem } from "./language";
import {
PACMAN_INSTALL_SCRIPT_SELECTOR,
pacmanInstallScriptStatusItem,
PKGBUILD_SELECTOR,
pkgbuildStatusItem,
} from "./language";
import log from "./log";
import { SubscriptionHelper } from "./shellcheck";

Expand All @@ -20,20 +25,26 @@ function packageJson(context: ExtensionContext): ExtensionPackageJson {

export function activate(context: ExtensionContext) {
commands.registerCommand("packaging.action.showLog", log.show, log);
statusItem.command = {
pacmanInstallScriptStatusItem.command = {
command: "packaging.action.showLog",
title: "Show extension log",
};
pkgbuildStatusItem.command = { ...pacmanInstallScriptStatusItem.command };

const helper: SubscriptionHelper = new SubscriptionHelper(context);
let subscription: Disposable | null = helper.trySubscribe();
extensions.onDidChange((_) => {
if (subscription) {
subscription = helper.refresh(subscription);
} else {
subscription = helper.trySubscribe();
}
});
const helpers: SubscriptionHelper[] = [
new SubscriptionHelper(context, PACMAN_INSTALL_SCRIPT_SELECTOR),
new SubscriptionHelper(context, PKGBUILD_SELECTOR),
];
for (const helper of helpers) {
let subscription: Disposable | null = helper.trySubscribe();
extensions.onDidChange((_) => {
if (subscription) {
subscription = helper.refresh(subscription);
} else {
subscription = helper.trySubscribe();
}
});
}

const { version } = packageJson(context);
log.info(`Extension v${version} startup successful`);
Expand Down
16 changes: 13 additions & 3 deletions extension/src/language.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,19 @@
import { DocumentFilter, languages, LanguageStatusItem } from "vscode";

export const LANGUAGE_SELECTOR: DocumentFilter = { language: "aur-pkgbuild" };
export const PKGBUILD_SELECTOR: DocumentFilter = { language: "aur-pkgbuild" };

export const statusItem: LanguageStatusItem = languages
export const pkgbuildStatusItem: LanguageStatusItem = languages
.createLanguageStatusItem(
"aur-pkgbuild.status.item",
LANGUAGE_SELECTOR,
PKGBUILD_SELECTOR,
);

export const PACMAN_INSTALL_SCRIPT_SELECTOR: DocumentFilter = {
language: "pacman-install-script",
};

export const pacmanInstallScriptStatusItem: LanguageStatusItem = languages
.createLanguageStatusItem(
"pacman-install-script",
PACMAN_INSTALL_SCRIPT_SELECTOR,
);
32 changes: 19 additions & 13 deletions extension/src/shellcheck.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import {
extensions,
} from "vscode";

import { LANGUAGE_SELECTOR } from "./language";
import log from "./log";

const SHELLCHECK_EXTENSION: string = "timonwong.shellcheck";
Expand All @@ -18,26 +17,32 @@ export interface ShellCheckExtensionApiVersion1 {
export class SubscriptionHelper {
#context: ExtensionContext;
#firstTry = true;
#prefix: string;
#selector: DocumentFilter;

constructor(context: ExtensionContext) {
constructor(context: ExtensionContext, selector: DocumentFilter) {
this.#context = context;
this.#prefix = selector.language ?? JSON.stringify(selector);
this.#selector = { ...selector };
}

trySubscribe(): Disposable | null {
const subscription: Disposable | null = this.#subscribe();

if (subscription) {
if (this.#firstTry) {
log.info("Connected to ShellCheck extension.");
log.info(`${this.#prefix}: Connected to ShellCheck extension.`);
} else {
log.info("ShellCheck extension has appeared. Connected.");
log.info(`${this.#prefix}:`
+ " ShellCheck extension has appeared. Connected.");
}
} else {
// eslint-disable-next-line no-lonely-if
if (this.#firstTry) {
log.info("ShellCheck extension not active.");
log.info(`${this.#prefix}: ShellCheck extension not active.`);
} else {
log.info("Extensions have changed but still no sign of ShellCheck.");
log.info(`${this.#prefix}:`
+ " Extensions have changed but still no sign of ShellCheck.");
}
}

Expand All @@ -51,10 +56,12 @@ export class SubscriptionHelper {
*/
refresh(subscription: Disposable): Disposable | null {
if (SubscriptionHelper.#api()) {
log.info("Extensions have changed but ShellCheck is still around.");
log.info(`${this.#prefix}:`
+ " Extensions have changed but ShellCheck is still around.");
return subscription;
}
log.info("ShellCheck extension has gone away. Cleaning up.");
log.info(`${this.#prefix}:`
+ "ShellCheck extension has gone away. Cleaning up.");
subscription.dispose();
return null;
}
Expand All @@ -68,12 +75,12 @@ export class SubscriptionHelper {
|| !("apiVersion1" in shellCheckExtension.exports)) {
log.error(
"The ShellCheck extension is active but did not provide an API surface."
+ " Is the ShellCheck extension outdated?",
+ " Is the ShellCheck extension outdated?",
);
return null;
}
const {apiVersion1} = shellCheckExtension.exports as
{apiVersion1: ShellCheckExtensionApiVersion1};
const { apiVersion1 } = shellCheckExtension.exports as
{ apiVersion1: ShellCheckExtensionApiVersion1 };
return apiVersion1;
}

Expand All @@ -83,8 +90,7 @@ export class SubscriptionHelper {
return null;
}

const subscription: Disposable =
api.registerDocumentFilter(LANGUAGE_SELECTOR);
const subscription: Disposable = api.registerDocumentFilter(this.#selector);
this.#context.subscriptions.push(subscription);
return subscription;
}
Expand Down

0 comments on commit dd9f1cc

Please sign in to comment.