Skip to content

Commit bce5297

Browse files
committed
feat: improve update command error handling and make it fully automatic
- Remove all user prompts and make update process automatic - Improve installation method detection with more path patterns - Add intelligent error handling for 'file already exists' (EEXIST) errors - Convert EEXIST errors to success messages indicating latest version is installed - Add similar error handling for Homebrew 'already installed' messages - Improve fallback logic when installation method detection fails - Add --force flag suggestion for npm update failures Now when the latest version is already installed, instead of showing: '✗ Error: Failed to update via npm: Command failed with exit code 1' It shows: '✓ Success: Latest version is already installed via npm!' The update process is now completely automatic with no user prompts.
1 parent 2425646 commit bce5297

File tree

1 file changed

+46
-57
lines changed

1 file changed

+46
-57
lines changed

templates/cli/lib/commands/update.js.twig

Lines changed: 46 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,21 @@ const { version } = require("../../package.json");
1414
*/
1515
const isInstalledViaNpm = () => {
1616
try {
17-
// Check if we're in a global npm installation
18-
const execPath = process.argv[0];
1917
const scriptPath = process.argv[1];
2018

2119
// Common indicators of npm global installation
2220
if (scriptPath.includes('node_modules') && scriptPath.includes('appwrite-cli')) {
2321
return true;
2422
}
2523

26-
// Check if npm is available and appwrite-cli is installed globally
24+
// Check for npm global paths
25+
if (scriptPath.includes('/usr/local/lib/node_modules/') ||
26+
scriptPath.includes('/opt/homebrew/lib/node_modules/') ||
27+
scriptPath.includes('/.npm-global/') ||
28+
scriptPath.includes('/node_modules/.bin/')) {
29+
return true;
30+
}
31+
2732
return false;
2833
} catch (e) {
2934
return false;
@@ -110,8 +115,14 @@ const updateViaNpm = async () => {
110115
success("Updated to latest version via npm!");
111116
hint("Run '{{ language.params.executableName|caseLower }} --version' to verify the new version.");
112117
} catch (e) {
113-
error(`Failed to update via npm: ${e.message}`);
114-
hint("Try running: npm install -g {{ language.params.npmPackage|caseDash }}@latest");
118+
// Check if error is due to file already existing (likely already latest version)
119+
if (e.message.includes('EEXIST') || e.message.includes('file already exists')) {
120+
success("Latest version is already installed via npm!");
121+
hint("The CLI is up to date. Run '{{ language.params.executableName|caseLower }} --version' to verify.");
122+
} else {
123+
error(`Failed to update via npm: ${e.message}`);
124+
hint("Try running: npm install -g {{ language.params.npmPackage|caseDash }}@latest --force");
125+
}
115126
}
116127
};
117128

@@ -124,8 +135,14 @@ const updateViaHomebrew = async () => {
124135
success("Updated to latest version via Homebrew!");
125136
hint("Run '{{ language.params.executableName|caseLower }} --version' to verify the new version.");
126137
} catch (e) {
127-
error(`Failed to update via Homebrew: ${e.message}`);
128-
hint("Try running: brew upgrade {{ language.params.executableName|caseLower }}");
138+
// Check if error is due to package already being up-to-date
139+
if (e.message.includes('already installed') || e.message.includes('up-to-date')) {
140+
success("Latest version is already installed via Homebrew!");
141+
hint("The CLI is up to date. Run '{{ language.params.executableName|caseLower }} --version' to verify.");
142+
} else {
143+
error(`Failed to update via Homebrew: ${e.message}`);
144+
hint("Try running: brew upgrade {{ language.params.executableName|caseLower }}");
145+
}
129146
}
130147
};
131148

@@ -146,11 +163,17 @@ const updateViaScript = async () => {
146163
success("Updated to latest version via installation script!");
147164
hint("Run '{{ language.params.executableName|caseLower }} --version' to verify the new version.");
148165
} catch (e) {
149-
error(`Failed to update via installation script: ${e.message}`);
150-
if (platform === 'win32') {
151-
hint("Try running: iwr -useb https://appwrite.io/cli/install.ps1 | iex");
166+
// Check if error indicates already up-to-date
167+
if (e.message.includes('already exists') || e.message.includes('up-to-date')) {
168+
success("Latest version is already installed!");
169+
hint("The CLI is up to date. Run '{{ language.params.executableName|caseLower }} --version' to verify.");
152170
} else {
153-
hint("Try running: wget -q https://appwrite.io/cli/install.sh -O - | /bin/bash");
171+
error(`Failed to update via installation script: ${e.message}`);
172+
if (platform === 'win32') {
173+
hint("Try running: iwr -useb https://appwrite.io/cli/install.ps1 | iex");
174+
} else {
175+
hint("Try running: wget -q https://appwrite.io/cli/install.sh -O - | /bin/bash");
176+
}
154177
}
155178
}
156179
};
@@ -209,56 +232,22 @@ const updateCli = async ({ manual } = {}) => {
209232
return;
210233
}
211234

212-
// Auto-detect installation method and suggest appropriate update
235+
// Auto-detect installation method and update automatically
213236
if (isInstalledViaNpm()) {
214-
const answer = await inquirer.prompt([{
215-
type: 'confirm',
216-
name: 'update',
217-
message: 'Update via npm?',
218-
default: true
219-
}]);
220-
221-
if (answer.update) {
222-
await updateViaNpm();
223-
}
237+
await updateViaNpm();
224238
} else if (isInstalledViaHomebrew()) {
225-
const answer = await inquirer.prompt([{
226-
type: 'confirm',
227-
name: 'update',
228-
message: 'Update via Homebrew?',
229-
default: true
230-
}]);
231-
232-
if (answer.update) {
233-
await updateViaHomebrew();
234-
}
239+
await updateViaHomebrew();
235240
} else {
236-
// Unknown installation method - show options
237-
const answer = await inquirer.prompt([{
238-
type: 'list',
239-
name: 'method',
240-
message: 'How would you like to update?',
241-
choices: [
242-
{ name: 'NPM (npm install -g)', value: 'npm' },
243-
{ name: 'Homebrew (macOS)', value: 'homebrew' },
244-
{ name: 'Installation Script', value: 'script' },
245-
{ name: 'Show manual instructions', value: 'manual' }
246-
]
247-
}]);
248-
249-
switch (answer.method) {
250-
case 'npm':
251-
await updateViaNpm();
252-
break;
253-
case 'homebrew':
254-
await updateViaHomebrew();
255-
break;
256-
case 'script':
257-
await updateViaScript();
258-
break;
259-
case 'manual':
241+
// Unknown installation method - try npm first, then show manual instructions
242+
try {
243+
await updateViaNpm();
244+
} catch (e) {
245+
// If npm failed and it's not because the version is already installed
246+
if (!e.message.includes('EEXIST') && !e.message.includes('file already exists')) {
247+
error("Could not detect installation method or update failed.");
260248
showManualInstructions(latestVersion);
261-
break;
249+
}
250+
// If it's EEXIST error, updateViaNpm already handled it with success message
262251
}
263252
}
264253

0 commit comments

Comments
 (0)