Skip to content

Commit 8fbf620

Browse files
committed
fix: make Greenfield default paths configurable
1 parent 39f9c4e commit 8fbf620

1 file changed

Lines changed: 31 additions & 11 deletions

File tree

server/greenfieldService.js

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
const fs = require('fs').promises;
22
const fsSync = require('fs');
33
const path = require('path');
4+
const os = require('os');
45
const { exec, spawn } = require('child_process');
56
const util = require('util');
67
const winston = require('winston');
@@ -20,29 +21,48 @@ const logger = winston.createLogger({
2021
});
2122

2223
// Project categories - determines folder structure
24+
function expandUserPath(p) {
25+
const raw = String(p || '').trim();
26+
if (!raw) return raw;
27+
28+
if (raw === '~') return os.homedir();
29+
if (raw.startsWith('~/')) return path.join(os.homedir(), raw.slice(2));
30+
return raw;
31+
}
32+
33+
function resolveGitHubRoot() {
34+
const envRoot = process.env.GREENFIELD_GITHUB_ROOT || process.env.GITHUB_ROOT || '';
35+
const root = envRoot ? expandUserPath(envRoot) : path.join(os.homedir(), 'GitHub');
36+
return root;
37+
}
38+
39+
function joinGitHubRoot(...parts) {
40+
return path.join(resolveGitHubRoot(), ...parts);
41+
}
42+
2343
const PROJECT_CATEGORIES = {
2444
'website': {
25-
path: '~/GitHub/websites',
45+
path: joinGitHubRoot('websites'),
2646
keywords: ['website', 'web app', 'frontend', 'landing page', 'portfolio', 'blog']
2747
},
2848
'game': {
29-
path: '~/GitHub/games',
49+
path: joinGitHubRoot('games'),
3050
keywords: ['game', 'hytopia', 'unity', 'godot', 'gaming']
3151
},
3252
'tool': {
33-
path: '~/GitHub/tools',
53+
path: joinGitHubRoot('tools'),
3454
keywords: ['tool', 'cli', 'utility', 'automation', 'script']
3555
},
3656
'api': {
37-
path: '~/GitHub/apis',
57+
path: joinGitHubRoot('apis'),
3858
keywords: ['api', 'backend', 'server', 'service', 'rest', 'graphql']
3959
},
4060
'library': {
41-
path: '~/GitHub/libraries',
61+
path: joinGitHubRoot('libraries'),
4262
keywords: ['library', 'package', 'module', 'npm', 'sdk']
4363
},
4464
'other': {
45-
path: '~/GitHub/projects',
65+
path: joinGitHubRoot('projects'),
4666
keywords: []
4767
}
4868
};
@@ -54,7 +74,7 @@ const PROJECT_TEMPLATES = {
5474
description: 'Hytopia SDK game project',
5575
initCommand: 'npx create-hytopia@latest',
5676
postInit: [],
57-
defaultPath: '~/GitHub/games/hytopia/games'
77+
defaultPath: joinGitHubRoot('games', 'hytopia', 'games')
5878
},
5979
'node-typescript': {
6080
name: 'Node.js TypeScript',
@@ -93,7 +113,7 @@ dist/
93113
.env
94114
*.log`
95115
},
96-
defaultPath: '~/GitHub/tools'
116+
defaultPath: joinGitHubRoot('tools')
97117
},
98118
'empty': {
99119
name: 'Empty Project',
@@ -103,7 +123,7 @@ dist/
103123
'README.md': `# {{projectName}}\n\nProject description here.`,
104124
'.gitignore': `node_modules/\n.env\n*.log`
105125
},
106-
defaultPath: '~/GitHub'
126+
defaultPath: resolveGitHubRoot()
107127
}
108128
};
109129

@@ -252,7 +272,7 @@ class GreenfieldService {
252272
// Detect or use provided category
253273
const category = providedCategory || this.detectCategory(description);
254274
const categoryConfig = this.categories[category];
255-
const basePath = categoryConfig.path.replace('~', process.env.HOME);
275+
const basePath = expandUserPath(categoryConfig.path);
256276

257277
logger.info('Detected category', { category, basePath });
258278

@@ -663,7 +683,7 @@ Start by understanding the requirements, then design and implement the solution.
663683
* Validate a project path
664684
*/
665685
async validatePath(projectPath) {
666-
const expandedPath = projectPath.replace('~', process.env.HOME);
686+
const expandedPath = expandUserPath(projectPath);
667687

668688
try {
669689
const stats = await fs.stat(expandedPath);

0 commit comments

Comments
 (0)