Skip to content

Commit 4f54f7c

Browse files
committed
refactor
1 parent f47b196 commit 4f54f7c

File tree

2 files changed

+54
-194
lines changed

2 files changed

+54
-194
lines changed

src/main/osinstaller/CxInstaller.ts

Lines changed: 51 additions & 141 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
11
import * as fs from 'fs/promises';
2+
import * as fs1 from "fs"
23
import * as path from 'path';
3-
import AdmZip from 'adm-zip'; // For extracting ZIP files
44
import * as tar from 'tar';
55
import axios from 'axios';
6-
import {createWriteStream} from "node:fs";
6+
import * as unzipper from "unzipper";
77

88

99
export class CxInstaller {
1010
private readonly platform: string;
1111
private cliVersion: string;
12+
private readonly resourceDirPath: string;
1213

1314
constructor(platform: string) {
1415
this.platform = platform;
16+
this.resourceDirPath = path.join(__dirname, `../wrapper/resources`);
1517
}
1618

1719
// Method to get the download URL based on OS and architecture
@@ -42,119 +44,73 @@ export class CxInstaller {
4244

4345
getExecutablePath(): string {
4446
let executablePath;
45-
const dirExecutablePath = path.join(__dirname, `../wrapper/resources`);
4647
if (this.platform === 'win32') {
47-
executablePath = path.join(dirExecutablePath, 'cx.exe');
48+
executablePath = path.join(this.resourceDirPath, 'cx.exe');
4849
} else {
49-
executablePath = path.join(dirExecutablePath, 'cx');
50+
executablePath = path.join(this.resourceDirPath, 'cx');
5051
}
5152
return executablePath;
5253
}
5354

54-
getZipPath(): string {
55-
let executablePath;
56-
const dirExecutablePath = path.join(__dirname, `../wrapper/resources/`);
57-
if (this.platform === 'win32') {
58-
executablePath = path.join(dirExecutablePath, 'cx.zip');
59-
} else {
60-
executablePath = path.join(dirExecutablePath, 'cx.tar.gz');
61-
}
62-
return executablePath;
63-
}
64-
65-
async getCLIExecutableName(): Promise<string> {
66-
let platformString: string;
67-
let archiveExtension: string;
68-
this.cliVersion = await this.readASTCLIVersion();
69-
70-
switch (this.platform) {
71-
case 'win32':
72-
platformString = 'windows';
73-
archiveExtension = 'zip';
74-
break;
75-
case 'darwin':
76-
archiveExtension = 'tar.gz';
77-
platformString = 'darwin';
78-
break;
79-
case 'linux':
80-
archiveExtension = 'tar.gz';
81-
platformString = 'linux';
82-
break;
83-
default:
84-
throw new Error('Unsupported platform or architecture');
85-
}
86-
87-
return `ast-cli_${this.cliVersion}_${platformString}_x64.${archiveExtension}`;
88-
}
89-
90-
removeExtension(fileName: string): string {
91-
if (fileName.endsWith('.tar.gz')) {
92-
return fileName.slice(0, -7); // Remove '.tar.gz'
55+
async downloadIfNotInstalledCLI() {
56+
if (!this.checkExecutableExists()) {
57+
const url = await this.getDownloadURL();
58+
const zipPath = this.getZipPath();
59+
try {
60+
await this.downloadFile(url, zipPath);
61+
console.log('Downloaded CLI to:', zipPath);
62+
63+
await this.extractArchive(zipPath, this.resourceDirPath);
64+
console.log('Extracted CLI to:', this.resourceDirPath);
65+
console.log('Done!');
66+
} catch (error) {
67+
console.error('Error:', error);
68+
}
9369
}
94-
return fileName.replace(/\.[^/.]+$/, ''); // Remove other extensions like '.zip'
9570
}
9671

97-
98-
99-
// Method to extract the file (ZIP or tar.gz)
100-
async extractFile(filePath: string, outputDir: string): Promise<void> {
101-
if (filePath.endsWith('.zip')) {
102-
// Extract ZIP file
103-
const zip = new AdmZip(filePath);
104-
zip.extractAllTo(outputDir, true); // Extract to outputDir
105-
console.log(`Extracted ZIP to ${outputDir}`);
106-
} else if (filePath.endsWith('.tar.gz')) {
107-
// Extract tar.gz file
108-
await tar.extract({
109-
file: filePath,
110-
cwd: outputDir, // Extract to the outputDir
111-
});
112-
console.log(`Extracted tar.gz to ${outputDir}`);
72+
async extractArchive(zipPath: string, extractPath: string): Promise<void> {
73+
if (zipPath.endsWith('.zip')) {
74+
console.log('Extracting ZIP file...');
75+
// Use unzipper to extract ZIP files
76+
await unzipper.Open.file(zipPath)
77+
.then(d => d.extract({path: extractPath}));
78+
console.log('Extracted ZIP file to:', extractPath);
79+
} else if (zipPath.endsWith('.tar.gz')) {
80+
console.log('Extracting TAR.GZ file...');
81+
// Use tar.extract to extract TAR.GZ files
82+
await tar.extract({file: zipPath, cwd: extractPath});
83+
console.log('Extracted TAR.GZ file to:', extractPath);
11384
} else {
114-
throw new Error('Unsupported archive format');
85+
console.error('Unsupported file type. Only .zip and .tar.gz are supported.');
11586
}
11687
}
11788

118-
// Method to execute the installation
119-
async install(outputPath: string): Promise<void> {
120-
const exists = await this.checkExecutableExists();
121-
if (exists) {
122-
console.log('Executable already exists. Skipping installation.');
123-
return;
124-
}
125-
126-
const url = await this.getDownloadURL();
127-
if (!url) {
128-
console.error('No valid download URL available for this platform.');
129-
return;
130-
}
131-
132-
try {
133-
console.log(`Downloading from: ${url}`);
134-
await downloadFile(url, outputPath);
135-
console.log(`Downloaded to: ${outputPath}`);
136-
137-
// Now extract the downloaded archive
138-
} catch (error) {
139-
console.error(`Error during installation: ${error.message}`);
140-
}
89+
async downloadFile(url: string, outputPath: string) {
90+
const writer = fs1.createWriteStream(outputPath);
91+
const response = await axios({url, responseType: 'stream'});
92+
response.data.pipe(writer);
93+
return new Promise((resolve, reject) => {
94+
writer.on('finish', resolve);
95+
writer.on('error', reject);
96+
});
14197
}
14298

143-
// Check if the executable exists
144-
async checkExecutableExists(): Promise<boolean> {
99+
getZipPath(): string {
145100
let executablePath;
146-
const dirExecutablePath = path.join(__dirname, `../../wrapper/resources/`);
147101
if (this.platform === 'win32') {
148-
executablePath = path.join(dirExecutablePath, 'cx.exe');
102+
executablePath = path.join(this.resourceDirPath, 'cx.zip');
149103
} else {
150-
executablePath = path.join(dirExecutablePath, 'cx');
104+
executablePath = path.join(this.resourceDirPath, 'cx.tar.gz');
151105
}
152-
try {
153-
await fs.access(executablePath);
154-
console.log(`Executable exists at: ${executablePath}`);
106+
return executablePath;
107+
}
108+
109+
checkExecutableExists(): boolean {
110+
if (fs1.existsSync(this.getExecutablePath())){
111+
console.log('Executable exists:', this.getExecutablePath());
155112
return true;
156-
} catch (error) {
157-
console.error(`Executable does not exist at: ${executablePath}`);
113+
} else {
158114
return false;
159115
}
160116
}
@@ -175,49 +131,3 @@ export class CxInstaller {
175131
}
176132
}
177133

178-
async function downloadFile(downloadURLPath: string, filePath: string): Promise<void> {
179-
const fileName = "cx";
180-
console.log(`Downloading ${fileName} from: ${downloadURLPath}`);
181-
182-
try {
183-
// Ensure the directory exists
184-
await fs.mkdir(path.dirname(downloadURLPath), { recursive: true });
185-
186-
// Check if filePath is a directory
187-
try {
188-
const stats = await fs.stat(filePath);
189-
if (stats.isDirectory()) {
190-
// If it's a directory, append the filename from the URL
191-
filePath = path.join(filePath, path.basename(downloadURLPath));
192-
}
193-
} catch (error) {
194-
// If the path doesn't exist, assume it's meant to be a file
195-
// The directory has already been created above
196-
}
197-
198-
// Perform HTTP GET request
199-
const response = await axios({
200-
method: 'GET',
201-
url: downloadURLPath,
202-
responseType: 'stream'
203-
});
204-
// Create the file stream at the specified filePath
205-
const fileStream = createWriteStream(process.cwd()+"/src/main/wrapper/resources/cx");
206-
207-
// Pipe the response data to the file
208-
response.data.pipe(fileStream);
209-
210-
// Wait for the file to finish writing
211-
await new Promise<void>((resolve, reject) => {
212-
fileStream.on('finish', resolve);
213-
fileStream.on('error', reject);
214-
});
215-
216-
console.log(`File downloaded successfully to ${filePath}`);
217-
218-
} catch (error) {
219-
console.log(`Error during file download:` + error.message);
220-
throw new Error(`Invoking HTTP request to download file failed - ${error.message}`);
221-
}
222-
}
223-

src/main/wrapper/CxWrapper.ts

Lines changed: 3 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,9 @@ import {CxConstants} from "./CxConstants";
44
import {ExecutionService} from "./ExecutionService";
55
import {CxCommandOutput} from "./CxCommandOutput";
66
import {getLoggerWithFilePath, logger} from "./loggerConfig";
7-
import * as fs from "fs"
87
import * as os from "os";
98
import CxBFL from "../bfl/CxBFL";
109
import {CxInstaller} from "../osinstaller/CxInstaller";
11-
import * as tar from 'tar';
12-
import axios from "axios";
13-
import * as unzipper from 'unzipper'; // For ZIP files
1410

1511

1612
type ParamTypeMap = Map<CxParamType, string>;
@@ -59,30 +55,11 @@ export class CxWrapper {
5955
}
6056
}
6157

62-
async downloadIfNotInstalledCLI(os: string) {
63-
64-
const cxInstaller = new CxInstaller(os);
65-
await cxInstaller.install('/resources');
66-
}
67-
6858
async initializeCommands(formatRequired: boolean): Promise<string[]> {
6959
const cxInstaller = new CxInstaller(process.platform);
60+
await cxInstaller.downloadIfNotInstalledCLI()
7061
this.config.pathToExecutable = cxInstaller.getExecutablePath();
71-
if (!fs.existsSync(cxInstaller.getExecutablePath())) {
72-
const url = await cxInstaller.getDownloadURL();
73-
const zipPath = cxInstaller.getZipPath();
74-
const extractPath = __dirname+"/"+ 'resources';
75-
try {
76-
await this.downloadFile(url, zipPath);
77-
console.log('Downloaded CLI to:', zipPath);
78-
79-
await this.extractArchive(zipPath, extractPath);
80-
console.log('Extracted CLI to:', extractPath);
81-
console.log('Done!');
82-
} catch (error) {
83-
console.error('Error:', error);
84-
}
85-
}
62+
8663
const list: string[] = [];
8764
if (this.config.clientId) {
8865
list.push(CxConstants.CLIENT_ID);
@@ -120,33 +97,6 @@ export class CxWrapper {
12097
return list;
12198
}
12299

123-
124-
async extractArchive(zipPath: string, extractPath: string): Promise<void> {
125-
if (zipPath.endsWith('.zip')) {
126-
console.log('Extracting ZIP file...');
127-
// Use unzipper to extract ZIP files
128-
await unzipper.Open.file(zipPath)
129-
.then(d => d.extract({ path: extractPath }));
130-
console.log('Extracted ZIP file to:', extractPath);
131-
} else if (zipPath.endsWith('.tar.gz')) {
132-
console.log('Extracting TAR.GZ file...');
133-
// Use tar.extract to extract TAR.GZ files
134-
await tar.extract({ file: zipPath, cwd: extractPath });
135-
console.log('Extracted TAR.GZ file to:', extractPath);
136-
} else {
137-
console.error('Unsupported file type. Only .zip and .tar.gz are supported.');
138-
}
139-
}
140-
async downloadFile(url: string, outputPath: string){
141-
const writer = fs.createWriteStream(outputPath);
142-
const response = await axios({url, responseType: 'stream'});
143-
response.data.pipe(writer);
144-
return new Promise((resolve, reject) => {
145-
writer.on('finish', resolve);
146-
writer.on('error', reject);
147-
});
148-
}
149-
150100
async authValidate(): Promise<CxCommandOutput> {
151101
const commands: string[] = [CxConstants.CMD_AUTH, CxConstants.SUB_CMD_VALIDATE];
152102
commands.push(...await this.initializeCommands(false));
@@ -306,7 +256,7 @@ export class CxWrapper {
306256
commands.push(CxConstants.AGENT);
307257
commands.push(agent);
308258
}
309-
commands.push(... await this.initializeCommands(false));
259+
commands.push(...await this.initializeCommands(false));
310260
return commands;
311261
}
312262

0 commit comments

Comments
 (0)