debug path selecting

This commit is contained in:
thatben 2025-02-19 14:56:22 +01:00
parent 91fa025864
commit 79cb99749b
No known key found for this signature in database
GPG Key ID: 62C543548433D43E
5 changed files with 196 additions and 56 deletions

View File

@ -23,6 +23,7 @@
"chalk": "^5.3.0", "chalk": "^5.3.0",
"inquirer": "^9.2.12", "inquirer": "^9.2.12",
"mime-types": "^2.1.35", "mime-types": "^2.1.35",
"nanospinner": "^1.1.0" "nanospinner": "^1.1.0",
"fs-extra": "^11.3.0"
} }
} }

105
src/configmenu.js Normal file
View File

@ -0,0 +1,105 @@
import inquirer from 'inquirer';
import chalk from 'chalk';
import { showErrorMessage, showInfoMessage } from './utils/messages.js';
import { isDir, showPathSelector } from './utils/pathSelector.js';
import { saveConfig } from './services/config.js';
import fs from 'fs-extra';
export async function showConfigMenu(config) {
var newDataDir = config.dataDir;
try {
while (true) {
console.log(showInfoMessage("Codex Configuration"));
const { choice } = await inquirer.prompt([
{
type: 'list',
name: 'choice',
message: 'Select to edit:',
choices: [
`1. Data path = "${newDataDir}"`,
`2. Logs path = "${config.logsDir}"`,
'3. Storage quota = TODO',
'4. Discovery port = TODO',
'5. P2P listen port = TODO',
'6. API port = TODO',
'7. Save changes and exit',
'8. Discard changes and exit'
],
pageSize: 8,
loop: true
}
]).catch(() => {
return;
});
switch (choice.split('.')[0]) {
case '1':
newDataDir = await showPathSelector(config.dataDir, false);
if (isDir(newDataDir)) {
console.log(showInfoMessage("Warning: The new data path already exists. Make sure you know what you're doing."));
}
break;
case '2':
config.logsDir = await showPathSelector(config.logsDir, true);
break;
case '3':
break;
case '4':
break;
case '5':
break;
case '6':
break;
case '7':
// save changes, back to main menu
config = updateDataDir(config, newDataDir);
saveConfig(config);
return;
case '8':
// discard changes, back to main menu
return;
}
}
} catch (error) {
console.error(chalk.red('An error occurred:', error.message));
return;
}
}
function updateDataDir(config, newDataDir) {
if (config.dataDir == newDataDir) return config;
// The Codex dataDir is a little strange:
// If the old one is empty: The new one should not exist, so that codex creates it
// with the correct security permissions.
// If the old one does exist: We move it.
if (isDir(config.dataDir)) {
console.log(showInfoMessage(
'Moving Codex data folder...\n' +
`From: "${config.dataDir}"\n` +
`To: "${newDataDir}"`
));
try {
fs.moveSync(config.dataDir, newDataDir);
} catch (error) {
console.log(showErrorMessage("Error while moving dataDir: " + error.message));
throw error;
}
} else {
// Old data dir does not exist.
if (isDir(newDataDir)) {
console.log(showInfoMessage(
"Warning: the selected data path already exists.\n" +
`New data path = "${newDataDir}"\n` +
"Codex may overwrite data in this folder.\n" +
"Codex will fail to start if this folder does not have the required\n" +
"security permissions."
));
}
}
config.dataDir = newDataDir;
return config;
}

View File

@ -117,7 +117,6 @@ export async function installCodex(config, showNavigationMenu) {
const spinner = createSpinner('Installing Codex...').start(); const spinner = createSpinner('Installing Codex...').start();
try { try {
if (platform === 'win32') { if (platform === 'win32') {
try { try {
try { try {
@ -198,6 +197,10 @@ export async function installCodex(config, showNavigationMenu) {
} catch (error) { } catch (error) {
throw new Error('Installation completed but Codex command is not available. Please restart your terminal and try again.'); throw new Error('Installation completed but Codex command is not available. Please restart your terminal and try again.');
} }
console.log(showInfoMessage(
"Please review the configuration before starting Codex."
));
spinner.success(); spinner.success();
await showNavigationMenu(); await showNavigationMenu();

View File

@ -10,6 +10,7 @@ import { checkCodexInstallation, installCodex, uninstallCodex } from './handlers
import { runCodex, checkNodeStatus } from './handlers/nodeHandlers.js'; import { runCodex, checkNodeStatus } from './handlers/nodeHandlers.js';
import { showInfoMessage } from './utils/messages.js'; import { showInfoMessage } from './utils/messages.js';
import { loadConfig } from './services/config.js'; import { loadConfig } from './services/config.js';
import { showConfigMenu } from './configmenu.js';
async function showNavigationMenu() { async function showNavigationMenu() {
console.log('\n') console.log('\n')
@ -78,57 +79,59 @@ export async function main() {
message: 'Select an option:', message: 'Select an option:',
choices: [ choices: [
'1. Download and install Codex', '1. Download and install Codex',
'2. Run Codex node', '2. Edit Codex configuration',
'3. Check node status', '3. Run Codex node',
'4. Upload a file', '4. Check node status',
'5. Download a file', '5. Upload a file',
'6. Show local data', '6. Download a file',
'7. Uninstall Codex node', '7. Show local data',
'8. Submit feedback', '8. Uninstall Codex node',
'9. Exit' '9. Submit feedback',
'10. Exit'
], ],
pageSize: 9, pageSize: 10,
loop: true loop: true
} }
]).catch(() => { ]).catch(() => {
handleExit(); handleExit();
return { choice: '9' }; return;
}); });
if (choice.startsWith('9')) {
handleExit();
break;
}
switch (choice.split('.')[0]) { switch (choice.split('.')[0]) {
case '1': case '1':
await checkCodexInstallation(config, showNavigationMenu); await checkCodexInstallation(config, showNavigationMenu);
break; break;
case '2': case '2':
await showConfigMenu(config);
break;
case '3':
await runCodex(config, showNavigationMenu); await runCodex(config, showNavigationMenu);
return; return;
case '3': case '4':
await checkNodeStatus(showNavigationMenu); await checkNodeStatus(showNavigationMenu);
break; break;
case '4': case '5':
await uploadFile(null, handleCommandLineOperation, showNavigationMenu); await uploadFile(null, handleCommandLineOperation, showNavigationMenu);
break; break;
case '5': case '6':
await downloadFile(null, handleCommandLineOperation, showNavigationMenu); await downloadFile(null, handleCommandLineOperation, showNavigationMenu);
break; break;
case '6': case '7':
await showLocalFiles(showNavigationMenu); await showLocalFiles(showNavigationMenu);
break; break;
case '7': case '8':
await uninstallCodex(config, showNavigationMenu); await uninstallCodex(config, showNavigationMenu);
break; break;
case '8': case '9':
const { exec } = await import('child_process'); const { exec } = await import('child_process');
const url = 'https://docs.google.com/forms/d/1U21xp6shfDkJWzJSKHhUjwIE7fsYk94gmLUKAbxUMcw/edit'; const url = 'https://docs.google.com/forms/d/1U21xp6shfDkJWzJSKHhUjwIE7fsYk94gmLUKAbxUMcw/edit';
const command = process.platform === 'win32' ? `start ${url}` : process.platform === 'darwin' ? `open ${url}` : `xdg-open ${url}`; const command = process.platform === 'win32' ? `start ${url}` : process.platform === 'darwin' ? `open ${url}` : `xdg-open ${url}`;
exec(command); exec(command);
console.log(showInfoMessage('Opening feedback form in your browser...')); console.log(showInfoMessage('Opening feedback form in your browser...'));
break; break;
case '10':
handleExit();
return;
} }
console.log('\n'); console.log('\n');

View File

@ -18,9 +18,31 @@ function splitPath(str) {
return str.replaceAll("\\", "/").split("/"); return str.replaceAll("\\", "/").split("/");
} }
function dropEmptyParts(parts) {
var result = [];
parts.forEach(function(part) {
if (part.length > 0) {
result.push(part);
}
})
return result;
}
function combine(parts) {
const toJoin = dropEmptyParts(parts);
if (toJoin.length == 1) return toJoin[0];
return path.join(...toJoin);
}
function combineWith(parts, extra) {
const toJoin = dropEmptyParts(parts);
if (toJoin.length == 1) return path.join(toJoin[0], extra);
return path.join(...toJoin, extra);
}
function showCurrent(currentPath) { function showCurrent(currentPath) {
const len = currentPath.length; const len = currentPath.length;
showMsg(`Current path: [${len}]\n` + path.join(...currentPath)); showMsg(`Current path: [${len}]\n` + combine(currentPath));
} }
async function showMain(currentPath) { async function showMain(currentPath) {
@ -34,10 +56,9 @@ async function showMain(currentPath) {
'1. Enter path', '1. Enter path',
'2. Go up one', '2. Go up one',
'3. Go down one', '3. Go down one',
'4. Check path exists', '4. Create new folder here',
'5. Create new folder here', '5. Select this path',
'6. Select this path', '6. Cancel'
'7. Cancel'
], ],
pageSize: 6, pageSize: 6,
loop: true loop: true
@ -50,15 +71,15 @@ async function showMain(currentPath) {
return choice; return choice;
} }
export async function selectPath() { export async function showPathSelector(startingPath, pathMustExist) {
var currentPath = splitPath(process.cwd()); var currentPath = splitPath(startingPath);
while (true) { while (true) {
const choice = await showMain(currentPath); const choice = await showMain(currentPath);
switch (choice.split('.')[0]) { switch (choice.split('.')[0]) {
case '1': case '1':
currentPath = await enterPath(); currentPath = await enterPath(currentPath, pathMustExist);
break; break;
case '2': case '2':
currentPath = upOne(currentPath); currentPath = upOne(currentPath);
@ -67,24 +88,22 @@ export async function selectPath() {
currentPath = await downOne(currentPath); currentPath = await downOne(currentPath);
break; break;
case '4': case '4':
await checkExists(currentPath); currentPath = await createSubDir(currentPath, pathMustExist);
break; break;
case '5': case '5':
currentPath = await createSubDir(currentPath); if (pathMustExist && !isDir(combine(currentPath))) {
break;
case '6':
if (!isDir(currentPath)) {
console.log("Current path does not exist."); console.log("Current path does not exist.");
break;
} else { } else {
return currentPath; return combine(currentPath);
} }
case '7': case '6':
return ""; return combine(currentPath);
} }
} }
} }
async function enterPath() { async function enterPath(currentPath, pathMustExist) {
const response = await inquirer.prompt([ const response = await inquirer.prompt([
{ {
type: 'input', type: 'input',
@ -92,6 +111,11 @@ async function enterPath() {
message: 'Enter Path:' message: 'Enter Path:'
}]); }]);
const newPath = response.path;
if (pathMustExist && !isDir(newPath)) {
console.log("The entered path does not exist.");
return currentPath;
}
return splitPath(response.path); return splitPath(response.path);
} }
@ -99,20 +123,30 @@ function upOne(currentPath) {
return currentPath.slice(0, currentPath.length - 1); return currentPath.slice(0, currentPath.length - 1);
} }
function isDir(dir) { export function isDir(dir) {
return fs.lstatSync(dir).isDirectory(); try {
return fs.lstatSync(dir).isDirectory();
} catch {
return false;
}
} }
function isSubDir(currentPath, entry) { function isSubDir(currentPath, entry) {
const newPath = path.join(...currentPath, entry); const newPath = combineWith(currentPath, entry);
return isDir(newPath); return isDir(newPath);
} }
function getSubDirOptions(currentPath) { function getSubDirOptions(currentPath) {
const entries = fs.readdirSync(path.join(...currentPath)); const fullPath = combine(currentPath);
currentPath.forEach(function(part) {
console.log("part: '" + part + "'");
});
console.log("current: '" + fullPath + "'");
const entries = fs.readdirSync(fullPath);
var result = []; var result = [];
var counter = 1; var counter = 1;
entries.forEach(function(entry) { entries.forEach(function(entry) {
console.log("entry: " + entry);
if (isSubDir(currentPath, entry)) { if (isSubDir(currentPath, entry)) {
result.push(counter + ". " + entry); result.push(counter + ". " + entry);
} }
@ -144,15 +178,7 @@ async function downOne(currentPath) {
return [...currentPath, subDir]; return [...currentPath, subDir];
} }
async function checkExists(currentPath) { async function createSubDir(currentPath, pathMustExist) {
if (!isDir(path.join(...currentPath))) {
console.log("Current path does not exist.");
} else{
console.log("Current path exists.");
}
}
async function createSubDir(currentPath) {
const response = await inquirer.prompt([ const response = await inquirer.prompt([
{ {
type: 'input', type: 'input',
@ -163,7 +189,9 @@ async function createSubDir(currentPath) {
const name = response.name; const name = response.name;
if (name.length < 1) return; if (name.length < 1) return;
const fullDir = path.join(...currentPath, name); const fullDir = combineWith(currentPath, name);
fs.mkdirSync(fullDir); if (pathMustExist && !isDir(fullDir)) {
fs.mkdirSync(fullDir);
}
return [...currentPath, name]; return [...currentPath, name];
} }