|
1 | | -import * as os from 'os' |
2 | 1 | import * as vscode from 'vscode' |
3 | 2 | import * as fs from 'fs' |
4 | 3 | import * as path from 'path' |
5 | 4 | import { exec } from 'child_process' |
6 | | -import { promisify } from 'util' |
7 | 5 | import { Config } from '../common/config' |
8 | 6 | import { Repository } from '../api/client' |
| 7 | +import Logger from '../common/logger' |
9 | 8 |
|
10 | | -const execAsync = promisify(exec) |
| 9 | +const CLI_FILE_NAME = 'cli.sh' |
| 10 | +const CLI_FOLDER_NAME = '.codacy' |
| 11 | +const CLI_COMMAND = `${CLI_FOLDER_NAME}/${CLI_FILE_NAME}` |
| 12 | + |
| 13 | +// Set a larger buffer size (10MB) |
| 14 | +const MAX_BUFFER_SIZE = 1024 * 1024 * 10 |
| 15 | + |
| 16 | +const execAsync = (command: string) => { |
| 17 | + const workspacePath = vscode.workspace.workspaceFolders?.[0]?.uri.fsPath || '' |
| 18 | + |
| 19 | + return new Promise((resolve, reject) => { |
| 20 | + exec( |
| 21 | + `CODACY_CLI_V2_VERSION=1.0.0-main.232.a6a6368 ${command}`, |
| 22 | + { |
| 23 | + cwd: workspacePath, |
| 24 | + maxBuffer: MAX_BUFFER_SIZE, // To solve: stdout maxBuffer exceeded |
| 25 | + }, |
| 26 | + (error, stdout, stderr) => { |
| 27 | + if (error) { |
| 28 | + reject(error) |
| 29 | + return |
| 30 | + } |
| 31 | + |
| 32 | + if (stderr && (!stdout || /error|fail|exception/i.test(stderr))) { |
| 33 | + reject(new Error(stderr)) |
| 34 | + return |
| 35 | + } |
| 36 | + |
| 37 | + resolve({ stdout, stderr }) |
| 38 | + } |
| 39 | + ) |
| 40 | + }) |
| 41 | +} |
11 | 42 |
|
12 | 43 | export async function isCLIInstalled(): Promise<boolean> { |
13 | 44 | try { |
14 | | - await execAsync('codacy-cli --help') |
| 45 | + await execAsync(`${CLI_COMMAND} --help`) |
15 | 46 | return true |
16 | 47 | } catch { |
17 | 48 | return false |
18 | 49 | } |
19 | 50 | } |
20 | 51 |
|
21 | | -async function isBrewInstalled(): Promise<boolean> { |
22 | | - try { |
23 | | - await execAsync('brew --version') |
24 | | - return true |
25 | | - } catch { |
26 | | - return false |
| 52 | +async function downloadCodacyCLI(): Promise<void> { |
| 53 | + const workspacePath = vscode.workspace.workspaceFolders?.[0]?.uri.fsPath || '' |
| 54 | + const codacyFolder = path.join(workspacePath, CLI_FOLDER_NAME) |
| 55 | + const codacyCliPath = path.join(codacyFolder, CLI_FILE_NAME) |
| 56 | + |
| 57 | + // Create .codacy folder if it doesn't exist |
| 58 | + if (!fs.existsSync(codacyFolder)) { |
| 59 | + fs.mkdirSync(codacyFolder, { recursive: true }) |
| 60 | + } |
| 61 | + |
| 62 | + // Download cli.sh if it doesn't exist |
| 63 | + if (!fs.existsSync(codacyCliPath)) { |
| 64 | + await execAsync( |
| 65 | + `curl -Ls -o "${CLI_COMMAND}" https://raw.githubusercontent.com/codacy/codacy-cli-v2/main/codacy-cli.sh` |
| 66 | + ) |
| 67 | + |
| 68 | + await execAsync(`chmod +x "${CLI_COMMAND}"`) |
27 | 69 | } |
28 | 70 | } |
29 | 71 |
|
30 | | -async function initializeCLI(repository: Repository): Promise<void> { |
| 72 | +async function initializeCLI(repository?: Repository): Promise<void> { |
31 | 73 | const workspacePath = vscode.workspace.workspaceFolders?.[0]?.uri.fsPath || '' |
32 | 74 | const codacyYamlPath = path.join(workspacePath, '.codacy', 'codacy.yaml') |
33 | | - const apiToken = Config.apiToken |
34 | 75 |
|
35 | | - const { provider, owner: organization, name: repositoryName } = repository |
| 76 | + const apiToken = Config.apiToken ? `--api-token ${Config.apiToken}` : '' |
| 77 | + const repositoryAccess = repository |
| 78 | + ? `--provider ${repository.provider} --organization ${repository.owner} --repository ${repository.name}` |
| 79 | + : '' |
36 | 80 |
|
37 | | - try { |
38 | | - if (!fs.existsSync(codacyYamlPath)) { |
39 | | - await execAsync( |
40 | | - `codacy-cli init --api-token ${apiToken} --provider ${provider} --organization ${organization} --repository ${repositoryName}` |
41 | | - ) |
42 | | - } |
43 | | - await execAsync('codacy-cli install') |
44 | | - } catch (error) { |
45 | | - if (error instanceof Error) { |
46 | | - throw new Error(`Failed to initialize Codacy CLI: ${error.message}`) |
47 | | - } |
48 | | - throw error |
| 81 | + if (!fs.existsSync(codacyYamlPath)) { |
| 82 | + await execAsync(`${CLI_COMMAND} init ${apiToken} ${repositoryAccess}`) |
49 | 83 | } |
50 | | -} |
51 | 84 |
|
52 | | -export async function installCodacyCLI(repository: Repository): Promise<void> { |
53 | | - const platform = os.platform() |
| 85 | + await execAsync(`${CLI_COMMAND} install`) |
54 | 86 |
|
55 | | - if (await isCLIInstalled()) { |
56 | | - await initializeCLI(repository) |
57 | | - return |
| 87 | + // add cli.sh to .gitignore |
| 88 | + const gitignorePath = path.join(workspacePath, '.codacy', '.gitignore') |
| 89 | + if (!fs.existsSync(gitignorePath)) { |
| 90 | + fs.writeFileSync(gitignorePath, '*.sh\n') |
| 91 | + } else { |
| 92 | + const gitignoreContent = fs.readFileSync(gitignorePath, 'utf8') |
| 93 | + if (!gitignoreContent.includes('*.sh')) { |
| 94 | + fs.appendFileSync(gitignorePath, '*.sh\n') |
| 95 | + } |
58 | 96 | } |
| 97 | +} |
59 | 98 |
|
| 99 | +export async function installCodacyCLI(repository?: Repository): Promise<void> { |
60 | 100 | try { |
61 | | - switch (platform) { |
62 | | - case 'darwin': |
63 | | - if (!(await isBrewInstalled())) { |
64 | | - throw new Error('Please install Homebrew first and then try installing the Codacy CLI again.') |
65 | | - } |
66 | | - await execAsync('brew install codacy/codacy-cli-v2/codacy-cli-v2') |
67 | | - break |
68 | | - |
69 | | - case 'linux': |
70 | | - throw new Error( |
71 | | - 'Codacy CLI cannot be automatically installed on Linux yet. For manual installation, please refer to the [Codacy CLI documentation](https://github.com/codacy/codacy-cli-v2).' |
72 | | - ) |
73 | | - break |
74 | | - |
75 | | - case 'win32': |
76 | | - throw new Error('Codacy CLI is not supported on Windows yet.') |
| 101 | + const isInstalled = await isCLIInstalled() |
77 | 102 |
|
78 | | - default: |
79 | | - throw new Error(`Unsupported operating system: ${platform}`) |
| 103 | + if (!isInstalled) { |
| 104 | + await downloadCodacyCLI() |
80 | 105 | } |
81 | 106 |
|
82 | 107 | await initializeCLI(repository) |
83 | 108 | } catch (error) { |
84 | 109 | if (error instanceof Error) { |
85 | | - throw new Error(`Failed to install Codacy CLI: ${error.message}`) |
| 110 | + Logger.error(`Failed to install Codacy CLI: ${error.message}`) |
86 | 111 | } |
87 | 112 | throw error |
88 | 113 | } |
|
0 commit comments