Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: cherry init template should explicitly set up repository info #145

Merged
merged 6 commits into from
Dec 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions .cherry.cjs
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
const JS_FILES = '**/*.{js,jsx}'
const TS_FILES = '**/*.{ts,tsx}'

module.exports = {
project_name: 'cherrypush/cherry-cli',
plugins: {
Expand Down
29 changes: 10 additions & 19 deletions bin/commands/init.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
#! /usr/bin/env node

import * as git from '../../src/git.js'

import { createConfigurationFile, createWorkflowFile, getConfigFile, workflowExists } from '../../src/configuration.js'

import { Command } from 'commander'
import prompt from 'prompt'
import { gitProjectRoot, gitRemoteUrl } from '../../src/git.js'
import { guessRepositoryInfo } from '../../src/repository.js'

export default function (program: Command) {
program.command('init').action(async () => {
Expand All @@ -16,24 +15,16 @@ export default function (program: Command) {
process.exit(1)
}

prompt.message = ''
prompt.start()

const remoteUrl = await git.gitRemoteUrl()
let projectName = git.guessProjectName(remoteUrl)

if (projectName === null) {
const { repo } = await prompt.get({
properties: { repo: { message: 'Enter your project name', required: true } },
})
if (typeof repo === 'string') projectName = repo
}

if (!projectName) throw new Error('Project name is required')
const remoteUrl = await gitRemoteUrl()
const projectRoot = await gitProjectRoot()
const repositoryInfo = await guessRepositoryInfo({ remoteUrl, configFile: null, projectRoot })

createConfigurationFile(projectName)
if (!repositoryInfo.host || !repositoryInfo.owner || !repositoryInfo.name)
throw new Error('Could not guess repository info. Please setup your config file manually.')

createConfigurationFile(repositoryInfo)
if (!workflowExists()) createWorkflowFile()
console.log('Your initial setup is done! Now try the command `cherry run` to see your first metrics.')

console.log('Your initial setup is complete! Run `cherry run` to view your metrics.')
})
}
114 changes: 0 additions & 114 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"dist"
],
"scripts": {
"install:global": "npm install -g .",
"build": "tsc",
"cherry": "tsx ./bin/cherry.ts",
"prepare": "husky install && npm run build",
Expand Down Expand Up @@ -49,7 +50,6 @@
"madge": "^8.0.0",
"minimatch": "^6.1.6",
"p-limit": "^4.0.0",
"prompt": "^1.3.0",
"semver": "^7.6.3",
"spinnies": "^0.5.1",
"true-case-path": "^2.2.1"
Expand Down
20 changes: 8 additions & 12 deletions src/configuration.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,26 @@
import { gitProjectRoot, gitRemoteUrl } from './git.js'

import fs from 'fs'
import { dirname } from 'path'
import { fileURLToPath } from 'url'
import buildAndImport from './build-and-import.cjs'
import { guessRepositoryInfo } from './repository.js'
import { Configuration } from './types.js'
import { getConfigTemplate, getWorkflowTemplate } from './templates.js'
import { Configuration, Repository } from './types.js'

export const CONFIG_FILE_LOCAL_PATHS = ['.cherry.js', '.cherry.cjs', '.cherry.ts']
export const WORKFLOW_FILE_LOCAL_PATH = '.github/workflows/cherry_push.yml'

export const CONFIG_FILE_FULL_PATHS = CONFIG_FILE_LOCAL_PATHS.map((filePath) => `${process.cwd()}/${filePath}`)
export const WORKFLOW_FILE_FULL_PATH = `${process.cwd()}/${WORKFLOW_FILE_LOCAL_PATH}`

const CONFIG_TEMPLATE_PATH = dirname(fileURLToPath(import.meta.url)) + '/templates/.cherry.js.template'
const WORKFLOW_TEMPLATE_PATH = dirname(fileURLToPath(import.meta.url)) + '/templates/.cherry_push.yml.template'

export const createConfigurationFile = (projectName: string) =>
fs.writeFileSync(
CONFIG_FILE_FULL_PATHS[0],
fs.readFileSync(CONFIG_TEMPLATE_PATH).toString().replace('PROJECT_NAME', projectName)
)
export const createConfigurationFile = (repositoryInfo: Repository) => {
const filePath = CONFIG_FILE_FULL_PATHS[0]
console.log('Creating configuration file at:', filePath)
fs.writeFileSync(filePath, getConfigTemplate(repositoryInfo))
}

export const createWorkflowFile = () => {
fs.mkdirSync(`${process.cwd()}/.github/workflows`, { recursive: true })
fs.writeFileSync(WORKFLOW_FILE_FULL_PATH, fs.readFileSync(WORKFLOW_TEMPLATE_PATH).toString())
fs.writeFileSync(WORKFLOW_FILE_FULL_PATH, getWorkflowTemplate())
}

export const getConfigFile = () => CONFIG_FILE_FULL_PATHS.find((filePath) => fs.existsSync(filePath)) ?? null
Expand Down
8 changes: 4 additions & 4 deletions src/repository.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import path from 'path'
import { PermalinkFn, Repository } from './types.js'
import { Host, PermalinkFn, Repository } from './types.js'

export const buildRepoURL = (repository: Repository) =>
`https://${repository.host}/${repository.owner}/${repository.name}`
Expand Down Expand Up @@ -34,15 +34,15 @@ export async function guessRepositoryInfo({
remoteUrl: string | null
configFile: string | null
projectRoot: string
}) {
}): Promise<Repository> {
if (remoteUrl === null) {
throw new Error('Could not guess repository info: no remote URL found')
}

// For github ssh remotes such as [email protected]:cherrypush/cherry-cli.git
if (remoteUrl.includes('[email protected]')) {
return {
host: 'github.com',
host: Host.Github,
owner: remoteUrl.split(':')[1].split('/')[0],
name: remoteUrl.split('/')[1].replace('.git', ''),
subdir: guessRepositorySubdir({ configFile, projectRoot }),
Expand All @@ -52,7 +52,7 @@ export async function guessRepositoryInfo({
// For github https remotes such as https://github.com/cherrypush/cherry-cli.git
if (remoteUrl.includes('https://github.com')) {
return {
host: 'github.com',
host: Host.Github,
owner: remoteUrl.split('/')[3],
name: remoteUrl.split('/')[4].replace('.git', ''),
subdir: guessRepositorySubdir({ configFile, projectRoot }),
Expand Down
47 changes: 47 additions & 0 deletions src/templates.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { Repository } from './types.js'

export function getConfigTemplate(repositoryInfo: Repository) {
return `// For detailed configuration options, see the documentation:
// https://www.cherrypush.com/docs
//
// In this configuration file, you can set up your repository information,
// enable plugins, and define custom metrics for your codebase.

export default {
repository: {
host: '${repositoryInfo.host}',
owner: '${repositoryInfo.owner}',
name: '${repositoryInfo.name}',
subdir: '${repositoryInfo.subdir}',
},
plugins: { loc: {} },
metrics: [
{
name: 'TODO/FIXME',
pattern: /(TODO|FIXME):/i,
},
],
}`
}

export function getWorkflowTemplate() {
return `name: cherry push

on:
push:
branches:
- \${{ github.event.repository.default_branch }}

jobs:
cherry_push:
runs-on: ubuntu-latest
steps:
- name: Checkout project
uses: actions/checkout@v4

- name: Install dependencies
run: npm i -g cherrypush

- name: Push metrics to Cherry
run: cherry push --quiet --api-key=\${{ secrets.CHERRY_API_KEY }}`
}
Loading
Loading