Skip to content

Commit

Permalink
Cleanup archive extraction
Browse files Browse the repository at this point in the history
  • Loading branch information
jakub-gonet committed Oct 2, 2024
1 parent 307e858 commit 07a99c4
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 35 deletions.
41 changes: 24 additions & 17 deletions packages/vscode-extension/src/builders/eas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,19 @@ import { Logger } from "../Logger";
import { CancelToken } from "./cancelToken";
import { exec } from "../utilities/subprocess";
import { downloadBinary } from "../utilities/common";
import { listEasBuilds, viewEasBuild } from "./easCommand";
import { EASBuild, listEasBuilds, viewEasBuild } from "./easCommand";

export async function fetchEasBuild(
cancelToken: CancelToken,
config: EasConfig,
platform: DevicePlatform
): Promise<string | undefined> {
const binaryUrl = await fetchBuildUrl(config, platform);
if (!binaryUrl) {
const build = await fetchBuild(config, platform);
if (!build) {
return undefined;
}

let easBinaryPath = await downloadAppFromEas(binaryUrl, platform, cancelToken);
let easBinaryPath = await downloadAppFromEas(build, platform, cancelToken);
if (!easBinaryPath) {
return undefined;
}
Expand All @@ -30,7 +30,7 @@ export async function fetchEasBuild(
return easBinaryPath;
}

async function fetchBuildUrl(config: EasConfig, platform: DevicePlatform) {
async function fetchBuild(config: EasConfig, platform: DevicePlatform) {
if (config.buildUUID) {
const build = await viewEasBuild(config.buildUUID, platform);
if (!build) {
Expand All @@ -44,7 +44,8 @@ async function fetchBuildUrl(config: EasConfig, platform: DevicePlatform) {
return undefined;
}

return build.binaryUrl;
Logger.debug(`Using EAS build artifact with ID ${build.id}.`);
return build;
}

const builds = await listEasBuilds(platform, config.profile);
Expand All @@ -61,23 +62,28 @@ async function fetchBuildUrl(config: EasConfig, platform: DevicePlatform) {
return undefined;
}

return maxBy(builds, "completedAt")!.binaryUrl;
const build = maxBy(builds, "completedAt")!;

Logger.debug(`Using EAS build artifact with ID ${build.id}.`);
return build;
}

async function downloadAppFromEas(
binaryUrl: string,
build: EASBuild,
platform: DevicePlatform,
cancelToken: CancelToken
) {
function isAppFile(name: string) {
return name.endsWith(".app");
}

const { id, binaryUrl } = build;

const tmpDirectory = await mkdtemp(path.join(os.tmpdir(), "rn-ide-eas-build-"));
// URL should be in format "https://expo.dev/artifacts/eas/ID.apk", where ID
// is unique identifier.
const binaryPath = await downloadBinary(binaryUrl, tmpDirectory);
if (!binaryPath) {
const binaryPath = path.join(tmpDirectory, id);

const success = await downloadBinary(binaryUrl, binaryPath);
if (!success) {
Logger.error(`Failed to download archive from '${binaryUrl}'.`);
return undefined;
}
Expand All @@ -87,21 +93,22 @@ async function downloadAppFromEas(
return binaryPath;
}

const extractDir = path.dirname(binaryPath);
const { failed } = await cancelToken.adapt(tarCommand({ archivePath: binaryPath, extractDir }));
const { failed } = await cancelToken.adapt(
tarCommand({ archivePath: binaryPath, extractDir: tmpDirectory })
);
if (failed) {
Logger.error(`Failed to extract archive '${binaryPath}' to '${extractDir}'.`);
Logger.error(`Failed to extract archive '${binaryPath}' to '${tmpDirectory}'.`);
return undefined;
}

// assuming that the archive contains only one .app file
const appName = (await readdir(extractDir)).find(isAppFile);
const appName = (await readdir(tmpDirectory)).find(isAppFile);
if (!appName) {
Logger.error(`Failed to find .app in extracted archive '${binaryPath}'.`);
return undefined;
}

const appPath = path.join(extractDir, appName);
const appPath = path.join(tmpDirectory, appName);
Logger.debug(`Extracted app archive to '${appPath}'.`);
return appPath;
}
Expand Down
4 changes: 3 additions & 1 deletion packages/vscode-extension/src/builders/easCommand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { exec } from "../utilities/subprocess";
type UnixTimestamp = number;

export type EASBuild = {
id: string;
platform: DevicePlatform;
binaryUrl: string;
appVersion: string;
Expand Down Expand Up @@ -93,8 +94,9 @@ function parseEasBuildOutput(stdout: string, platform: DevicePlatform): EASBuild

return isFinished && isUsableForDevice && platformMapping[easPlatform] === platform;
})
.map(({ platform: easPlatform, artifacts, completedAt, appVersion, expirationDate }) => {
.map(({ id, platform: easPlatform, artifacts, completedAt, appVersion, expirationDate }) => {
return {
id,
platform: platformMapping[easPlatform],
binaryUrl: artifacts.applicationArchiveUrl,
appVersion,
Expand Down
27 changes: 10 additions & 17 deletions packages/vscode-extension/src/utilities/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,36 +157,29 @@ function isPidRunning(pid: number) {
}
}

export async function downloadBinary(url: string, directory: string) {
const filename = url.split("/").pop();
const hasInvalidFormat = !filename;
if (hasInvalidFormat) {
return undefined;
}

export async function downloadBinary(url: string, destination: string) {
let body: NodeJS.ReadableStream;
let ok: boolean;
try {
const result = await fetch(url);
if (!result.body) {
return undefined;
return false;
}
body = result.body;
ok = result.ok;
} catch (_e) {
// Network error
return undefined;
return false;
}

if (ok) {
const destination = path.resolve(directory, filename);
const fileStream = fs.createWriteStream(destination, { flags: "wx" });
await finished(body.pipe(fileStream));

return destination.toString();
} else {
return undefined;
if (!ok) {
return false;
}

const fileStream = fs.createWriteStream(destination, { flags: "w" });
await finished(body.pipe(fileStream));

return true;
}

async function calculateFileMD5(filePath: string, hash: Hash) {
Expand Down

0 comments on commit 07a99c4

Please sign in to comment.