184 lines
6.5 KiB
JavaScript
184 lines
6.5 KiB
JavaScript
import fs from 'node:fs';
|
|
import path from 'node:path';
|
|
function fileExists(root, names) {
|
|
return names.some((name) => fs.existsSync(path.join(root, name)));
|
|
}
|
|
function readRequirements(root) {
|
|
for (const name of ['requirements.txt', 'requirements-dev.txt', 'pyproject.toml']) {
|
|
const file = path.join(root, name);
|
|
if (fs.existsSync(file))
|
|
return fs.readFileSync(file, 'utf8').toLowerCase();
|
|
}
|
|
return '';
|
|
}
|
|
/**
|
|
* Django detection stub: install/dev/test via manage.py / common Python tooling.
|
|
* Deeper generators land in a later phase.
|
|
*/
|
|
export class DjangoAdapter {
|
|
root;
|
|
kind = 'django';
|
|
label = 'Django';
|
|
constructor(root) {
|
|
this.root = root;
|
|
}
|
|
installCommand() {
|
|
if (fileExists(this.root, ['pyproject.toml']) && fileExists(this.root, ['uv.lock'])) {
|
|
return { command: 'uv', args: ['sync'], cwd: this.root };
|
|
}
|
|
if (fileExists(this.root, ['poetry.lock', 'pyproject.toml'])) {
|
|
return { command: 'poetry', args: ['install'], cwd: this.root };
|
|
}
|
|
if (fileExists(this.root, ['requirements.txt'])) {
|
|
return { command: 'pip', args: ['install', '-r', 'requirements.txt'], cwd: this.root };
|
|
}
|
|
throw new Error(`No Django dependency file found at "${this.root}" (expected requirements.txt, poetry.lock, or uv.lock).`);
|
|
}
|
|
devCommand() {
|
|
if (!fileExists(this.root, ['manage.py'])) {
|
|
throw new Error(`No manage.py found at "${this.root}".`);
|
|
}
|
|
return { command: 'python', args: ['manage.py', 'runserver', '127.0.0.1:8000'], cwd: this.root };
|
|
}
|
|
buildCommand() {
|
|
if (!fileExists(this.root, ['manage.py']))
|
|
return null;
|
|
return { command: 'python', args: ['manage.py', 'collectstatic', '--noinput'], cwd: this.root };
|
|
}
|
|
testCommand(extraArgs = []) {
|
|
if (!fileExists(this.root, ['manage.py']))
|
|
return null;
|
|
return { command: 'python', args: ['manage.py', 'test', ...extraArgs], cwd: this.root };
|
|
}
|
|
lintCommand() {
|
|
return null;
|
|
}
|
|
readyPattern() {
|
|
return /Starting development server at (https?:\/\/\S+)/i;
|
|
}
|
|
describe() {
|
|
const req = readRequirements(this.root);
|
|
return {
|
|
kind: this.kind,
|
|
label: this.label,
|
|
root: this.root,
|
|
hasManagePy: fileExists(this.root, ['manage.py']),
|
|
notes: 'install/dev/test + generate_*_resource stubs available.',
|
|
hintsDjango: /django/.test(req),
|
|
};
|
|
}
|
|
}
|
|
/**
|
|
* Rails detection stub: bundle install + bin/rails server / test.
|
|
*/
|
|
export class RailsAdapter {
|
|
root;
|
|
kind = 'rails';
|
|
label = 'Rails';
|
|
constructor(root) {
|
|
this.root = root;
|
|
}
|
|
installCommand() {
|
|
return { command: 'bundle', args: ['install'], cwd: this.root };
|
|
}
|
|
devCommand() {
|
|
const binRails = path.join(this.root, 'bin', 'rails');
|
|
if (fs.existsSync(binRails)) {
|
|
return { command: 'ruby', args: [binRails, 'server', '-b', '127.0.0.1', '-p', '3000'], cwd: this.root };
|
|
}
|
|
return { command: 'rails', args: ['server', '-b', '127.0.0.1', '-p', '3000'], cwd: this.root };
|
|
}
|
|
buildCommand() {
|
|
const binRails = path.join(this.root, 'bin', 'rails');
|
|
if (fs.existsSync(binRails)) {
|
|
return { command: 'ruby', args: [binRails, 'assets:precompile'], cwd: this.root };
|
|
}
|
|
return { command: 'rails', args: ['assets:precompile'], cwd: this.root };
|
|
}
|
|
testCommand(extraArgs = []) {
|
|
const binRails = path.join(this.root, 'bin', 'rails');
|
|
if (fs.existsSync(binRails)) {
|
|
return { command: 'ruby', args: [binRails, 'test', ...extraArgs], cwd: this.root };
|
|
}
|
|
return { command: 'rails', args: ['test', ...extraArgs], cwd: this.root };
|
|
}
|
|
lintCommand() {
|
|
return null;
|
|
}
|
|
readyPattern() {
|
|
return /Listening on (https?:\/\/\S+)|Puma starting/i;
|
|
}
|
|
describe() {
|
|
return {
|
|
kind: this.kind,
|
|
label: this.label,
|
|
root: this.root,
|
|
hasBinRails: fs.existsSync(path.join(this.root, 'bin', 'rails')),
|
|
notes: 'install/dev/test + generate_*_resource stubs available.',
|
|
};
|
|
}
|
|
}
|
|
/**
|
|
* Symfony detection stub: composer + symfony CLI / php -S patterns via composer scripts when present.
|
|
*/
|
|
export class SymfonyAdapter {
|
|
root;
|
|
kind = 'symfony';
|
|
label = 'Symfony';
|
|
constructor(root) {
|
|
this.root = root;
|
|
}
|
|
installCommand() {
|
|
return { command: 'composer', args: ['install'], cwd: this.root };
|
|
}
|
|
devCommand() {
|
|
// Prefer composer script when present; otherwise PHP built-in server on public/
|
|
const composerPath = path.join(this.root, 'composer.json');
|
|
if (fs.existsSync(composerPath)) {
|
|
try {
|
|
const pkg = JSON.parse(fs.readFileSync(composerPath, 'utf8'));
|
|
if (pkg.scripts?.['serve'] || pkg.scripts?.dev) {
|
|
const script = pkg.scripts.dev ? 'dev' : 'serve';
|
|
return { command: 'composer', args: ['run', script], cwd: this.root };
|
|
}
|
|
}
|
|
catch {
|
|
// fall through
|
|
}
|
|
}
|
|
return {
|
|
command: 'php',
|
|
args: ['-S', '127.0.0.1:8000', '-t', 'public'],
|
|
cwd: this.root,
|
|
};
|
|
}
|
|
buildCommand() {
|
|
return { command: 'composer', args: ['install', '--no-dev', '--optimize-autoloader'], cwd: this.root };
|
|
}
|
|
testCommand(extraArgs = []) {
|
|
const phpunit = path.join(this.root, 'bin', 'phpunit');
|
|
if (fs.existsSync(phpunit) || fs.existsSync(`${phpunit}.bat`)) {
|
|
return { command: 'php', args: ['bin/phpunit', ...extraArgs], cwd: this.root };
|
|
}
|
|
const vendor = path.join(this.root, 'vendor', 'bin', 'phpunit');
|
|
if (fs.existsSync(vendor) || fs.existsSync(`${vendor}.bat`)) {
|
|
return { command: 'php', args: [path.join('vendor', 'bin', 'phpunit'), ...extraArgs], cwd: this.root };
|
|
}
|
|
return null;
|
|
}
|
|
lintCommand() {
|
|
return null;
|
|
}
|
|
readyPattern() {
|
|
return /(?:Development Server|started|listening).*(https?:\/\/\S+)/i;
|
|
}
|
|
describe() {
|
|
return {
|
|
kind: this.kind,
|
|
label: this.label,
|
|
root: this.root,
|
|
notes: 'install/dev/test + generate_*_resource stubs available.',
|
|
};
|
|
}
|
|
}
|
|
//# sourceMappingURL=djangoRailsSymfony.js.map
|