joelspadin-garmin / vscode-private-extension-manager

Private extension manager for Visual Studio Code
103 stars 22 forks source link

Question: how to automatically install your extension from a local VSIX #15

Closed jfthuong closed 4 years ago

jfthuong commented 4 years ago

Hi,

I really like your extension and would like to automatically install it if I install manually a VSIX from a local path (Command Extensions: Install from VSIX...).

I tried to used Extension Pack in my package.json:

        "extensionPack": [
            "garmin.private-extension-manager",
            "garmin.private-extension-manager-remote-helper"        
        ]

but it did nothing.

Is there a way to do it (maybe using a Typescript that is run when my extension is activated)?

Thanks

joelspadin-garmin commented 4 years ago

I'm guessing extensionPack doesn't work for an extension installed from a .vsix file.

You can install an extension from a script in your extension using this command though:

vscode.commands.executeCommand('workbench.extensions.installExtension', 'garmin.private-extension-manager');

As far as I can tell, there is no event that only runs the first time your extension is installed. You could check to see if Private Extension Manager is installed each time your extension is activated though:

export function activate(context: vscode.ExtensionContext) {
    if (vscode.extension.getExtension('garmin.private-extension-manager') === undefined) {
        ...
    }
}
jfthuong commented 4 years ago

Awesome....

Now, the only problem is that you cannot uninstall your extension as long as mine is installed (or it will re-install itself like some crapware 💩 )

jfthuong commented 4 years ago

FYI: it was vscode.extensions (with a -s).

The code is the following

export function activate(context: vscode.ExtensionContext) {
    // We will install Private Extension Manager automatically to be able to update more easily
    if (
        vscode.extensions.getExtension("garmin.private-extension-manager") === undefined
    ) {
        vscode.commands.executeCommand(
            "workbench.extensions.installExtension",
            "garmin.private-extension-manager"
        );
    }
}
jfthuong commented 4 years ago

Sorry to disturb you but would you know how to add a given registry to settings.json of the user if it does not exist yet?

I have the following in my activate function:

// We will also add the user settings to point to the correct registry
    let disposable = vscode.commands.registerCommand(
        "privateExtensions.addRepo",
        () => {
            const registry = {
                name: "VS Code Extensions Registry",
                registry:
                    "http://myrepo:8082/artifactory/api/npm/vs-code-extensions/",
                enablePagination: false,
            }

            vscode.workspace
                .getConfiguration()
                .update(
                    "privateExtensions.registries",
                    [registry],
                    vscode.ConfigurationTarget.Global
                );

                vscode.window.showInformationMessage(
                "Registry for Extensions Added!"
            )
        }
    );

This function is triggered by a registered command and works fine when called.

Would you know how check if the setting is not set?

Thank you very much

joelspadin-garmin commented 4 years ago

See the documentation for how to get the existing value, if it exists. The code for updating release channels might help for updating the setting: https://github.com/joelspadin-garmin/vscode-private-extension-manager/blob/b84e933054951d812641cfe1650d543d1de4f911/extension/src/releaseChannel.ts#L41-L51 It updates a dictionary, not a list, but it shows how to handle one issue I ran into: you can't just modify the object that get() returns. You have to make a clone of it, change it as needed, and then call update() with that.

Also, if you have specific repos that you want your private extension to be used with, there's a much less heavy handed approach. Create workspace recommended extensions and add "garmin.private-extension-manager" to it. Then you can make a similar file for private extensions which recommends your extension. I haven't finished adding a notification when there a recommended private extensions though, so you still have to manually install the recommended extensions though.

jfthuong commented 4 years ago

Thanks a lot of these tips.

I didn't have to clone it though. This is my code to remove the key query:

async function update_registry(registries: Array<object>) {
    await vscode.workspace
        .getConfiguration()
        .update(
            "privateExtensions.registries",
            registries,
            vscode.ConfigurationTarget.Global
        );
}

async function remove_filter_on_registry() {
    let registries: Array<object> = vscode.workspace
        .getConfiguration()
        .get("privateExtensions.registries", []);

    // Add registry for my extensions if not found
    if (!check_registry_found(registries)) {
        registries.push(default_registry);
    }

    registries.forEach((reg: object) => {
        // @ts-ignore: Does not know what is "reg"
        let url: string = reg["registry"];
        // @ts-ignore: Does not know what is "reg"
        let query: string = reg["query"] || "";
        if (url.includes("myrepo") && query == "myextension") {
            // @ts-ignore: Does not know what is "reg"
            delete reg["query"];
            vscode.window.showInformationMessage(
                "Private Repo: removed filter"
            );
        }
    });

    await update_registry(registries);
}