Skip to content

feat: supporting proxy config #79

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

Closed
Closed
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
3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,6 @@
"@types/node": "20.2.5",
"@types/simple-mock": "^0.8.6",
"@types/tar": "^6.1.13",
"@types/unzipper": "^0.10.10",
"@types/vscode": "^1.81.0",
"@typescript-eslint/eslint-plugin": "^5.59.8",
"@typescript-eslint/parser": "^5.59.8",
Expand All @@ -169,7 +168,7 @@
},
"dependencies": {
"adm-zip": "^0.5.16",
"sync-request": "^6.1.0",
"axios": "^1.9.0",
"tar": "^7.4.3"
}
}
4 changes: 2 additions & 2 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,9 @@ function registerOpenViewsCommands(
);
}

export function activate(context: ExtensionContext) {
export async function activate(context: ExtensionContext) {
const outputChannel = window.createOutputChannel("GitGuardian");
let configuration = getConfiguration(context, outputChannel);
let configuration = await getConfiguration(context, outputChannel);

const ggshieldResolver = new GGShieldResolver(
outputChannel,
Expand Down
10 changes: 6 additions & 4 deletions src/lib/ggshield-configuration-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,23 @@ import { getGGShield } from "./ggshield-resolver-utils";
* Retrieve configuration from settings
* @returns {GGShieldConfiguration} from the extension settings
*/
export function getConfiguration(
export async function getConfiguration(
context: ExtensionContext,
outputChannel: OutputChannel
): GGShieldConfiguration {
): Promise<GGShieldConfiguration> {
const config = workspace.getConfiguration("gitguardian");

const ggshieldPath: string | undefined = config.get("GGShieldPath");
const apiUrl: string | undefined = config.get("apiUrl");
const allowSelfSigned: boolean = config.get("allowSelfSigned", false);
const ignoreSSLErrors = allowSelfSigned;

const pathToGGShield: string = getGGShield(
const pathToGGShield: string = await getGGShield(
os.platform(),
os.arch(),
context,
outputChannel
outputChannel,
ignoreSSLErrors
);

return new GGShieldConfiguration(
Expand Down
61 changes: 41 additions & 20 deletions src/lib/ggshield-resolver-utils.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
import * as path from "path";
import * as fs from "fs";
import * as tar from "tar";
import axios, { AxiosRequestConfig} from "axios";
import { Agent } from "https";

const AdmZip = require("adm-zip");

Check warning on line 7 in src/lib/ggshield-resolver-utils.ts

View workflow job for this annotation

GitHub Actions / build-and-test (windows-latest)

Variable name `AdmZip` must match one of the following formats: camelCase, UPPER_CASE

Check warning on line 7 in src/lib/ggshield-resolver-utils.ts

View workflow job for this annotation

GitHub Actions / build-and-test (macos-latest)

Variable name `AdmZip` must match one of the following formats: camelCase, UPPER_CASE

Check warning on line 7 in src/lib/ggshield-resolver-utils.ts

View workflow job for this annotation

GitHub Actions / build-and-test (ubuntu-latest)

Variable name `AdmZip` must match one of the following formats: camelCase, UPPER_CASE
import { ExtensionContext, OutputChannel } from "vscode";

const defaultRequestConfig = {
headers: { "User-Agent": "GitGuardian-VSCode-Extension" },

Check warning on line 11 in src/lib/ggshield-resolver-utils.ts

View workflow job for this annotation

GitHub Actions / build-and-test (windows-latest)

Object Literal Property name `User-Agent` must match one of the following formats: camelCase

Check warning on line 11 in src/lib/ggshield-resolver-utils.ts

View workflow job for this annotation

GitHub Actions / build-and-test (macos-latest)

Object Literal Property name `User-Agent` must match one of the following formats: camelCase

Check warning on line 11 in src/lib/ggshield-resolver-utils.ts

View workflow job for this annotation

GitHub Actions / build-and-test (ubuntu-latest)

Object Literal Property name `User-Agent` must match one of the following formats: camelCase
timeout: 30_000
} satisfies AxiosRequestConfig;

/**
* Get the absolute path to GGShield binary. If it doesn't exist, it will be installed.
* @param platform The platform of the user
Expand All @@ -12,12 +20,13 @@
* @param outputChannel The output channel to use
* @returns The absolute path to the GGShield binary
*/
export function getGGShield(
export async function getGGShield(
platform: NodeJS.Platform,
arch: string,
context: ExtensionContext,
outputChannel: OutputChannel
): string {
outputChannel: OutputChannel,
ignoreSSLErrors: boolean
): Promise<string> {
const version = fs
.readFileSync(path.join(context.extensionPath, "ggshield_version"), "utf8")
.trim();
Expand Down Expand Up @@ -47,7 +56,7 @@
}
fs.mkdirSync(ggshieldFolder);
// install GGShield
installGGShield(platform, arch, ggshieldFolder, version);
await installGGShield(platform, arch, ggshieldFolder, version, ignoreSSLErrors);
outputChannel.appendLine(
`Updated to GGShield v${version}. Checkout https://github.com/GitGuardian/ggshield for more info.`
);
Expand All @@ -59,14 +68,16 @@
* Get the latest version of GGShield
* @returns The latest version of GGShield
*/
export function getGGShieldLatestVersion(): string {
const response = require("sync-request")(
"GET",
export async function getGGShieldLatestVersion(): Promise<string> {
const { data } = await axios.get<{tag_name?: string}>(

Check warning on line 72 in src/lib/ggshield-resolver-utils.ts

View workflow job for this annotation

GitHub Actions / build-and-test (windows-latest)

Type Property name `tag_name` must match one of the following formats: camelCase

Check warning on line 72 in src/lib/ggshield-resolver-utils.ts

View workflow job for this annotation

GitHub Actions / build-and-test (macos-latest)

Type Property name `tag_name` must match one of the following formats: camelCase

Check warning on line 72 in src/lib/ggshield-resolver-utils.ts

View workflow job for this annotation

GitHub Actions / build-and-test (ubuntu-latest)

Type Property name `tag_name` must match one of the following formats: camelCase
"https://api.github.com/repos/GitGuardian/ggshield/releases/latest",
{ headers: { "User-Agent": "GitGuardian-VSCode-Extension" } }
{
...defaultRequestConfig,
responseEncoding: 'utf8'
}
);
const data = JSON.parse(response.getBody("utf8"));
return data.tag_name?.replace(/^v/, "");

return data.tag_name?.replace(/^v/, "") ?? "";
}

/**
Expand Down Expand Up @@ -119,12 +130,13 @@
* @param ggshieldFolder The folder of the GGShield binary
* @param version The version of GGShield
*/
export function installGGShield(
export async function installGGShield(
platform: NodeJS.Platform,
arch: string,
ggshieldFolder: string,
version: string
): void {
version: string,
ignoreSSLErrors: boolean,
): Promise<void> {
let extension: string = "";
switch (platform) {
case "win32":
Expand All @@ -144,7 +156,7 @@
version
)}.${extension}`;
const downloadUrl: string = `https://github.com/GitGuardian/ggshield/releases/download/v${version}/${fileName}`;
downloadGGShieldFromGitHub(fileName, downloadUrl, ggshieldFolder);
await downloadGGShieldFromGitHub(fileName, downloadUrl, ggshieldFolder, ignoreSSLErrors);
extractGGShieldBinary(path.join(ggshieldFolder, fileName), ggshieldFolder);
}

Expand Down Expand Up @@ -177,16 +189,25 @@
* @param downloadUrl The URL of the GGShield binary
* @param ggshieldFolder The folder of the GGShield binary
*/
function downloadGGShieldFromGitHub(
async function downloadGGShieldFromGitHub(
fileName: string,
downloadUrl: string,
ggshieldFolder: string
): void {
ggshieldFolder: string,
ignoreSSLErrors: boolean
): Promise<void> {
console.log(`Downloading GGShield from ${downloadUrl}`);
const response = require("sync-request")("GET", downloadUrl, {
headers: { "User-Agent": "GitGuardian-VSCode-Extension" },

const instance = ignoreSSLErrors ? new Agent({
rejectUnauthorized: true
}): undefined;

const { data } = await axios.get(downloadUrl, {
...defaultRequestConfig,
responseType: 'arraybuffer',
httpsAgent: instance
});
fs.writeFileSync(path.join(ggshieldFolder, fileName), response.getBody());

fs.writeFileSync(path.join(ggshieldFolder, fileName), data);
console.log(
`GGShield archive downloaded to ${path.join(ggshieldFolder, fileName)}`
);
Expand Down
4 changes: 2 additions & 2 deletions src/test/suite/lib/ggshield-configuration-utils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ suite("getConfiguration", () => {
simple.restore();
});

test("Vscode settings are correctly read", () => {
test("Vscode settings are correctly read", async () => {
const context = {} as ExtensionContext;
const outputChannel = window.createOutputChannel("GitGuardian");
simple.mock(context, "asAbsolutePath").returnWith("");
Expand All @@ -42,7 +42,7 @@ suite("getConfiguration", () => {
}
},
});
const configuration = getConfiguration(context, outputChannel);
const configuration = await getConfiguration(context, outputChannel);

// Assert both workspace.getConfiguration and GGShieldConfiguration constructor were called
assert(
Expand Down
21 changes: 12 additions & 9 deletions src/test/suite/lib/ggshield-resolver-utils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,17 @@
import * as fs from "fs";
import * as os from "os";
import * as tar from "tar";
const AdmZip = require("adm-zip");

Check warning on line 6 in src/test/suite/lib/ggshield-resolver-utils.test.ts

View workflow job for this annotation

GitHub Actions / build-and-test (windows-latest)

Variable name `AdmZip` must match one of the following formats: camelCase, UPPER_CASE

Check warning on line 6 in src/test/suite/lib/ggshield-resolver-utils.test.ts

View workflow job for this annotation

GitHub Actions / build-and-test (macos-latest)

Variable name `AdmZip` must match one of the following formats: camelCase, UPPER_CASE

Check warning on line 6 in src/test/suite/lib/ggshield-resolver-utils.test.ts

View workflow job for this annotation

GitHub Actions / build-and-test (ubuntu-latest)

Variable name `AdmZip` must match one of the following formats: camelCase, UPPER_CASE
import * as getGGShieldUtils from "../../../lib/ggshield-resolver-utils";
import { ExtensionContext, window, OutputChannel } from "vscode";

suite("getGGShield integration tests", () => {
suite("getGGShield integration tests", async () => {
let tempDir: string;
let mockContext: ExtensionContext;
let outputChannel: OutputChannel = window.createOutputChannel("GitGuardian");
const platform = process.platform;
const arch = process.arch;
const latestVersion = getGGShieldUtils.getGGShieldLatestVersion();
const latestVersion = await getGGShieldUtils.getGGShieldLatestVersion();
let originalLog: (message?: any, ...optionalParams: any[]) => void;
let output: string;

Expand Down Expand Up @@ -54,7 +54,8 @@
platform,
arch,
mockContext,
outputChannel
outputChannel,
false
);

assert.strictEqual(result, binaryPath);
Expand All @@ -66,7 +67,7 @@
);
});

test("installs binary when it doesn't exist", () => {
test("installs binary when it doesn't exist", async () => {
const expectedBinaryPath: string = getGGShieldUtils.computeGGShieldPath(
platform,
arch,
Expand All @@ -75,11 +76,12 @@
);
assert(!fs.existsSync(expectedBinaryPath));

const result = getGGShieldUtils.getGGShield(
const result = await getGGShieldUtils.getGGShield(
platform,
arch,
mockContext,
outputChannel
outputChannel,
false
);

assert(fs.existsSync(result));
Expand All @@ -91,18 +93,19 @@
);
});

test("updates binary when newer version set by ggshield_version file", () => {
test("updates binary when newer version set by ggshield_version file", async () => {
const oldBinaryPath: string = createFakeBinary(
tempDir,
platform,
arch,
"1.0.0"
);
const result = getGGShieldUtils.getGGShield(
const result = await getGGShieldUtils.getGGShield(
platform,
arch,
mockContext,
outputChannel
outputChannel,
false
);

assert(fs.existsSync(result));
Expand Down
Loading