abapgit-agent 1.8.5 ā 1.8.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/abapgit-agent +10 -3
- package/package.json +2 -1
- package/src/commands/import.js +73 -15
- package/src/commands/pull.js +27 -1
- package/src/commands/upgrade.js +456 -0
- package/src/config.js +57 -1
- package/src/utils/backgroundJobPoller.README.md +218 -0
- package/src/utils/backgroundJobPoller.js +251 -0
- package/src/utils/version-check.js +182 -1
package/bin/abapgit-agent
CHANGED
|
@@ -24,7 +24,7 @@ const gitUtils = require('../src/utils/git-utils');
|
|
|
24
24
|
const versionCheck = require('../src/utils/version-check');
|
|
25
25
|
const validators = require('../src/utils/validators');
|
|
26
26
|
const { AbapHttp } = require('../src/utils/abap-http');
|
|
27
|
-
const { loadConfig, getTransport, isAbapIntegrationEnabled } = require('../src/config');
|
|
27
|
+
const { loadConfig, getTransport, isAbapIntegrationEnabled, getSafeguards } = require('../src/config');
|
|
28
28
|
|
|
29
29
|
// Get terminal width for responsive table
|
|
30
30
|
const getTermWidth = () => process.stdout.columns || 80;
|
|
@@ -52,7 +52,8 @@ async function main() {
|
|
|
52
52
|
where: require('../src/commands/where'),
|
|
53
53
|
ref: require('../src/commands/ref'),
|
|
54
54
|
init: require('../src/commands/init'),
|
|
55
|
-
pull: require('../src/commands/pull')
|
|
55
|
+
pull: require('../src/commands/pull'),
|
|
56
|
+
upgrade: require('../src/commands/upgrade')
|
|
56
57
|
};
|
|
57
58
|
|
|
58
59
|
// Check if this is a modular command
|
|
@@ -98,11 +99,17 @@ To enable integration:
|
|
|
98
99
|
isAbapIntegrationEnabled,
|
|
99
100
|
loadConfig,
|
|
100
101
|
AbapHttp,
|
|
101
|
-
getTransport
|
|
102
|
+
getTransport,
|
|
103
|
+
getSafeguards
|
|
102
104
|
};
|
|
103
105
|
|
|
104
106
|
// Execute command
|
|
105
107
|
await cmd.execute(args.slice(1), context);
|
|
108
|
+
|
|
109
|
+
// Show new version reminder (non-blocking, cached daily)
|
|
110
|
+
if (command !== 'upgrade') {
|
|
111
|
+
await versionCheck.showNewVersionReminder();
|
|
112
|
+
}
|
|
106
113
|
return;
|
|
107
114
|
}
|
|
108
115
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "abapgit-agent",
|
|
3
|
-
"version": "1.8.
|
|
3
|
+
"version": "1.8.7",
|
|
4
4
|
"description": "ABAP Git Agent - Pull and activate ABAP code via abapGit from any git repository",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"files": [
|
|
@@ -33,6 +33,7 @@
|
|
|
33
33
|
"test:cmd:view": "node tests/run-all.js --cmd --command=view",
|
|
34
34
|
"test:cmd:preview": "node tests/run-all.js --cmd --command=preview",
|
|
35
35
|
"test:cmd:tree": "node tests/run-all.js --cmd --command=tree",
|
|
36
|
+
"test:cmd:upgrade": "node tests/run-all.js --cmd --command=upgrade",
|
|
36
37
|
"test:lifecycle": "node tests/run-all.js --lifecycle",
|
|
37
38
|
"test:pull": "node tests/run-all.js --pull",
|
|
38
39
|
"pull": "node bin/abapgit-agent",
|
package/src/commands/import.js
CHANGED
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
* Import command - Import existing objects from package to git repository
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
+
const {
|
|
6
|
+
startBackgroundJob,
|
|
7
|
+
pollForCompletion,
|
|
8
|
+
displayProgress,
|
|
9
|
+
formatTimestamp,
|
|
10
|
+
calculateTimeSpent
|
|
11
|
+
} = require('../utils/backgroundJobPoller');
|
|
12
|
+
|
|
5
13
|
module.exports = {
|
|
6
14
|
name: 'import',
|
|
7
15
|
description: 'Import existing objects from package to git repository',
|
|
@@ -9,9 +17,10 @@ module.exports = {
|
|
|
9
17
|
requiresVersionCheck: true,
|
|
10
18
|
|
|
11
19
|
async execute(args, context) {
|
|
12
|
-
|
|
20
|
+
try {
|
|
21
|
+
const { loadConfig, gitUtils, AbapHttp } = context;
|
|
13
22
|
|
|
14
|
-
|
|
23
|
+
// Show help if requested
|
|
15
24
|
const helpIndex = args.findIndex(a => a === '--help' || a === '-h');
|
|
16
25
|
if (helpIndex !== -1) {
|
|
17
26
|
console.log(`
|
|
@@ -22,6 +31,9 @@ Description:
|
|
|
22
31
|
Import existing objects from package to git repository.
|
|
23
32
|
Uses the git remote URL to find the abapGit online repository.
|
|
24
33
|
|
|
34
|
+
This command runs asynchronously using a background job and displays
|
|
35
|
+
real-time progress updates.
|
|
36
|
+
|
|
25
37
|
Prerequisites:
|
|
26
38
|
- Run "abapgit-agent create" first or create repository in abapGit UI
|
|
27
39
|
- Package must have objects to import
|
|
@@ -51,7 +63,7 @@ Examples:
|
|
|
51
63
|
commitMessage = args[messageArgIndex + 1];
|
|
52
64
|
}
|
|
53
65
|
|
|
54
|
-
console.log(`\nš¦
|
|
66
|
+
console.log(`\nš¦ Starting import job`);
|
|
55
67
|
console.log(` URL: ${repoUrl}`);
|
|
56
68
|
if (commitMessage) {
|
|
57
69
|
console.log(` Message: ${commitMessage}`);
|
|
@@ -76,23 +88,69 @@ Examples:
|
|
|
76
88
|
data.password = config.gitPassword;
|
|
77
89
|
}
|
|
78
90
|
|
|
79
|
-
|
|
91
|
+
// Step 1: Start the background job
|
|
92
|
+
const endpoint = '/sap/bc/z_abapgit_agent/import';
|
|
93
|
+
const jobInfo = await startBackgroundJob(http, endpoint, data, csrfToken);
|
|
80
94
|
|
|
81
|
-
console.log(
|
|
95
|
+
console.log(`ā
Job started: ${jobInfo.jobNumber}`);
|
|
96
|
+
console.log('');
|
|
82
97
|
|
|
83
|
-
//
|
|
84
|
-
const
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
98
|
+
// Step 2: Poll for completion with progress updates
|
|
99
|
+
const finalResult = await pollForCompletion(http, endpoint, jobInfo.jobNumber, {
|
|
100
|
+
pollInterval: 2000,
|
|
101
|
+
maxAttempts: 300,
|
|
102
|
+
onProgress: (progress, message) => {
|
|
103
|
+
displayProgress(progress, message);
|
|
104
|
+
}
|
|
105
|
+
});
|
|
88
106
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
107
|
+
// Step 3: Show final result
|
|
108
|
+
console.log('\n');
|
|
109
|
+
|
|
110
|
+
if (finalResult.status === 'completed' && finalResult.result) {
|
|
111
|
+
// Parse result JSON string
|
|
112
|
+
let resultData;
|
|
113
|
+
try {
|
|
114
|
+
if (typeof finalResult.result === 'string') {
|
|
115
|
+
resultData = JSON.parse(finalResult.result);
|
|
116
|
+
} else {
|
|
117
|
+
resultData = finalResult.result;
|
|
118
|
+
}
|
|
119
|
+
} catch (e) {
|
|
120
|
+
resultData = { filesStaged: 'unknown', commitMessage: commitMessage };
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
console.log(`ā
Import completed successfully!`);
|
|
124
|
+
console.log(` Files staged: ${resultData.filesStaged || resultData.FILES_STAGED || 'unknown'}`);
|
|
125
|
+
console.log(` Commit: ${resultData.commitMessage || resultData.COMMIT_MESSAGE || commitMessage || 'Initial import'}`);
|
|
126
|
+
console.log(``);
|
|
127
|
+
|
|
128
|
+
// Calculate time spent
|
|
129
|
+
if (finalResult.startedAt && finalResult.completedAt) {
|
|
130
|
+
const timeSpent = calculateTimeSpent(finalResult.startedAt, finalResult.completedAt);
|
|
131
|
+
console.log(`ā±ļø Time spent: ${timeSpent}`);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
console.log(`š Stats:`);
|
|
135
|
+
console.log(` Job number: ${jobInfo.jobNumber}`);
|
|
136
|
+
if (finalResult.startedAt) {
|
|
137
|
+
console.log(` Started: ${formatTimestamp(finalResult.startedAt)}`);
|
|
138
|
+
}
|
|
139
|
+
if (finalResult.completedAt) {
|
|
140
|
+
console.log(` Completed: ${formatTimestamp(finalResult.completedAt)}`);
|
|
141
|
+
}
|
|
93
142
|
} else {
|
|
94
143
|
console.log(`ā Import failed`);
|
|
95
|
-
console.log(`
|
|
144
|
+
console.log(` Status: ${finalResult.status}`);
|
|
145
|
+
process.exit(1);
|
|
146
|
+
}
|
|
147
|
+
} catch (error) {
|
|
148
|
+
console.error('\nā Error during import:');
|
|
149
|
+
console.error(` ${error.message || error}`);
|
|
150
|
+
if (error.response) {
|
|
151
|
+
console.error(` HTTP Status: ${error.response.status}`);
|
|
152
|
+
console.error(` Response: ${JSON.stringify(error.response.data)}`);
|
|
153
|
+
}
|
|
96
154
|
process.exit(1);
|
|
97
155
|
}
|
|
98
156
|
}
|
package/src/commands/pull.js
CHANGED
|
@@ -9,7 +9,21 @@ module.exports = {
|
|
|
9
9
|
requiresVersionCheck: true,
|
|
10
10
|
|
|
11
11
|
async execute(args, context) {
|
|
12
|
-
const { loadConfig, AbapHttp, gitUtils, getTransport } = context;
|
|
12
|
+
const { loadConfig, AbapHttp, gitUtils, getTransport, getSafeguards } = context;
|
|
13
|
+
|
|
14
|
+
// Check project-level safeguards
|
|
15
|
+
const safeguards = getSafeguards();
|
|
16
|
+
|
|
17
|
+
// SAFEGUARD 1: Check if pull is completely disabled
|
|
18
|
+
if (safeguards.disablePull) {
|
|
19
|
+
console.error('ā Error: pull command is disabled for this project\n');
|
|
20
|
+
if (safeguards.reason) {
|
|
21
|
+
console.error(`Reason: ${safeguards.reason}\n`);
|
|
22
|
+
}
|
|
23
|
+
console.error('The pull command has been disabled in .abapgit-agent.json');
|
|
24
|
+
console.error('Please contact the project maintainer to enable it.');
|
|
25
|
+
process.exit(1);
|
|
26
|
+
}
|
|
13
27
|
|
|
14
28
|
const urlArgIndex = args.indexOf('--url');
|
|
15
29
|
const branchArgIndex = args.indexOf('--branch');
|
|
@@ -36,6 +50,18 @@ module.exports = {
|
|
|
36
50
|
files = args[filesArgIndex + 1].split(',').map(f => f.trim());
|
|
37
51
|
}
|
|
38
52
|
|
|
53
|
+
// SAFEGUARD 2: Check if files are required but not provided
|
|
54
|
+
if (safeguards.requireFilesForPull && !files) {
|
|
55
|
+
console.error('ā Error: --files parameter is required for this project\n');
|
|
56
|
+
if (safeguards.reason) {
|
|
57
|
+
console.error(`Reason: ${safeguards.reason}\n`);
|
|
58
|
+
}
|
|
59
|
+
console.error('Usage: abapgit-agent pull --files <file1>,<file2>\n');
|
|
60
|
+
console.error('This safeguard is configured in .abapgit-agent.json');
|
|
61
|
+
console.error('Contact the project maintainer if you need to change this setting.');
|
|
62
|
+
process.exit(1);
|
|
63
|
+
}
|
|
64
|
+
|
|
39
65
|
if (!gitUrl) {
|
|
40
66
|
gitUrl = gitUtils.getRemoteUrl();
|
|
41
67
|
if (!gitUrl) {
|
|
@@ -0,0 +1,456 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Upgrade command - Upgrade CLI and/or ABAP backend to latest or specific version
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
const { execSync } = require('child_process');
|
|
6
|
+
const readline = require('readline');
|
|
7
|
+
|
|
8
|
+
module.exports = {
|
|
9
|
+
name: 'upgrade',
|
|
10
|
+
description: 'Upgrade CLI and/or ABAP backend to latest or specific version',
|
|
11
|
+
requiresAbapConfig: false, // Checked conditionally
|
|
12
|
+
requiresVersionCheck: false, // Does its own version checks
|
|
13
|
+
|
|
14
|
+
async execute(args, context) {
|
|
15
|
+
const { versionCheck, loadConfig, isAbapIntegrationEnabled } = context;
|
|
16
|
+
|
|
17
|
+
// Parse flags
|
|
18
|
+
const flags = this.parseFlags(args);
|
|
19
|
+
|
|
20
|
+
// Validate flag combinations
|
|
21
|
+
try {
|
|
22
|
+
this.validateFlags(flags);
|
|
23
|
+
} catch (error) {
|
|
24
|
+
console.error(`ā Error: ${error.message}`);
|
|
25
|
+
process.exit(1);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Check if ABAP config is needed
|
|
29
|
+
const needsAbapConfig = !flags.cliOnly && !flags.checkOnly;
|
|
30
|
+
if (needsAbapConfig && !isAbapIntegrationEnabled()) {
|
|
31
|
+
console.error('ā Error: .abapGitAgent config file not found');
|
|
32
|
+
console.error(' ABAP upgrade requires configuration.');
|
|
33
|
+
console.error(' Run: abapgit-agent init');
|
|
34
|
+
console.error('');
|
|
35
|
+
console.error(' Or use --cli-only to upgrade CLI package only.');
|
|
36
|
+
process.exit(1);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Get current versions
|
|
40
|
+
const cliVersion = versionCheck.getCliVersion();
|
|
41
|
+
let abapVersion = null;
|
|
42
|
+
|
|
43
|
+
if (needsAbapConfig) {
|
|
44
|
+
try {
|
|
45
|
+
const config = loadConfig();
|
|
46
|
+
const { apiVersion } = await versionCheck.checkCompatibility(config);
|
|
47
|
+
abapVersion = apiVersion;
|
|
48
|
+
} catch (e) {
|
|
49
|
+
console.error(`ā ļø Could not fetch ABAP version: ${e.message}`);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Get latest version from npm
|
|
54
|
+
const latestVersion = await versionCheck.getLatestNpmVersion();
|
|
55
|
+
if (!latestVersion && !flags.version && !flags.match) {
|
|
56
|
+
console.error('ā Error: Could not fetch latest version from npm registry');
|
|
57
|
+
console.error(' Please check your internet connection or specify --version X.X.X');
|
|
58
|
+
process.exit(1);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Validate specified version exists in npm registry
|
|
62
|
+
if (flags.version && !flags.abapOnly) {
|
|
63
|
+
const versionExists = await this.validateVersionExists(flags.version);
|
|
64
|
+
if (!versionExists) {
|
|
65
|
+
console.error(`ā Error: Version ${flags.version} not found in npm registry`);
|
|
66
|
+
console.error(' Please check available versions at: https://www.npmjs.com/package/abapgit-agent?activeTab=versions');
|
|
67
|
+
process.exit(1);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Determine target versions
|
|
72
|
+
const targets = this.determineTargets(flags, cliVersion, abapVersion, latestVersion);
|
|
73
|
+
|
|
74
|
+
// Check-only mode
|
|
75
|
+
if (flags.checkOnly) {
|
|
76
|
+
this.showCheckReport(cliVersion, abapVersion, latestVersion);
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Dry-run mode
|
|
81
|
+
if (flags.dryRun) {
|
|
82
|
+
this.showDryRunPlan(cliVersion, abapVersion, targets, flags);
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Show upgrade plan
|
|
87
|
+
if (!flags.yes) {
|
|
88
|
+
const proceed = await this.confirmUpgrade(cliVersion, abapVersion, targets, flags);
|
|
89
|
+
if (!proceed) {
|
|
90
|
+
console.log('Upgrade cancelled.');
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Execute upgrade
|
|
96
|
+
await this.performUpgrade(targets, flags, context);
|
|
97
|
+
|
|
98
|
+
// Verify upgrade
|
|
99
|
+
await this.verifyUpgrade(targets, flags, context);
|
|
100
|
+
},
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Parse command-line flags
|
|
104
|
+
*/
|
|
105
|
+
parseFlags(args) {
|
|
106
|
+
return {
|
|
107
|
+
checkOnly: args.includes('--check'),
|
|
108
|
+
cliOnly: args.includes('--cli-only'),
|
|
109
|
+
abapOnly: args.includes('--abap-only'),
|
|
110
|
+
match: args.includes('--match'),
|
|
111
|
+
version: this.getArgValue(args, '--version'),
|
|
112
|
+
latest: args.includes('--latest'),
|
|
113
|
+
yes: args.includes('--yes') || args.includes('-y'),
|
|
114
|
+
dryRun: args.includes('--dry-run'),
|
|
115
|
+
transport: this.getArgValue(args, '--transport')
|
|
116
|
+
};
|
|
117
|
+
},
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Get argument value following a flag
|
|
121
|
+
*/
|
|
122
|
+
getArgValue(args, flag) {
|
|
123
|
+
const index = args.indexOf(flag);
|
|
124
|
+
if (index !== -1 && index + 1 < args.length) {
|
|
125
|
+
return args[index + 1];
|
|
126
|
+
}
|
|
127
|
+
return null;
|
|
128
|
+
},
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Validate flag combinations
|
|
132
|
+
*/
|
|
133
|
+
validateFlags(flags) {
|
|
134
|
+
// Invalid combinations
|
|
135
|
+
if (flags.match && flags.version) {
|
|
136
|
+
throw new Error('Cannot use --match and --version together');
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
if (flags.match && flags.cliOnly) {
|
|
140
|
+
throw new Error('Cannot use --match with --cli-only. --match upgrades ABAP to match CLI version');
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
if (flags.cliOnly && flags.abapOnly) {
|
|
144
|
+
throw new Error('Cannot use --cli-only and --abap-only together');
|
|
145
|
+
}
|
|
146
|
+
},
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Validate that a version exists in npm registry
|
|
150
|
+
*/
|
|
151
|
+
async validateVersionExists(version) {
|
|
152
|
+
return new Promise((resolve) => {
|
|
153
|
+
const { execSync } = require('child_process');
|
|
154
|
+
try {
|
|
155
|
+
// Use npm view to check if version exists
|
|
156
|
+
const output = execSync(`npm view abapgit-agent@${version} version 2>/dev/null`, {
|
|
157
|
+
encoding: 'utf8',
|
|
158
|
+
stdio: ['pipe', 'pipe', 'ignore']
|
|
159
|
+
}).trim();
|
|
160
|
+
|
|
161
|
+
// If npm view returns the version, it exists
|
|
162
|
+
resolve(output === version);
|
|
163
|
+
} catch (e) {
|
|
164
|
+
// Version doesn't exist or npm command failed
|
|
165
|
+
resolve(false);
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
},
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Determine target versions for CLI and ABAP
|
|
172
|
+
*/
|
|
173
|
+
determineTargets(flags, cliVersion, abapVersion, latestVersion) {
|
|
174
|
+
let cliTarget = null;
|
|
175
|
+
let abapTarget = null;
|
|
176
|
+
|
|
177
|
+
if (flags.match) {
|
|
178
|
+
// Match ABAP to CLI version
|
|
179
|
+
abapTarget = cliVersion;
|
|
180
|
+
} else if (flags.version) {
|
|
181
|
+
// Specific version
|
|
182
|
+
cliTarget = flags.cliOnly ? flags.version : (flags.abapOnly ? null : flags.version);
|
|
183
|
+
abapTarget = flags.abapOnly ? flags.version : (flags.cliOnly ? null : flags.version);
|
|
184
|
+
} else {
|
|
185
|
+
// Latest version (default)
|
|
186
|
+
cliTarget = flags.abapOnly ? null : latestVersion;
|
|
187
|
+
abapTarget = flags.cliOnly ? null : latestVersion;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
return { cliTarget, abapTarget };
|
|
191
|
+
},
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Show check-only report
|
|
195
|
+
*/
|
|
196
|
+
showCheckReport(cliVersion, abapVersion, latestVersion) {
|
|
197
|
+
console.log('');
|
|
198
|
+
console.log('Current versions:');
|
|
199
|
+
console.log(` CLI: v${cliVersion}`);
|
|
200
|
+
if (abapVersion) {
|
|
201
|
+
console.log(` ABAP: v${abapVersion}`);
|
|
202
|
+
}
|
|
203
|
+
console.log('');
|
|
204
|
+
|
|
205
|
+
if (latestVersion) {
|
|
206
|
+
console.log(`Latest available: v${latestVersion}`);
|
|
207
|
+
console.log('');
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
const needsCliUpgrade = latestVersion && cliVersion !== latestVersion;
|
|
211
|
+
const needsAbapUpgrade = abapVersion && latestVersion && abapVersion !== latestVersion;
|
|
212
|
+
const versionMismatch = abapVersion && cliVersion !== abapVersion;
|
|
213
|
+
|
|
214
|
+
if (versionMismatch) {
|
|
215
|
+
console.log('ā ļø Version mismatch detected');
|
|
216
|
+
console.log('');
|
|
217
|
+
} else if (!needsCliUpgrade && !needsAbapUpgrade) {
|
|
218
|
+
console.log('ā
All components are up to date');
|
|
219
|
+
console.log('');
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
console.log('To upgrade:');
|
|
224
|
+
console.log(' Both: abapgit-agent upgrade');
|
|
225
|
+
console.log(' CLI only: abapgit-agent upgrade --cli-only');
|
|
226
|
+
if (abapVersion) {
|
|
227
|
+
console.log(' ABAP only: abapgit-agent upgrade --abap-only');
|
|
228
|
+
console.log(' Match: abapgit-agent upgrade --match');
|
|
229
|
+
}
|
|
230
|
+
console.log('');
|
|
231
|
+
},
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Show dry-run plan
|
|
235
|
+
*/
|
|
236
|
+
showDryRunPlan(cliVersion, abapVersion, targets, flags) {
|
|
237
|
+
console.log('');
|
|
238
|
+
console.log('š¹ DRY RUN - No changes will be made');
|
|
239
|
+
console.log('');
|
|
240
|
+
console.log('Current versions:');
|
|
241
|
+
console.log(` CLI: v${cliVersion}`);
|
|
242
|
+
if (abapVersion) {
|
|
243
|
+
console.log(` ABAP: v${abapVersion}`);
|
|
244
|
+
}
|
|
245
|
+
console.log('');
|
|
246
|
+
|
|
247
|
+
console.log('Target versions:');
|
|
248
|
+
if (targets.cliTarget) {
|
|
249
|
+
console.log(` CLI: v${targets.cliTarget}`);
|
|
250
|
+
}
|
|
251
|
+
if (targets.abapTarget) {
|
|
252
|
+
console.log(` ABAP: v${targets.abapTarget}`);
|
|
253
|
+
}
|
|
254
|
+
console.log('');
|
|
255
|
+
|
|
256
|
+
console.log('Would execute:');
|
|
257
|
+
let step = 1;
|
|
258
|
+
if (targets.cliTarget) {
|
|
259
|
+
console.log(` ${step}. npm install -g abapgit-agent@${targets.cliTarget}`);
|
|
260
|
+
step++;
|
|
261
|
+
}
|
|
262
|
+
if (targets.abapTarget) {
|
|
263
|
+
console.log(` ${step}. abapgit-agent pull --branch v${targets.abapTarget}`);
|
|
264
|
+
console.log(' (via existing abapGit repository)');
|
|
265
|
+
step++;
|
|
266
|
+
}
|
|
267
|
+
console.log(` ${step}. Verify versions match`);
|
|
268
|
+
console.log('');
|
|
269
|
+
console.log('No changes made.');
|
|
270
|
+
console.log('');
|
|
271
|
+
},
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* Confirm upgrade with user
|
|
275
|
+
*/
|
|
276
|
+
async confirmUpgrade(cliVersion, abapVersion, targets, flags) {
|
|
277
|
+
console.log('');
|
|
278
|
+
console.log('š¦ Upgrade Plan:');
|
|
279
|
+
console.log('');
|
|
280
|
+
console.log('Current versions:');
|
|
281
|
+
console.log(` CLI: v${cliVersion}`);
|
|
282
|
+
if (abapVersion) {
|
|
283
|
+
console.log(` ABAP: v${abapVersion}`);
|
|
284
|
+
}
|
|
285
|
+
console.log('');
|
|
286
|
+
|
|
287
|
+
console.log('Target versions:');
|
|
288
|
+
if (targets.cliTarget) {
|
|
289
|
+
console.log(` CLI: v${targets.cliTarget}`);
|
|
290
|
+
}
|
|
291
|
+
if (targets.abapTarget) {
|
|
292
|
+
console.log(` ABAP: v${targets.abapTarget}`);
|
|
293
|
+
}
|
|
294
|
+
console.log('');
|
|
295
|
+
|
|
296
|
+
console.log('This will:');
|
|
297
|
+
let step = 1;
|
|
298
|
+
if (targets.cliTarget) {
|
|
299
|
+
console.log(` ${step}. Upgrade npm package: abapgit-agent@${targets.cliTarget}`);
|
|
300
|
+
step++;
|
|
301
|
+
}
|
|
302
|
+
if (targets.abapTarget) {
|
|
303
|
+
console.log(` ${step}. Pull ABAP code from git tag v${targets.abapTarget}`);
|
|
304
|
+
step++;
|
|
305
|
+
console.log(` ${step}. Activate all backend components`);
|
|
306
|
+
step++;
|
|
307
|
+
}
|
|
308
|
+
console.log('');
|
|
309
|
+
|
|
310
|
+
return new Promise((resolve) => {
|
|
311
|
+
const rl = readline.createInterface({
|
|
312
|
+
input: process.stdin,
|
|
313
|
+
output: process.stdout
|
|
314
|
+
});
|
|
315
|
+
|
|
316
|
+
rl.question('Do you want to continue? [Y/n] ', (answer) => {
|
|
317
|
+
rl.close();
|
|
318
|
+
const normalized = answer.trim().toLowerCase();
|
|
319
|
+
resolve(normalized === '' || normalized === 'y' || normalized === 'yes');
|
|
320
|
+
});
|
|
321
|
+
});
|
|
322
|
+
},
|
|
323
|
+
|
|
324
|
+
/**
|
|
325
|
+
* Perform upgrade
|
|
326
|
+
*/
|
|
327
|
+
async performUpgrade(targets, flags, context) {
|
|
328
|
+
console.log('');
|
|
329
|
+
console.log('š Starting upgrade...');
|
|
330
|
+
console.log('');
|
|
331
|
+
|
|
332
|
+
// Upgrade CLI
|
|
333
|
+
if (targets.cliTarget) {
|
|
334
|
+
await this.upgradeCliPackage(targets.cliTarget);
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
// Upgrade ABAP
|
|
338
|
+
if (targets.abapTarget) {
|
|
339
|
+
await this.upgradeAbapBackend(targets.abapTarget, flags.transport, context);
|
|
340
|
+
}
|
|
341
|
+
},
|
|
342
|
+
|
|
343
|
+
/**
|
|
344
|
+
* Upgrade CLI package via npm
|
|
345
|
+
*/
|
|
346
|
+
async upgradeCliPackage(version) {
|
|
347
|
+
console.log(`š¦ Upgrading CLI to v${version}...`);
|
|
348
|
+
|
|
349
|
+
try {
|
|
350
|
+
// Check if npm is available
|
|
351
|
+
try {
|
|
352
|
+
execSync('npm --version', { stdio: 'ignore' });
|
|
353
|
+
} catch (e) {
|
|
354
|
+
console.error('ā Error: npm is not installed or not in PATH');
|
|
355
|
+
console.error(' Please install Node.js and npm: https://nodejs.org/');
|
|
356
|
+
process.exit(1);
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
// Run npm install
|
|
360
|
+
const command = `npm install -g abapgit-agent@${version}`;
|
|
361
|
+
console.log(` Running: ${command}`);
|
|
362
|
+
|
|
363
|
+
execSync(command, {
|
|
364
|
+
stdio: 'inherit',
|
|
365
|
+
encoding: 'utf8'
|
|
366
|
+
});
|
|
367
|
+
|
|
368
|
+
console.log(`ā
CLI upgraded to v${version}`);
|
|
369
|
+
console.log('');
|
|
370
|
+
} catch (error) {
|
|
371
|
+
console.error(`ā Failed to upgrade CLI: ${error.message}`);
|
|
372
|
+
console.error('');
|
|
373
|
+
console.error('This may be due to:');
|
|
374
|
+
console.error(' - Version not found in npm registry');
|
|
375
|
+
console.error(' - Permission issues (try with sudo)');
|
|
376
|
+
console.error(' - Network connectivity issues');
|
|
377
|
+
process.exit(1);
|
|
378
|
+
}
|
|
379
|
+
},
|
|
380
|
+
|
|
381
|
+
/**
|
|
382
|
+
* Upgrade ABAP backend via pull command
|
|
383
|
+
*/
|
|
384
|
+
async upgradeAbapBackend(version, transport, context) {
|
|
385
|
+
console.log(`š¦ Upgrading ABAP backend to v${version}...`);
|
|
386
|
+
console.log(` Using git tag: v${version}`);
|
|
387
|
+
console.log('');
|
|
388
|
+
|
|
389
|
+
try {
|
|
390
|
+
// Build pull command args
|
|
391
|
+
const pullArgs = ['--branch', `v${version}`];
|
|
392
|
+
if (transport) {
|
|
393
|
+
pullArgs.push('--transport', transport);
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
// Execute pull command
|
|
397
|
+
const pullCommand = require('./pull');
|
|
398
|
+
await pullCommand.execute(pullArgs, context);
|
|
399
|
+
|
|
400
|
+
console.log('');
|
|
401
|
+
console.log(`ā
ABAP backend upgraded to v${version}`);
|
|
402
|
+
console.log('');
|
|
403
|
+
} catch (error) {
|
|
404
|
+
console.error(`ā Failed to upgrade ABAP backend: ${error.message}`);
|
|
405
|
+
console.error('');
|
|
406
|
+
console.error('This may be due to:');
|
|
407
|
+
console.error(' - Git tag not found in repository');
|
|
408
|
+
console.error(' - ABAP activation errors');
|
|
409
|
+
console.error(' - Connection issues with ABAP system');
|
|
410
|
+
process.exit(1);
|
|
411
|
+
}
|
|
412
|
+
},
|
|
413
|
+
|
|
414
|
+
/**
|
|
415
|
+
* Verify upgrade success
|
|
416
|
+
*/
|
|
417
|
+
async verifyUpgrade(targets, flags, context) {
|
|
418
|
+
console.log('š Verifying upgrade...');
|
|
419
|
+
console.log('');
|
|
420
|
+
|
|
421
|
+
const { versionCheck, loadConfig } = context;
|
|
422
|
+
|
|
423
|
+
// Check CLI version
|
|
424
|
+
let cliVersion = null;
|
|
425
|
+
if (targets.cliTarget) {
|
|
426
|
+
cliVersion = versionCheck.getCliVersion();
|
|
427
|
+
if (cliVersion === targets.cliTarget) {
|
|
428
|
+
console.log(`ā
CLI version verified: v${cliVersion}`);
|
|
429
|
+
} else {
|
|
430
|
+
console.log(`ā ļø CLI version mismatch: expected v${targets.cliTarget}, got v${cliVersion}`);
|
|
431
|
+
console.log(' You may need to restart your terminal or reinstall globally');
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
// Check ABAP version
|
|
436
|
+
if (targets.abapTarget && !flags.cliOnly) {
|
|
437
|
+
try {
|
|
438
|
+
const config = loadConfig();
|
|
439
|
+
const { apiVersion: abapVersion } = await versionCheck.checkCompatibility(config);
|
|
440
|
+
|
|
441
|
+
if (abapVersion === targets.abapTarget) {
|
|
442
|
+
console.log(`ā
ABAP version verified: v${abapVersion}`);
|
|
443
|
+
} else {
|
|
444
|
+
console.log(`ā ļø ABAP version mismatch: expected v${targets.abapTarget}, got v${abapVersion}`);
|
|
445
|
+
console.log(' Some components may have failed to activate');
|
|
446
|
+
}
|
|
447
|
+
} catch (e) {
|
|
448
|
+
console.log(`ā ļø Could not verify ABAP version: ${e.message}`);
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
console.log('');
|
|
453
|
+
console.log('ā
Upgrade complete!');
|
|
454
|
+
console.log('');
|
|
455
|
+
}
|
|
456
|
+
};
|