Skip to content

Commit

Permalink
refactor: command overall readibility
Browse files Browse the repository at this point in the history
  • Loading branch information
maneike committed Oct 31, 2024
1 parent e4ad706 commit 8f207e4
Show file tree
Hide file tree
Showing 25 changed files with 234 additions and 126 deletions.
6 changes: 2 additions & 4 deletions packages/cli/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,11 @@ const asciiArt = `
const displayHeader = () => {
const metalGradient = gradient([
{ color: '#3C3C3C', pos: 0 },
{ color: '#FFFFFF', pos: 0.5 },
{ color: '#BDBDBD', pos: 0.75 },
{ color: '#3C3C3C', pos: 1 },
{ color: '#FFFFFF', pos: 1 },
]);

console.log(metalGradient(asciiArt));
console.log(chalk.bold('\n🖇️ Welcome to Stapler!\n'));
console.log(chalk.bold('\nWelcome to Stapler!\n'));
};

const program = new Command();
Expand Down
2 changes: 0 additions & 2 deletions packages/core/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@ interface ProjectOptions {
export const createProject = async (options: ProjectOptions) => {
const { name, usePayload } = options;

console.log(`🖇️ Stapling ${name}...`);

await createTurboRepo(name);

process.chdir(name);
Expand Down
2 changes: 2 additions & 0 deletions packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@
"dev": "tsc -w"
},
"dependencies": {
"chalk": "^5.3.0",
"fs-extra": "^11.2.0",
"gradient-string": "^3.0.0",
"inquirer": "^10.2.2"
},
"devDependencies": {
Expand Down
9 changes: 5 additions & 4 deletions packages/core/utils/bar/prepareDrink.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import chalk from 'chalk';

const getName = (name: string) => {
if (!name) {
return '.';
Expand All @@ -12,13 +14,12 @@ export const prepareDrink = (name: string) => {
setTimeout(() => {
console.log('🍸 Adding gin and lime juice...');
setTimeout(() => {
console.log('🍸 Topping with', '\x1b[34mTonik\x1b[0m...');
console.log('🍸 Topping with', chalk.blue('Tonik') + '...');
setTimeout(() => {
console.log('🍸 Garnishing with lime wedge...');
setTimeout(() => {
console.log(`\x1b[32m%s\x1b[0m`, `🍸 Your Stapled ${getName(name)} is ready!`, `\x1b[0m`);
// I'm too lazy to mess with modules building to allow coloring library to be installed lol
console.log(`🍸 You can now run:`, `\x1b[36mcd ${name} && pnpm dev\x1b[0m`);
console.log(chalk.green(`🍸 Your Stapled ${getName(name)} is ready!`));
console.log(`🍸 You can now run:`, chalk.cyan(`cd ${name} && pnpm dev`));
}, 1000);
}, 1000);
}, 1000);
Expand Down
2 changes: 1 addition & 1 deletion packages/core/utils/docs/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { templateGenerator } from '../generator/generator';
import { getTemplateDirectory } from '../shared/getTemplateDirectory';

export const createDocFiles = () => {
console.log('🖇️ Writing docs...');
console.log('Writing docs...');
const templateDirectory = getTemplateDirectory(`/templates/docs/files`);
const destinationDirectory = process.cwd();

Expand Down
2 changes: 1 addition & 1 deletion packages/core/utils/env/createEnvFile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const requiredEnvVariables: Record<string, 'required' | 'optional'> = {

// Function to create .env file with empty fields
export const createEnvFile = (destinationDirectory: string) => {
console.log('🖇️ Creating .env file...');
console.log('Creating .env file...');
let envTemplate = '';
for (const [key, status] of Object.entries(requiredEnvVariables)) {
envTemplate += `${key}=\n`;
Expand Down
26 changes: 18 additions & 8 deletions packages/core/utils/github/ghInstaller.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import { execSync } from 'child_process';
import * as os from 'os';
import gradient from 'gradient-string';

const githubGradient = gradient([
{ color: '#3B8640', pos: 0 },
{ color: '#8256D0', pos: 1 },
]);

export const isGitHubCLIInstalled = (): boolean => {
try {
Expand Down Expand Up @@ -27,28 +33,32 @@ export const installGitHubCLI = (): boolean => {
installCommand =
'sudo dnf config-manager --add-repo https://cli.github.com/packages/rpm/gh-cli.repo && sudo dnf install gh';
} else {
console.log('🖇️ Automatic installation is not supported for your Linux distribution.');
console.log('🖇️ Please visit https://github.com/cli/cli#installation for installation instructions.');
console.log(
githubGradient('Automatic installation is not supported for your Linux distribution.'),
githubGradient('\n Please visit https://github.com/cli/cli#installation for installation instructions.'),
);
return false;
}
break;
case 'win32': // Windows
installCommand = 'winget install --id GitHub.cli';
break;
default:
console.log('🖇️ Automatic installation is not supported for your operating system.');
console.log('🖇️ Please visit https://github.com/cli/cli#installation for installation instructions.');
console.log(
githubGradient('Automatic installation is not supported for your operating system.'),
githubGradient('\nPlease visit https://github.com/cli/cli#installation for installation instructions.'),
);
return false;
}

console.log('🖇️ Installing GitHub CLI...');
console.log(githubGradient('Installing GitHub CLI...'));
try {
execSync(installCommand, { stdio: 'inherit' });
console.log('🖇️ GitHub CLI installed successfully.');
console.log(githubGradient('GitHub CLI installed successfully.'));
return true;
} catch (error) {
console.error('🖇️ Failed to install GitHub CLI.');
console.log('🖇️ Please install it manually from: https://github.com/cli/cli#installation');
console.error('Failed to install GitHub CLI.');
console.log(githubGradient('Please install it manually from: https://github.com/cli/cli#installation'));
return false;
}
};
Expand Down
24 changes: 14 additions & 10 deletions packages/core/utils/github/install.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import gradient from 'gradient-string';
import { installGitHubCLI, isGitHubCLIInstalled } from './ghInstaller';
import {
authenticateGitHub,
Expand All @@ -12,31 +13,36 @@ interface ProjectOptions {
visibility: 'public' | 'private';
}

const githubGradient = gradient([
{ color: '#3B8640', pos: 0 },
{ color: '#8256D0', pos: 1 },
]);

// Helper function to check if GitHub CLI is installed
const checkGitHubCLI = () => {
console.log('🖇️ Checking GitHub CLI installation...');
console.log(githubGradient('Checking if GitHub CLI is installed...'));
if (!isGitHubCLIInstalled()) {
console.log('🖇️ GitHub CLI is not installed.');
console.log(githubGradient('GitHub CLI is not installed.'));
const installed = installGitHubCLI();
if (!installed) {
console.error('🖇️ GitHub CLI installation failed. Exiting...');
console.error('GitHub CLI installation failed. Exiting...');
process.exit(1);
}
}
};

// Helper function to ensure GitHub authentication
const ensureGitHubAuthentication = () => {
console.log('🖇️ Checking GitHub authentication status...');
console.log(githubGradient('Checking GitHub authentication status...'));

// Check if the user is already authenticated
if (isGitHubAuthenticated()) {
console.log('🖇️ You are already logged in to GitHub.');
console.log(githubGradient('You are already logged in to GitHub.'));
return; // Exit early if authenticated
}

if (!isGitHubAuthenticated()) {
console.error(`🖇️ It looks like you're not logged in...`);
console.error(`It looks like you're not logged in...`);
authenticateGitHub();
}
};
Expand All @@ -50,16 +56,14 @@ export const initializeRepository = async (options: ProjectOptions) => {
// Retrieve GitHub username once
const username = await fetchGitHubUsername();
if (!username) {
console.error('🖇️ Failed to retrieve GitHub username. Aborting repository creation.');
console.error('Failed to retrieve GitHub username. Aborting repository creation.');
process.exit(1);
}

// Check if the repository exists and create it
const repoName = await createGitHubRepository(projectName, visibility, username);
if (!repoName) {
console.error(
'🖇️ Failed to create GitHub repository. Check your permissions or if the repository already exists.',
);
console.error('Failed to create GitHub repository. Check your permissions.');
process.exit(1);
}

Expand Down
33 changes: 19 additions & 14 deletions packages/core/utils/github/repositoryManager.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@
import { exec, execSync } from 'child_process';
import inquirer from 'inquirer';
import { promisify } from 'util';
import gradient from 'gradient-string';

const execAsync = promisify(exec);

const githubGradient = gradient([
{ color: '#3B8640', pos: 0 },
{ color: '#8256D0', pos: 1 },
]);

const generateUniqueRepoName = async (baseName: string): Promise<string> => {
// Remove any existing numbering pattern from the end
const cleanBaseName = baseName.replace(/-\d+$/, '');

// Try the base name first
try {
await execAsync(`gh repo view ${cleanBaseName}`);
console.error(`🖇️ Repository "${cleanBaseName}" already exists.`);
console.error(`Repository "${cleanBaseName}" already exists.`);
// If we get here, the repo exists, so we need a new name
} catch (error) {
// If repo doesn't exist, we can use the clean base name
Expand All @@ -26,7 +32,7 @@ const generateUniqueRepoName = async (baseName: string): Promise<string> => {
const candidateName = `${cleanBaseName}-v${counter}`;
try {
await execAsync(`gh repo view ${candidateName}`);
console.error(`🖇️ Repository "${candidateName}" already exists.`);
console.error(`Repository "${candidateName}" already exists.`);
counter++;
} catch (error) {
if (error) {
Expand All @@ -49,18 +55,17 @@ export const isGitHubAuthenticated = (): boolean => {
};

export const authenticateGitHub = async (): Promise<boolean> => {
console.log('🖇️ Attempting to authenticate with GitHub...');
console.log(githubGradient('Attempting to authenticate with GitHub...'));

execSync('gh auth login', { stdio: 'inherit' });

// Immediately check authentication status after login attempt
const isAuthenticated = isGitHubAuthenticated();

if (isAuthenticated) {
console.log('🖇️ Authentication was successful.');
return true;
} else {
console.error('🖇️ Authentication failed after login attempt.');
console.error('Authentication failed after login attempt.');
return false;
}
};
Expand All @@ -71,14 +76,14 @@ export const fetchGitHubUsername = async (): Promise<string | null> => {
const username = execSync('echo "$(gh api user --jq .login)"', { stdio: 'pipe' }).toString().trim();

if (username) {
console.log(`🖇️ Hello \x1b[36m${username}\x1b[0m!`);
console.log(githubGradient(`Hello ${username}!`));
return username;
} else {
console.log('🖇️ No username returned or an error occurred.');
console.log(githubGradient('No username returned or an error occurred.'));
return null;
}
} catch (error) {
console.error('🖇️ Error fetching GitHub username:', error);
console.error('Error fetching GitHub username:', error);
return null;
}
};
Expand All @@ -88,7 +93,7 @@ export const createGitHubRepository = async (
repositoryVisibility: 'public' | 'private',
username: string,
): Promise<string | undefined> => {
console.log(`🖇️ Checking if repository already exists...`);
console.log(githubGradient(`Checking if repository already exists...`));

// Check if the repository exists
const repoCheckCommand = `echo "$(gh repo view ${username}/${projectName} --json name)"`;
Expand All @@ -114,25 +119,25 @@ export const createGitHubRepository = async (
repoName = confirmedName;
}

console.log(`🖇️ Creating GitHub repository: \x1b[36m${repoName}\x1b[0m`);
console.log(githubGradient(`Creating GitHub repository: ${repoName}`));

const visibility = repositoryVisibility === 'public' ? '--public' : '--private';
const command = `gh repo create ${repoName} ${visibility}`;

const result = execSync(command);

if (result) {
console.log(`🖇️ Repository successfully created at \x1b[36m${result}\x1b[0m`);
console.log(githubGradient(`Repository successfully created at ${result}`));
return repoName; // Return true to indicate success
}

console.error('🖇️ Failed to create GitHub repository.');
console.error('Failed to create GitHub repository.');
return; // Return false on failure
};

// New function to set up the local Git repository
export const setupGitRepository = async (projectName: string, username: string) => {
console.log(`🖇️ Setting up Git for the repository...`);
console.log(githubGradient(`Pushing files to repository...`));

// Set the remote origin and push to GitHub
const commands = [
Expand All @@ -147,7 +152,7 @@ export const setupGitRepository = async (projectName: string, username: string)
for (const cmd of commands) {
const result = execSync(cmd, { stdio: 'pipe' });
if (!result) {
console.error(`🖇️ Failed to execute command: ${cmd}`);
console.error(`Failed to execute command: ${cmd}`);
process.exit(1);
}
}
Expand Down
14 changes: 10 additions & 4 deletions packages/core/utils/payload/install.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,35 @@
import { execSync } from 'child_process';
import { existsSync } from 'fs';
import { join } from 'path';
import gradient from 'gradient-string';
import { preparePayloadConfig } from './preparePayloadConfig';
import { prepareTsConfig } from './prepareTsConfig';
import { removeTurboFlag } from './removeTurboFlag';
import { updatePackages } from './updatePackages';

const payloadGradient = gradient([
{ color: '#12324A', pos: 0 },
{ color: '#E5AA5F', pos: 1 },
]);

export const preparePayload = async () => {
console.log('🖇️ Initializing Payload...');
console.log(payloadGradient('Initializing Payload...'));

process.chdir('./apps/web/');

prepareTsConfig();

updatePackages();

console.log('🖇️ Moving files to (app) directory...');
console.log(payloadGradient('Moving files to (app) directory...'));
execSync(
`mkdir -p ./app/\\(app\\) && find ./app -maxdepth 1 ! -path './app' ! -path './app/\\(app\\)' -exec mv {} ./app/\\(app\\)/ \\;`,
{
stdio: 'inherit',
},
);

console.log('🖇️ Installing Payload to Next.js...');
console.log(payloadGradient('Installing Payload to Next.js...'));
execSync(`npx create-payload-app@beta`, { stdio: 'inherit' });

// Payload doesn't work with Turbopack yet
Expand All @@ -32,7 +38,7 @@ export const preparePayload = async () => {
// Check if the payload configuration file exists
const payloadConfigPath = join(process.cwd(), 'payload.config.ts');
if (!existsSync(payloadConfigPath)) {
console.error('🖇️ Payload installation cancelled/failed.');
console.error('Payload installation cancelled/failed.');
} else {
await preparePayloadConfig(payloadConfigPath);
}
Expand Down
10 changes: 8 additions & 2 deletions packages/core/utils/payload/preparePayloadConfig.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
import type { PathLike } from 'fs';
import fs from 'fs/promises';
import gradient from 'gradient-string';

const payloadGradient = gradient([
{ color: '#12324A', pos: 0 },
{ color: '#E5AA5F', pos: 1 },
]);

export const preparePayloadConfig = async (configPath: PathLike) => {
console.log('🖇️ Preparing payload.config.ts...');
console.log(payloadGradient('Preparing payload.config.ts...'));

try {
// Read the payload.config.ts file
Expand All @@ -20,6 +26,6 @@ export const preparePayloadConfig = async (configPath: PathLike) => {
// Write the updated payload.config.ts back to the file
await fs.writeFile(configPath, updatedConfig);
} catch (err) {
console.error('🖇️ Error during processing payload.config.ts', err);
console.error('Error during processing payload.config.ts', err);
}
};
Loading

0 comments on commit 8f207e4

Please sign in to comment.