nitor 1.2.2 → 1.2.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nitor",
3
- "version": "1.2.2",
3
+ "version": "1.2.3",
4
4
  "description": "A comprehensive CLI toolkit for automating GitLab operations, AI-powered code review, build/deploy automation, MongoDB backup/restore, and developer productivity tools",
5
5
  "main": "index.js",
6
6
  "author": "Nithin V <mails2nithin@gmail.com>",
@@ -1,26 +1,35 @@
1
1
  const { execSync } = require('child_process');
2
+ const os = require('os');
3
+ const isWindows = os.platform() === 'win32';
2
4
 
3
5
  const cleanup = async () => {
4
6
  try {
5
7
  console.log('Starting cleanup process...\n');
6
8
 
9
+ const execOptions = { encoding: 'utf-8', shell: isWindows ? 'cmd.exe' : '/bin/sh' };
10
+ const execOptionsInherit = {
11
+ encoding: 'utf-8',
12
+ stdio: 'inherit',
13
+ shell: isWindows ? 'cmd.exe' : '/bin/sh',
14
+ };
15
+
7
16
  // Get current branch
8
- const currentBranch = execSync('git branch --show-current', { encoding: 'utf-8' }).trim();
17
+ const currentBranch = execSync('git branch --show-current', execOptions).trim();
9
18
  console.log(`Current branch: ${currentBranch}`);
10
19
 
11
20
  // Checkout to master
12
21
  console.log('\nChecking out to master branch...');
13
22
  try {
14
- execSync('git checkout master', { encoding: 'utf-8', stdio: 'inherit' });
23
+ execSync('git checkout master', execOptionsInherit);
15
24
  } catch (error) {
16
25
  // Try main if master doesn't exist
17
26
  console.log('Master branch not found, trying main...');
18
- execSync('git checkout main', { encoding: 'utf-8', stdio: 'inherit' });
27
+ execSync('git checkout main', execOptionsInherit);
19
28
  }
20
29
 
21
30
  // Get all local branches except master/main
22
31
  console.log('\nFetching list of local branches...');
23
- const branches = execSync('git branch', { encoding: 'utf-8' })
32
+ const branches = execSync('git branch', execOptions)
24
33
  .split('\n')
25
34
  .map((branch) => branch.trim().replace('* ', ''))
26
35
  .filter((branch) => branch && branch !== 'master' && branch !== 'main');
@@ -39,7 +48,7 @@ const cleanup = async () => {
39
48
 
40
49
  for (const branch of branches) {
41
50
  try {
42
- execSync(`git branch -D ${branch}`, { encoding: 'utf-8' });
51
+ execSync(`git branch -D ${branch}`, execOptions);
43
52
  console.log(` ✓ Deleted: ${branch}`);
44
53
  deletedCount++;
45
54
  } catch (error) {
@@ -1,4 +1,6 @@
1
1
  const { execSync } = require('child_process');
2
+ const os = require('os');
3
+ const isWindows = os.platform() === 'win32';
2
4
 
3
5
  const createBranch = async (values) => {
4
6
  if (!values.task || !values.type || !values.description) {
@@ -20,7 +22,10 @@ const createBranch = async (values) => {
20
22
  const branchName = `${values.project}-${values.task}-${values.type}-${values.description.toLowerCase().replace(/\s/g, '-')}`;
21
23
 
22
24
  try {
23
- execSync(`git checkout -b ${branchName}`, { stdio: 'inherit' });
25
+ execSync(`git checkout -b ${branchName}`, {
26
+ stdio: 'inherit',
27
+ shell: isWindows ? 'cmd.exe' : '/bin/sh',
28
+ });
24
29
  } catch (error) {
25
30
  console.error('Error creating branch:', error.message);
26
31
  }
package/services/merge.js CHANGED
@@ -1,4 +1,6 @@
1
1
  const { execSync } = require('child_process');
2
+ const os = require('os');
3
+ const isWindows = os.platform() === 'win32';
2
4
 
3
5
  const merge = async (values) => {
4
6
  const { source, target } = values;
@@ -12,16 +14,18 @@ const merge = async (values) => {
12
14
  try {
13
15
  console.log('Starting merge process...\n');
14
16
 
15
- execSync('git checkout master', { stdio: 'inherit' });
16
- execSync('git pull', { stdio: 'inherit' });
17
- execSync(`git checkout ${source}`, { stdio: 'inherit' });
18
- execSync('git pull', { stdio: 'inherit' });
17
+ const execOptions = { stdio: 'inherit', shell: isWindows ? 'cmd.exe' : '/bin/sh' };
18
+
19
+ execSync('git checkout master', execOptions);
20
+ execSync('git pull', execOptions);
21
+ execSync(`git checkout ${source}`, execOptions);
22
+ execSync('git pull', execOptions);
19
23
 
20
24
  for (const branch of target.split(' ')) {
21
- execSync(`git checkout ${branch}`, { stdio: 'inherit' });
22
- execSync('git pull', { stdio: 'inherit' });
23
- execSync(`git merge ${source} --no-edit`, { stdio: 'inherit' });
24
- execSync('git push', { stdio: 'inherit' });
25
+ execSync(`git checkout ${branch}`, execOptions);
26
+ execSync('git pull', execOptions);
27
+ execSync(`git merge ${source} --no-edit`, execOptions);
28
+ execSync('git push', execOptions);
25
29
  }
26
30
 
27
31
  console.log('\n✓ Merge completed successfully!');
@@ -1,7 +1,8 @@
1
1
  const { execSync } = require('child_process');
2
2
  const os = require('os');
3
+ const path = require('path');
3
4
  const { backupConfig, restoreConfig } = require('./utils');
4
-
5
+ const isWindows = os.platform() === 'win32';
5
6
  // ANSI color codes
6
7
  const colors = {
7
8
  red: '\x1b[31m',
@@ -12,6 +13,7 @@ const colors = {
12
13
  /**
13
14
  * Execute MongoDB restore from local backup to Docker container
14
15
  * @param {Object} config - Restore configuration
16
+ * @param {boolean} config.mongoInDocker - If mongodb running outside of docker
15
17
  * @param {string} config.containerName - Name of the Docker container (default: 'mongodb')
16
18
  * @param {string} config.localBackupPath - Local path where backup is stored (default: '~/backups/mongo')
17
19
  * @param {string} config.containerBackupPath - Path inside container for backup (default: '/data/backup')
@@ -19,37 +21,60 @@ const colors = {
19
21
  const executeMongoRestore = async (config) => {
20
22
  const {
21
23
  containerName = 'mongodb',
22
- localBackupPath = os.homedir() + '/backups/mongo',
24
+ localBackupPath = path.join(os.homedir(), 'backups', 'mongo'),
23
25
  containerBackupPath = '/data/backup',
24
26
  } = config;
25
27
 
26
28
  try {
27
- const expandedLocalPath = localBackupPath.replace('~', os.homedir());
28
-
29
- console.log(`\nStarting MongoDB restore to container: ${containerName}`);
30
-
31
- // Step 1: Copy backup from local to Docker container
32
- const copyCommand = `docker cp ${expandedLocalPath} ${containerName}:${containerBackupPath}`;
33
-
34
- console.log(`Copying backup to container...`);
35
- execSync(copyCommand, { stdio: 'inherit' });
36
- console.log(`${colors.green}✓ Backup copied to container${colors.reset}`);
37
-
38
- // Step 2: Execute mongorestore inside the container
39
- const restoreCommand = `docker exec -it ${containerName} mongorestore ${containerBackupPath}`;
40
-
41
- console.log('Executing mongorestore...');
42
- execSync(restoreCommand, { stdio: 'inherit' });
43
- console.log(`${colors.green}✓ Mongorestore completed successfully${colors.reset}`);
44
-
45
- // Step 3: Remove backup data from container
46
- const cleanupCommand = `docker exec -it ${containerName} rm -rf ${containerBackupPath}`;
47
-
48
- console.log('Cleaning up backup data from container...');
49
- execSync(cleanupCommand, { stdio: 'inherit' });
50
- console.log(`${colors.green}✓ Backup data removed from container${colors.reset}`);
51
-
52
- console.log(`${colors.green}Restore completed successfully!${colors.reset}\n`);
29
+ const expandedLocalPath = localBackupPath.startsWith('~')
30
+ ? localBackupPath.replace('~', os.homedir())
31
+ : localBackupPath;
32
+ const normalizedLocalPath = path.normalize(expandedLocalPath);
33
+
34
+ if (config.mongoInDocker) {
35
+ console.log(`\nStarting MongoDB restore to container: ${containerName}`);
36
+
37
+ // Step 1: Copy backup from local to Docker container
38
+ // Use normalized path for Windows compatibility
39
+ const copyCommand = `docker cp "${normalizedLocalPath}" ${containerName}:${containerBackupPath}`;
40
+
41
+ console.log(`Copying backup to container...`);
42
+ execSync(copyCommand, { stdio: 'inherit', shell: isWindows ? 'cmd.exe' : '/bin/sh' });
43
+ console.log(`${colors.green}✓ Backup copied to container${colors.reset}`);
44
+
45
+ // Step 2: Execute mongorestore inside the container
46
+ // Remove -it flag for Windows compatibility (causes issues in non-interactive shells)
47
+ const restoreCommand = isWindows
48
+ ? `docker exec ${containerName} mongorestore ${containerBackupPath}`
49
+ : `docker exec -it ${containerName} mongorestore ${containerBackupPath}`;
50
+
51
+ console.log('Executing mongorestore...');
52
+ execSync(restoreCommand, { stdio: 'inherit', shell: isWindows ? 'cmd.exe' : '/bin/sh' });
53
+ console.log(`${colors.green}✓ Mongorestore completed successfully${colors.reset}`);
54
+
55
+ // Step 3: Remove backup data from container
56
+ const cleanupCommand = isWindows
57
+ ? `docker exec ${containerName} rm -rf ${containerBackupPath}`
58
+ : `docker exec -it ${containerName} rm -rf ${containerBackupPath}`;
59
+
60
+ console.log('Cleaning up backup data from container...');
61
+ execSync(cleanupCommand, { stdio: 'inherit', shell: isWindows ? 'cmd.exe' : '/bin/sh' });
62
+ console.log(`${colors.green}✓ Backup data removed from container${colors.reset}`);
63
+
64
+ console.log(`${colors.green}Restore completed successfully!${colors.reset}\n`);
65
+ } else {
66
+ console.log(`\nStarting MongoDB restore to local machine`);
67
+
68
+ console.log('Executing mongorestore...');
69
+ const localRestoreCommand = `mongorestore --uri="mongodb://localhost:27017/" "${normalizedLocalPath}"`;
70
+ execSync(localRestoreCommand, {
71
+ stdio: 'inherit',
72
+ shell: isWindows ? 'cmd.exe' : '/bin/sh',
73
+ });
74
+ console.log(`${colors.green}✓ Mongorestore completed successfully${colors.reset}`);
75
+
76
+ console.log(`${colors.green}Restore completed successfully!${colors.reset}\n`);
77
+ }
53
78
 
54
79
  return { success: true };
55
80
  } catch (error) {
@@ -75,29 +100,40 @@ const executeMongoBackup = async (config) => {
75
100
  password,
76
101
  database,
77
102
  backupPath = '/data/backup',
78
- localBackupPath = '~/backups/mongo/',
103
+ localBackupPath = path.join(os.homedir(), 'backups', 'mongo'),
79
104
  } = config;
80
105
 
81
106
  try {
82
107
  console.log(`\nStarting MongoDB backup for pod: ${pod}, database: ${database}`);
83
108
 
84
- const mongodumpCommand = `kubectl exec -it ${pod} -- mongodump --username ${username} --password ${password} --authenticationDatabase ${database} --db ${database} --out ${backupPath}`;
109
+ // Remove -it flag for Windows compatibility
110
+ const mongodumpCommand = isWindows
111
+ ? `kubectl exec ${pod} -- mongodump --username ${username} --password ${password} --authenticationDatabase ${database} --db ${database} --out ${backupPath}`
112
+ : `kubectl exec -it ${pod} -- mongodump --username ${username} --password ${password} --authenticationDatabase ${database} --db ${database} --out ${backupPath}`;
85
113
 
86
114
  console.log('Executing mongodump...');
87
- execSync(mongodumpCommand, { stdio: 'inherit' });
115
+ execSync(mongodumpCommand, { stdio: 'inherit', shell: isWindows ? 'cmd.exe' : '/bin/sh' });
88
116
  console.log(`${colors.green}✓ Mongodump completed successfully${colors.reset}`);
89
117
 
90
- const expandedLocalPath = localBackupPath.replace('~', os.homedir());
91
- const destinationPath = `${expandedLocalPath}${database}`;
92
- const copyCommand = `kubectl cp ${pod}:${backupPath}/${database} ${destinationPath}`;
93
- const cleanupCommand = `kubectl exec -it ${pod} -- rm -rf ${backupPath}`;
118
+ // Expand and normalize paths for cross-platform compatibility
119
+ const expandedLocalPath = localBackupPath.startsWith('~')
120
+ ? localBackupPath.replace('~', os.homedir())
121
+ : localBackupPath;
122
+ const normalizedBasePath = path.normalize(expandedLocalPath);
123
+ const destinationPath = path.join(normalizedBasePath, database);
124
+
125
+ // Use quotes for paths with spaces on Windows
126
+ const copyCommand = `kubectl cp ${pod}:${backupPath}/${database} "${destinationPath}"`;
127
+ const cleanupCommand = isWindows
128
+ ? `kubectl exec ${pod} -- rm -rf ${backupPath}`
129
+ : `kubectl exec -it ${pod} -- rm -rf ${backupPath}`;
94
130
 
95
131
  console.log(`Copying backup to ${destinationPath}...`);
96
- execSync(copyCommand, { stdio: 'inherit' });
132
+ execSync(copyCommand, { stdio: 'inherit', shell: isWindows ? 'cmd.exe' : '/bin/sh' });
97
133
  console.log(`${colors.green}✓ Backup copied successfully${colors.reset}`);
98
134
 
99
135
  console.log('Cleaning up backup data from pod...');
100
- execSync(cleanupCommand, { stdio: 'inherit' });
136
+ execSync(cleanupCommand, { stdio: 'inherit', shell: isWindows ? 'cmd.exe' : '/bin/sh' });
101
137
  console.log(`${colors.green}✓ Backup data removed from pod${colors.reset}`);
102
138
 
103
139
  console.log(
@@ -159,6 +195,8 @@ const backup = async (values) => {
159
195
  console.log(`Starting restore process for projects: ${projects.join(', ')}`);
160
196
  console.log(`========================================`);
161
197
 
198
+ restoreConfig.mongoInDocker = !!values?.docker;
199
+
162
200
  await executeMongoRestore(restoreConfig);
163
201
 
164
202
  console.log('\n========================================');
@@ -24,19 +24,7 @@ const processArgs = async (type, value) => {
24
24
  let values;
25
25
 
26
26
  // Skip convertParamsToMap for time commands and other special commands
27
- const skipConversion = [
28
- ACTIONS.HELP,
29
- ACTIONS.VERSION,
30
- ACTIONS.CLEANUP,
31
- ACTIONS.TIME_ADD,
32
- ACTIONS.TIME_UPDATE,
33
- ACTIONS.TIME_DELETE,
34
- ACTIONS.TIME_STATUS,
35
- ACTIONS.TIME_ENTRIES,
36
- ACTIONS.TIME_ZOHO,
37
- ACTIONS.TIME_GITLAB,
38
- ACTIONS.TIME_MERGE,
39
- ];
27
+ const skipConversion = [ACTIONS.HELP, ACTIONS.VERSION, ACTIONS.CLEANUP];
40
28
 
41
29
  if (!skipConversion.includes(type) && !value?.includes('--h') && !value?.includes('-help')) {
42
30
  values = await convertParamsToMap(value, type);
package/services/utils.js CHANGED
@@ -56,6 +56,8 @@ const keyMap = {
56
56
  so: 'source',
57
57
  target: 'target',
58
58
  ta: 'target',
59
+ docker: 'docker',
60
+ do: 'docker',
59
61
  };
60
62
  const projectMap = {
61
63
  portal: 'medica-portal',
@@ -304,6 +306,14 @@ const convertParamsToMap = async (item, type) => {
304
306
  ACTIONS.REFACTOR,
305
307
  ACTIONS.BACKUP,
306
308
  ACTIONS.MERGE,
309
+ ACTIONS.TIME_ADD,
310
+ ACTIONS.TIME_UPDATE,
311
+ ACTIONS.TIME_DELETE,
312
+ ACTIONS.TIME_STATUS,
313
+ ACTIONS.TIME_ENTRIES,
314
+ ACTIONS.TIME_ZOHO,
315
+ ACTIONS.TIME_GITLAB,
316
+ ACTIONS.TIME_MERGE,
307
317
  ];
308
318
  const skipCheck = itemsToSkipCheck.includes(type);
309
319
  let live = false;