install.js 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. /**
  2. * Copyright 2017 Google Inc. All rights reserved.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. import assert from 'assert';
  17. import { existsSync } from 'fs';
  18. import { mkdir, unlink } from 'fs/promises';
  19. import os from 'os';
  20. import path from 'path';
  21. import { downloadUrls, } from './browser-data/browser-data.js';
  22. import { Cache } from './Cache.js';
  23. import { debug } from './debug.js';
  24. import { detectBrowserPlatform } from './detectPlatform.js';
  25. import { unpackArchive } from './fileUtil.js';
  26. import { downloadFile, headHttpRequest } from './httpUtil.js';
  27. const debugInstall = debug('puppeteer:browsers:install');
  28. const times = new Map();
  29. function debugTime(label) {
  30. times.set(label, process.hrtime());
  31. }
  32. function debugTimeEnd(label) {
  33. const end = process.hrtime();
  34. const start = times.get(label);
  35. if (!start) {
  36. return;
  37. }
  38. const duration = end[0] * 1000 + end[1] / 1e6 - (start[0] * 1000 + start[1] / 1e6); // calculate duration in milliseconds
  39. debugInstall(`Duration for ${label}: ${duration}ms`);
  40. }
  41. /**
  42. * @public
  43. */
  44. export async function install(options) {
  45. options.platform ??= detectBrowserPlatform();
  46. options.unpack ??= true;
  47. if (!options.platform) {
  48. throw new Error(`Cannot download a binary for the provided platform: ${os.platform()} (${os.arch()})`);
  49. }
  50. const url = getDownloadUrl(options.browser, options.platform, options.buildId, options.baseUrl);
  51. const fileName = url.toString().split('/').pop();
  52. assert(fileName, `A malformed download URL was found: ${url}.`);
  53. const structure = new Cache(options.cacheDir);
  54. const browserRoot = structure.browserRoot(options.browser);
  55. const archivePath = path.join(browserRoot, fileName);
  56. if (!existsSync(browserRoot)) {
  57. await mkdir(browserRoot, { recursive: true });
  58. }
  59. if (!options.unpack) {
  60. if (existsSync(archivePath)) {
  61. return {
  62. path: archivePath,
  63. browser: options.browser,
  64. platform: options.platform,
  65. buildId: options.buildId,
  66. };
  67. }
  68. debugInstall(`Downloading binary from ${url}`);
  69. debugTime('download');
  70. await downloadFile(url, archivePath, options.downloadProgressCallback);
  71. debugTimeEnd('download');
  72. return {
  73. path: archivePath,
  74. browser: options.browser,
  75. platform: options.platform,
  76. buildId: options.buildId,
  77. };
  78. }
  79. const outputPath = structure.installationDir(options.browser, options.platform, options.buildId);
  80. if (existsSync(outputPath)) {
  81. return {
  82. path: outputPath,
  83. browser: options.browser,
  84. platform: options.platform,
  85. buildId: options.buildId,
  86. };
  87. }
  88. try {
  89. debugInstall(`Downloading binary from ${url}`);
  90. try {
  91. debugTime('download');
  92. await downloadFile(url, archivePath, options.downloadProgressCallback);
  93. }
  94. finally {
  95. debugTimeEnd('download');
  96. }
  97. debugInstall(`Installing ${archivePath} to ${outputPath}`);
  98. try {
  99. debugTime('extract');
  100. await unpackArchive(archivePath, outputPath);
  101. }
  102. finally {
  103. debugTimeEnd('extract');
  104. }
  105. }
  106. finally {
  107. if (existsSync(archivePath)) {
  108. await unlink(archivePath);
  109. }
  110. }
  111. return {
  112. path: outputPath,
  113. browser: options.browser,
  114. platform: options.platform,
  115. buildId: options.buildId,
  116. };
  117. }
  118. /**
  119. *
  120. * @public
  121. */
  122. export async function uninstall(options) {
  123. options.platform ??= detectBrowserPlatform();
  124. if (!options.platform) {
  125. throw new Error(`Cannot detect the browser platform for: ${os.platform()} (${os.arch()})`);
  126. }
  127. new Cache(options.cacheDir).uninstall(options.browser, options.platform, options.buildId);
  128. }
  129. /**
  130. * Returns metadata about browsers installed in the cache directory.
  131. *
  132. * @public
  133. */
  134. export async function getInstalledBrowsers(options) {
  135. return new Cache(options.cacheDir).getInstalledBrowsers();
  136. }
  137. /**
  138. * @public
  139. */
  140. export async function canDownload(options) {
  141. options.platform ??= detectBrowserPlatform();
  142. if (!options.platform) {
  143. throw new Error(`Cannot download a binary for the provided platform: ${os.platform()} (${os.arch()})`);
  144. }
  145. return await headHttpRequest(getDownloadUrl(options.browser, options.platform, options.buildId, options.baseUrl));
  146. }
  147. function getDownloadUrl(browser, platform, buildId, baseUrl) {
  148. return new URL(downloadUrls[browser](platform, buildId, baseUrl));
  149. }
  150. //# sourceMappingURL=install.js.map