fileUtil.js 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. /**
  2. * Copyright 2023 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 { exec as execChildProcess } from 'child_process';
  17. import { createReadStream } from 'fs';
  18. import { mkdir, readdir } from 'fs/promises';
  19. import * as path from 'path';
  20. import { promisify } from 'util';
  21. import extractZip from 'extract-zip';
  22. import tar from 'tar-fs';
  23. import bzip from 'unbzip2-stream';
  24. const exec = promisify(execChildProcess);
  25. /**
  26. * @internal
  27. */
  28. export async function unpackArchive(archivePath, folderPath) {
  29. if (archivePath.endsWith('.zip')) {
  30. await extractZip(archivePath, { dir: folderPath });
  31. }
  32. else if (archivePath.endsWith('.tar.bz2')) {
  33. await extractTar(archivePath, folderPath);
  34. }
  35. else if (archivePath.endsWith('.dmg')) {
  36. await mkdir(folderPath);
  37. await installDMG(archivePath, folderPath);
  38. }
  39. else {
  40. throw new Error(`Unsupported archive format: ${archivePath}`);
  41. }
  42. }
  43. /**
  44. * @internal
  45. */
  46. function extractTar(tarPath, folderPath) {
  47. return new Promise((fulfill, reject) => {
  48. const tarStream = tar.extract(folderPath);
  49. tarStream.on('error', reject);
  50. tarStream.on('finish', fulfill);
  51. const readStream = createReadStream(tarPath);
  52. readStream.pipe(bzip()).pipe(tarStream);
  53. });
  54. }
  55. /**
  56. * @internal
  57. */
  58. async function installDMG(dmgPath, folderPath) {
  59. const { stdout } = await exec(`hdiutil attach -nobrowse -noautoopen "${dmgPath}"`);
  60. const volumes = stdout.match(/\/Volumes\/(.*)/m);
  61. if (!volumes) {
  62. throw new Error(`Could not find volume path in ${stdout}`);
  63. }
  64. const mountPath = volumes[0];
  65. try {
  66. const fileNames = await readdir(mountPath);
  67. const appName = fileNames.find(item => {
  68. return typeof item === 'string' && item.endsWith('.app');
  69. });
  70. if (!appName) {
  71. throw new Error(`Cannot find app in ${mountPath}`);
  72. }
  73. const mountedPath = path.join(mountPath, appName);
  74. await exec(`cp -R "${mountedPath}" "${folderPath}"`);
  75. }
  76. finally {
  77. await exec(`hdiutil detach "${mountPath}" -quiet`);
  78. }
  79. }
  80. //# sourceMappingURL=fileUtil.js.map