Skip to content

Commit

Permalink
Forks update script from Angular Dev Infra repo.
Browse files Browse the repository at this point in the history
Refs #74.

This is a straight copy of the relevant files with no modifications made to the files to be clear about changes in subsequent diffs. The only difference is that the files are named `*.mts` instead of `*.ts` to match existing repository conventions.
  • Loading branch information
dgp1130 committed Jul 29, 2023
1 parent 99c4cc4 commit 25634f9
Show file tree
Hide file tree
Showing 11 changed files with 713 additions and 0 deletions.
36 changes: 36 additions & 0 deletions bazel/browsers/update_script/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
load("//tools:defaults.bzl", "esbuild", "ts_library")
load("@build_bazel_rules_nodejs//:index.bzl", "nodejs_binary")

package(default_visibility = ["//visibility:private"])

ts_library(
name = "update_script_lib",
testonly = True,
srcs = glob(["*.ts"]),
deps = [
"//ng-dev/utils",
"@npm//@google-cloud/storage",
"@npm//@types/node",
"@npm//@types/tmp",
"@npm//@types/yargs",
"@npm//node-fetch",
"@npm//tmp",
"@npm//yargs",
],
)

esbuild(
name = "cli_script",
testonly = True,
entry_point = ":index.ts",
format = "iife",
deps = [":update_script_lib"],
)

nodejs_binary(
name = "update-script",
testonly = True,
data = [":cli_script"],
entry_point = "cli_script.js",
templated_args = ["--nobazel_run_linker"],
)
4 changes: 4 additions & 0 deletions bazel/browsers/update_script/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Browser Update Script

Forked from
https://github.com/angular/dev-infra/tree/1ad20ef9dd457de967252283c1a968b0d702d0ae/bazel/browsers/update-script.
69 changes: 69 additions & 0 deletions bazel/browsers/update_script/browser-artifact.mts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/**
* @license
* Copyright Google LLC
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/

import {Browser} from './browser.mjs';
import * as path from 'path';

/** Type describing possible artifact types for browser downloads. */
export type ArtifactType = 'driver-bin' | 'browser-bin';

/** Set of known artifact extensions, including chained extensions for gzipped files. */
const KNOWN_EXTENSIONS = new Set(['zip', 'tar.gz', 'tar.bz2', 'dmg']);

/** Class describing an artifact for a browser. */
export class BrowserArtifact {
constructor(
/** Instance of the browser this artifact exists for. */
public browser: Browser<unknown>,
/** Type of the artifact. */
public type: ArtifactType,
/** URL for downloading the artifact. */
public downloadUrl: string,
/** Extension of the artifact. If unspecified, derived from the download URL. */
public extension: string = detectArtifactExtension(downloadUrl),
) {}
}

/**
* Gets the extension of a given artifact file, excluding the dot/period.
*
* Since artifact download URLs can use chained extensions as for
* example with `.tar.gz`, we will need to keep track of known extensions
* and start looking with the first dot/period we discover.
*/
export function detectArtifactExtension(filePath: string) {
let tmpPath: string = filePath;
let extension: string = '';
let currentPart: string = '';

// Iterate from the end of the path, finding the largest possible
// extension substring, accounting for cases like `a/b.tmp/file.tar.gz`.
while ((currentPart = path.extname(tmpPath)) !== '') {
// An extension needs to be a continuous set of alphanumeric characters. This is a rather
// strict requirement as technically extensions could contain e.g. `dashes`. In our case
// this strictness is acceptable though as we don't expect such extensions and it makes
// this extension detection logic more correct. e.g. the logic would not incorrectly
// detect an extension for `firefox-97.0-linux.tar.gz` to `0-linux.tar.gz`.
if (!/^\.[a-zA-Z0-9]+$/.test(currentPart)) {
break;
}

extension = currentPart + extension;
tmpPath = path.basename(tmpPath, currentPart);
}

// Strip off the leading period/dot from the extension.
// If there is no extension, this string would remain empty.
extension = extension.substring(1);

if (KNOWN_EXTENSIONS.has(extension)) {
return extension;
}

throw new Error(`Unable to find known extension for file path: ${filePath}`);
}
18 changes: 18 additions & 0 deletions bazel/browsers/update_script/browser.mts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/**
* @license
* Copyright Google LLC
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/

import {BrowserArtifact, ArtifactType} from './browser-artifact.mjs';
import {Platform} from './platform.mjs';

/** Interface describing a browser. */
export interface Browser<T> {
name: string;
revision: T;
supports(platform: Platform): boolean;
getArtifact(platform: Platform, type: ArtifactType): BrowserArtifact;
}
82 changes: 82 additions & 0 deletions bazel/browsers/update_script/chromium.mts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/**
* @license
* Copyright Google LLC
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/

import {Browser} from './browser.mjs';
import {ArtifactType, BrowserArtifact} from './browser-artifact.mjs';
import {Platform} from './platform.mjs';

const cloudStorageArchiveUrl =
'https://storage.googleapis.com/chromium-browser-snapshots/{platform}/{revision}/{file}';

const cloudStorageHeadRevisionUrl = `https://storage.googleapis.com/chromium-browser-snapshots/{platform}/LAST_CHANGE`;

/**
* Map a platform to the platfrom key used by the Chromium snapshot buildbot.
* See: https://commondatastorage.googleapis.com/chromium-browser-snapshots/index.html.
*/
const PlatformSnapshotNameMap = {
[Platform.LINUX_X64]: 'Linux_x64',
[Platform.MAC_X64]: 'Mac',
[Platform.MAC_ARM64]: 'Mac_Arm',
[Platform.WINDOWS_X64]: 'Win',
};

/** Maps a browser platform to the snapshot archive file containing the browser binary. */
const PlatformBrowserArchiveMap = {
[Platform.LINUX_X64]: 'chrome-linux.zip',
[Platform.MAC_X64]: 'chrome-mac.zip',
[Platform.MAC_ARM64]: 'chrome-mac.zip',
[Platform.WINDOWS_X64]: 'chrome-win.zip',
};

/** Maps a browser platform to the archive file containing the driver. */
const PlatformDriverArchiveMap = {
[Platform.LINUX_X64]: 'chromedriver_linux64.zip',
[Platform.MAC_X64]: 'chromedriver_mac64.zip',
[Platform.MAC_ARM64]: 'chromedriver_mac64.zip',
[Platform.WINDOWS_X64]: 'chromedriver_win32.zip',
};

/** List of supported platforms for the Chromium binaries. */
const supportedPlatforms = new Set([
Platform.LINUX_X64,
Platform.MAC_X64,
Platform.MAC_ARM64,
Platform.WINDOWS_X64,
]);

/** Class providing necessary information for the chromium browser. */
export class Chromium implements Browser<number> {
name = 'chromium';

constructor(public revision: number) {}

supports(platform: Platform): boolean {
return supportedPlatforms.has(platform);
}

getArtifact(platform: Platform, type: ArtifactType): BrowserArtifact {
return new BrowserArtifact(this, type, this.getDownloadUrl(platform, type));
}

getDownloadUrl(platform: Platform, type: ArtifactType): string {
return Chromium.getDownloadArtifactUrl(this.revision, platform, type);
}

static getDownloadArtifactUrl(revision: number, platform: Platform, type: ArtifactType): string {
const archiveMap = type === 'driver-bin' ? PlatformDriverArchiveMap : PlatformBrowserArchiveMap;
return cloudStorageArchiveUrl
.replace('{platform}', PlatformSnapshotNameMap[platform])
.replace('{revision}', `${revision}`)
.replace('{file}', archiveMap[platform]);
}

static getLatestRevisionUrl(platform: Platform) {
return cloudStorageHeadRevisionUrl.replace('{platform}', PlatformSnapshotNameMap[platform]);
}
}
Loading

0 comments on commit 25634f9

Please sign in to comment.