Skip to content

Commit

Permalink
Merge branch 'main' of github.com:tonik/stapler
Browse files Browse the repository at this point in the history
  • Loading branch information
maneike committed Nov 4, 2024
2 parents 31b8a53 + 213401f commit 0aa3eed
Show file tree
Hide file tree
Showing 14 changed files with 801 additions and 94 deletions.
109 changes: 94 additions & 15 deletions packages/cli/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
#!/usr/bin/env node
import fs from 'fs';
import chalk from 'chalk';
import { Command } from 'commander';
import gradient from 'gradient-string';
import inquirer from 'inquirer';
import { findUnfinishedProjects, UnfinishedProject } from './utils/findUnfinishedProjects';
import { createProject } from '@tonik/create-stapler-app-core';

const asciiArt = `
Expand Down Expand Up @@ -38,22 +40,99 @@ program
});

const createAction = async () => {
const answers = await inquirer.prompt([
{
type: 'input',
name: 'name',
message: 'What is your project named?',
default: 'my-stapled-app',
},
{
type: 'confirm',
name: 'usePayload',
message: 'Would you like to add Payload to your app?',
default: true,
},
]);
const currentDir = process.cwd();
const unfinishedProjects: UnfinishedProject[] = findUnfinishedProjects(currentDir);
let proceedWithNewProject = true;
let selectedProject: UnfinishedProject | null = null;

if (unfinishedProjects.length > 0) {
const projectChoices = unfinishedProjects.map((proj) => ({
name: proj.projectName,
value: proj,
}));

const resumeAnswers = await inquirer.prompt([
{
type: 'confirm',
name: 'resume',
message: `We found the following unfinished project(s):\n${unfinishedProjects
.map((p) => `- ${p.projectName}`)
.join('\n')}\nWould you like to resume one of them?`,
default: true,
},
{
type: 'list',
name: 'selectedProject',
message: 'Select a project to resume:',
choices: projectChoices,
when: (answers) => answers.resume && unfinishedProjects.length > 1,
},
]);

if (resumeAnswers.resume) {
proceedWithNewProject = false;
if (unfinishedProjects.length === 1) {
selectedProject = unfinishedProjects[0];
} else {
selectedProject = resumeAnswers.selectedProject || null;
}
}
}

if (!proceedWithNewProject && selectedProject) {
process.chdir(selectedProject.projectPath);
selectedProject.state.options.name = selectedProject.projectName;
await createProject(selectedProject.state.options, selectedProject.projectPath).catch((error) => {
console.error('Error resuming project:', error);
});
} else {
// create new project
const answers = await inquirer.prompt([
{
type: 'input',
name: 'name',
message: 'What is your project named?',
default: 'my-stapled-app',
},
]);
const projectDir = `${currentDir}/${answers.name}`;
// Check if the directory already exists
if (fs.existsSync(projectDir)) {
const overwriteAnswer = await inquirer.prompt([
{
type: 'confirm',
name: 'overwrite',
message: `The directory "${answers.name}" already exists. Do you want to overwrite it?`,
default: false,
},
]);

if (!overwriteAnswer.overwrite) {
console.log(chalk.red('Project creation canceled. Project directory already exists.'));
return;
}

// Optional: Clear the directory if overwrite is confirmed
fs.rmSync(projectDir, { recursive: true, force: true });
console.log(chalk.yellow(`The directory "${answers.name}" has been cleared.`));
}

// Now proceed with further questions like adding Payload
const payloadAnswer = await inquirer.prompt([
{
type: 'confirm',
name: 'usePayload',
message: 'Would you like to add Payload to your app?',
default: true,
},
]);

const finalOptions = { ...answers, ...payloadAnswer };

await createProject(answers);
await createProject(finalOptions, projectDir).catch((error) => {
console.error(chalk.red('Error creating project:', error));
});
}
};

program.command('create').description('Create a new tonik-infused app').action(createAction);
Expand Down
7 changes: 4 additions & 3 deletions packages/cli/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
"strict": true,
"esModuleInterop": true,
"outDir": "./dist",
"rootDir": ".",
"composite": true
}
"rootDir": "."
},
"include": ["./**/*.ts"],
"exclude": ["node_modules", "dist"]
}
54 changes: 54 additions & 0 deletions packages/cli/utils/findUnfinishedProjects.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import fs from 'fs';
import path from 'path';
import { StaplerState } from '@tonik/create-stapler-app-core/types';

const MAX_DEPTH = 2;

export interface UnfinishedProject {
projectName: string;
projectPath: string;
state: StaplerState;
}

export const findUnfinishedProjects = (
dir: string,
depth: number = 0,
results: UnfinishedProject[] = [],
): UnfinishedProject[] => {
if (depth > MAX_DEPTH) return results;

const files = fs.readdirSync(dir);

for (const file of files) {
const fullPath = path.join(dir, file);

try {
const stat = fs.statSync(fullPath);

if (stat.isDirectory()) {
// Recursively search subdirectories
findUnfinishedProjects(fullPath, depth + 1, results);
} else if (file === '.staplerrc') {
// Found a .staplerrc file, check if the project is unfinished
const data = fs.readFileSync(fullPath, 'utf-8');
const state: StaplerState = JSON.parse(data);

if (isProjectUnfinished(state)) {
results.push({
projectName: state.projectName || path.basename(dir),
projectPath: dir,
state,
});
}
}
} catch (error) {
console.error(`Error accessing ${fullPath}:`, error);
}
}

return results;
};

const isProjectUnfinished = (state: StaplerState): boolean => {
return Object.values(state.stepsCompleted).some((completed) => !completed);
};
Loading

0 comments on commit 0aa3eed

Please sign in to comment.