create-platformatic 1.2.0 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -37,5 +37,5 @@ export {
37
37
  createDynamicWorkspaceGHAction
38
38
  } from './src/ghaction.mjs'
39
39
 
40
- export { createGitignore, createPackageJson, getDependencyVersion, getVersion } from './src/index.mjs'
40
+ export { createGitignore, createGitRepository, createPackageJson, getDependencyVersion, getVersion } from './src/index.mjs'
41
41
  export { default as createService } from './src/service/create-service.mjs'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-platformatic",
3
- "version": "1.2.0",
3
+ "version": "1.3.1",
4
4
  "description": "Create platformatic-db interactive tool",
5
5
  "repository": {
6
6
  "type": "git",
@@ -35,7 +35,7 @@
35
35
  "strip-ansi": "^7.1.0",
36
36
  "undici": "^5.25.4",
37
37
  "which": "^3.0.1",
38
- "@platformatic/config": "1.2.0"
38
+ "@platformatic/config": "1.3.1"
39
39
  },
40
40
  "devDependencies": {
41
41
  "ajv": "^8.12.0",
@@ -48,12 +48,13 @@
48
48
  "tap": "^16.3.9",
49
49
  "typescript": "~5.2.2",
50
50
  "yaml": "^2.3.2",
51
- "@platformatic/db": "1.2.0",
52
- "@platformatic/service": "1.2.0"
51
+ "@platformatic/db": "1.3.1",
52
+ "@platformatic/service": "1.3.1"
53
53
  },
54
54
  "scripts": {
55
- "test:cli": "tap --no-coverage test/cli/*test.mjs -t90",
56
- "test": "standard | snazzy && cross-env NODE_OPTIONS=\"--loader=esmock --no-warnings\" c8 tap --no-coverage test/*test.mjs test/*[!cli]/*test.mjs && npm run test:cli",
55
+ "test:cli": "tap --no-coverage test/cli/*test.mjs -t120",
56
+ "test:unit": "standard | snazzy && cross-env NODE_OPTIONS=\"--loader=esmock --no-warnings\" c8 tap --no-coverage test/*test.mjs test/*[!cli]/*test.mjs",
57
+ "test": "npm run test:unit && npm run test:cli",
57
58
  "lint": "standard | snazzy"
58
59
  }
59
60
  }
package/src/ask-dir.mjs CHANGED
@@ -1,5 +1,6 @@
1
1
  'use strict'
2
2
 
3
+ import { stat } from 'fs/promises'
3
4
  import inquirer from 'inquirer'
4
5
  import { resolve } from 'path'
5
6
 
@@ -12,6 +13,24 @@ const askProjectDir = async (logger, defaultName, message = 'Where would you lik
12
13
  })
13
14
 
14
15
  const projectDir = resolve(process.cwd(), options.dir)
16
+
17
+ try {
18
+ await stat(projectDir)
19
+ logger.warn(`Directory ${projectDir} is not empty. Some files may be overwritten without confirmation.`)
20
+ const confirmation = await inquirer.prompt({
21
+ type: 'list',
22
+ name: 'confirmExistingDirectory',
23
+ message: `Confirm you want to use ${projectDir} directory?`,
24
+ default: 'no',
25
+ choices: [{ name: 'yes', value: true }, { name: 'no', value: false }]
26
+ })
27
+ if (!confirmation.confirmExistingDirectory) {
28
+ logger.error('Please choose another directory.')
29
+ process.exit(1)
30
+ }
31
+ } catch (err) {
32
+ // directory is empty, we can proceed
33
+ }
15
34
  return projectDir
16
35
  }
17
36
 
@@ -19,6 +19,16 @@ export const getUseTypescript = typescript => {
19
19
  }
20
20
  }
21
21
 
22
+ export const getInitGitRepository = () => {
23
+ return {
24
+ type: 'list',
25
+ name: 'initGitRepository',
26
+ message: 'Do you want to init the git repository?',
27
+ default: false,
28
+ choices: [{ name: 'yes', value: true }, { name: 'no', value: false }]
29
+ }
30
+ }
31
+
22
32
  let port = 3042
23
33
  export const getPort = (nextPort) => {
24
34
  if (nextPort === undefined) {
@@ -1,19 +1,17 @@
1
- import { getVersion, getDependencyVersion } from '../utils.mjs'
1
+ import { getVersion, getDependencyVersion, safeMkdir } from '../utils.mjs'
2
2
  import { createPackageJson } from '../create-package-json.mjs'
3
3
  import { createGitignore } from '../create-gitignore.mjs'
4
4
  import { getPkgManager } from '../get-pkg-manager.mjs'
5
5
  import parseArgs from 'minimist'
6
6
  import inquirer from 'inquirer'
7
- import { mkdir } from 'fs/promises'
8
7
  import pino from 'pino'
9
8
  import pretty from 'pino-pretty'
10
9
  import { execa } from 'execa'
11
10
  import ora from 'ora'
12
11
  import createComposer from './create-composer.mjs'
13
12
  import askDir from '../ask-dir.mjs'
14
- import { getRunPackageManagerInstall, getPort, getUseTypescript } from '../cli-options.mjs'
13
+ import { getRunPackageManagerInstall, getPort, getUseTypescript, getInitGitRepository } from '../cli-options.mjs'
15
14
  import { createReadme } from '../create-readme.mjs'
16
- import { stat } from 'node:fs/promises'
17
15
  import { join } from 'path'
18
16
 
19
17
  export const getServicesToCompose = (servicesNames) => {
@@ -46,13 +44,6 @@ const createPlatformaticComposer = async (_args, opts) => {
46
44
  const pkgManager = getPkgManager()
47
45
 
48
46
  const projectDir = opts.dir || await askDir(logger, join('.', 'platformatic-composer'))
49
- // checks directory
50
- try {
51
- await stat(projectDir)
52
- logger.error(`Directory ${projectDir} already exists. Please choose another path.`)
53
- process.exit(1)
54
- } catch (err) {}
55
-
56
47
  const isRuntimeContext = opts.isRuntimeContext || false
57
48
 
58
49
  const toAsk = []
@@ -91,17 +82,22 @@ const createPlatformaticComposer = async (_args, opts) => {
91
82
  choices: [{ name: 'yes', value: true }, { name: 'no', value: false }]
92
83
  })
93
84
  }
85
+
86
+ if (!opts.skipGitRepository) {
87
+ toAsk.push(getInitGitRepository())
88
+ }
94
89
  const {
95
90
  runPackageManagerInstall,
96
91
  servicesToCompose,
97
92
  port,
98
93
  staticWorkspaceGitHubAction,
99
94
  dynamicWorkspaceGitHubAction,
100
- useTypescript
95
+ useTypescript,
96
+ initGitRepository
101
97
  } = await inquirer.prompt(toAsk)
102
98
 
103
99
  // Create the project directory
104
- await mkdir(projectDir, { recursive: true })
100
+ await safeMkdir(projectDir)
105
101
 
106
102
  const params = {
107
103
  isRuntimeContext,
@@ -111,7 +107,8 @@ const createPlatformaticComposer = async (_args, opts) => {
111
107
  staticWorkspaceGitHubAction,
112
108
  dynamicWorkspaceGitHubAction,
113
109
  runtimeContext: opts.runtimeContext,
114
- typescript: useTypescript
110
+ typescript: useTypescript,
111
+ initGitRepository
115
112
  }
116
113
 
117
114
  await createComposer(
@@ -1,10 +1,10 @@
1
1
  import { readFile, writeFile, appendFile } from 'fs/promises'
2
- import { findComposerConfigFile, isFileAccessible } from '../utils.mjs'
3
2
  import { join } from 'path'
4
3
  import * as desm from 'desm'
5
4
  import { generatePlugins, generateRouteWithTypesSupport } from '../create-plugins.mjs'
6
5
  import { createDynamicWorkspaceGHAction, createStaticWorkspaceGHAction } from '../ghaction.mjs'
7
6
  import { getTsConfig } from '../get-tsconfig.mjs'
7
+ import { createGitRepository } from '../create-git-repository.mjs'
8
8
 
9
9
  const TS_OUT_DIR = 'dist'
10
10
 
@@ -93,7 +93,8 @@ async function createComposer (
93
93
  runtimeContext,
94
94
  typescript,
95
95
  staticWorkspaceGitHubAction,
96
- dynamicWorkspaceGitHubAction
96
+ dynamicWorkspaceGitHubAction,
97
+ initGitRepository
97
98
  } = params
98
99
 
99
100
  const composerEnv = {
@@ -105,28 +106,17 @@ async function createComposer (
105
106
  const pkg = await readFile(desm.join(import.meta.url, '..', '..', 'package.json'))
106
107
  version = JSON.parse(pkg).version
107
108
  }
108
- const accessibleConfigFilename = await findComposerConfigFile(currentDir)
109
-
110
- if (accessibleConfigFilename === undefined) {
111
- const envPrefix = runtimeContext !== undefined ? `${runtimeContext.envPrefix}_` : ''
112
-
113
- const config = generateConfig(isRuntimeContext, version, servicesToCompose, typescript, envPrefix)
114
- await writeFile(join(currentDir, 'platformatic.composer.json'), JSON.stringify(config, null, 2))
115
- logger.info('Configuration file platformatic.composer.json successfully created.')
116
-
117
- const env = generateEnv(isRuntimeContext, hostname, port, typescript, envPrefix)
118
- const envFileExists = await isFileAccessible('.env', currentDir)
119
- await appendFile(join(currentDir, '.env'), env)
120
- await writeFile(join(currentDir, '.env.sample'), env)
121
- /* c8 ignore next 5 */
122
- if (envFileExists) {
123
- logger.info('Environment file .env found, appending new environment variables to existing .env file.')
124
- } else {
125
- logger.info('Environment file .env successfully created.')
126
- }
127
- } else {
128
- logger.info(`Configuration file ${accessibleConfigFilename} found, skipping creation of configuration file.`)
129
- }
109
+ const envPrefix = runtimeContext !== undefined ? `${runtimeContext.envPrefix}_` : ''
110
+
111
+ const config = generateConfig(isRuntimeContext, version, servicesToCompose, typescript, envPrefix)
112
+ await writeFile(join(currentDir, 'platformatic.composer.json'), JSON.stringify(config, null, 2))
113
+ logger.info('Configuration file platformatic.composer.json successfully created.')
114
+
115
+ const env = generateEnv(isRuntimeContext, hostname, port, typescript, envPrefix)
116
+ await appendFile(join(currentDir, '.env'), env)
117
+ await writeFile(join(currentDir, '.env.sample'), env)
118
+ /* c8 ignore next 5 */
119
+ logger.info('Environment file .env successfully created.')
130
120
  await generatePlugins(logger, currentDir, typescript, 'composer')
131
121
  await generateRouteWithTypesSupport(logger, currentDir, true)
132
122
 
@@ -147,6 +137,10 @@ async function createComposer (
147
137
  await createDynamicWorkspaceGHAction(logger, composerEnv, './platformatic.service.json', currentDir, typescript)
148
138
  }
149
139
 
140
+ if (initGitRepository) {
141
+ await createGitRepository(logger, currentDir)
142
+ }
143
+
150
144
  return composerEnv
151
145
  }
152
146
 
@@ -0,0 +1,105 @@
1
+ import { execa } from 'execa'
2
+
3
+ export const GIT_FIRST_COMMIT_MESSAGE = 'Platformatic project started! 🚀'
4
+ export const GIT_MAIN_BRANCH = 'main'
5
+
6
+ /**
7
+ * Creates a Git repository and performs the initial commit if it doesn't already exist.
8
+ *
9
+ * This function checks if Git is installed, initializes a Git repository in the specified
10
+ * directory if it's not already a Git repository, and performs the initial commit.
11
+ *
12
+ * @param {import('pino.').BaseLogger} logger - The logger interface for logging messages.
13
+ * @param {string} [dir='.'] - The target directory where the Git repository should be created.
14
+ */
15
+ export async function createGitRepository (logger, dir = '.') {
16
+ if (!await isGitInstalled()) {
17
+ logger.error('Git is not installed')
18
+ return
19
+ }
20
+
21
+ if (!await gitInit(logger, dir)) {
22
+ return
23
+ }
24
+
25
+ if (!await gitCommit(logger, dir)) {
26
+ return
27
+ }
28
+
29
+ logger.info('Git repository initialized.')
30
+ }
31
+
32
+ /**
33
+ * Checks if Git is installed on the system.
34
+ *
35
+ * @async
36
+ * @returns {Promise<boolean>} A Promise that resolves to true if Git is installed, false otherwise.
37
+ */
38
+ async function isGitInstalled () {
39
+ try {
40
+ await execa('git', ['--version'])
41
+ return true
42
+ } catch (err) {
43
+ return false
44
+ }
45
+ }
46
+
47
+ /**
48
+ * Checks if a Git repository exists in the specified directory.
49
+ *
50
+ * @async
51
+ * @param {string} dir - The directory to check for a Git repository.
52
+ * @returns {Promise<boolean>} A Promise that resolves to true if a Git repository exists in the directory, false otherwise.
53
+ */
54
+ async function doesGitRepositoryExist (dir) {
55
+ try {
56
+ await execa('git', ['rev-parse', '--is-inside-work-tree'], { cwd: dir })
57
+ return true
58
+ } catch (e) {
59
+ return false
60
+ }
61
+ }
62
+
63
+ /**
64
+ * Initializes a Git repository in the specified directory if it doesn't already exist.
65
+ *
66
+ * @async
67
+ * @param {import('pino.').BaseLogger} - The logger object for logging messages.
68
+ * @param {string} dir - The directory where the Git repository should be initialized.
69
+ * @returns {Promise<boolean>} A Promise that resolves to true if the Git repository is successfully initialized, false otherwise.
70
+ */
71
+ async function gitInit (logger, dir) {
72
+ try {
73
+ if (await doesGitRepositoryExist(dir)) {
74
+ logger.info('Git repository already exists.')
75
+ return false
76
+ }
77
+
78
+ await execa('git', ['init', '-b', GIT_MAIN_BRANCH], { cwd: dir })
79
+ logger.debug('Git repository initialized.')
80
+ return true
81
+ } catch (err) {
82
+ logger.error('Git repository init failed.', err)
83
+ return false
84
+ }
85
+ }
86
+
87
+ /**
88
+ * Commits changes in a Git repository located in the specified directory.
89
+ *
90
+ * @async
91
+ * @param {import('pino.').BaseLogger} - The logger object for logging messages.
92
+ * @param {string} dir - The directory of the Git repository where changes should be committed.
93
+ * @returns {Promise<boolean>} A Promise that resolves to true if the Git commit is successful, false otherwise.
94
+ */
95
+ async function gitCommit (logger, dir) {
96
+ try {
97
+ await execa('git', ['add', '-A'], { cwd: dir })
98
+ await execa('git', ['commit', '-m', GIT_FIRST_COMMIT_MESSAGE], { cwd: dir })
99
+ logger.debug('Git commit done.')
100
+ return true
101
+ } catch (err) {
102
+ logger.error('Git commit failed.', err)
103
+ return false
104
+ }
105
+ }
@@ -1,4 +1,3 @@
1
- import { isFileAccessible } from './utils.mjs'
2
1
  import { writeFile } from 'fs/promises'
3
2
  import { join } from 'node:path'
4
3
 
@@ -38,11 +37,6 @@ tags
38
37
  */
39
38
  export const createGitignore = async (logger, dir = '.') => {
40
39
  const gitignoreFileName = join(dir, '.gitignore')
41
- const isGitignoreExists = await isFileAccessible(gitignoreFileName)
42
- if (!isGitignoreExists) {
43
- await writeFile(gitignoreFileName, gitignore)
44
- logger.debug(`Gitignore file ${gitignoreFileName} successfully created.`)
45
- } else {
46
- logger.debug(`Gitignore file ${gitignoreFileName} found, skipping creation of gitignore file.`)
47
- }
40
+ await writeFile(gitignoreFileName, gitignore)
41
+ logger.debug(`Gitignore file ${gitignoreFileName} successfully created.`)
48
42
  }
@@ -1,4 +1,3 @@
1
- import { isFileAccessible } from './utils.mjs'
2
1
  import { writeFile, readFile } from 'fs/promises'
3
2
  import { join } from 'node:path'
4
3
  import { fileURLToPath } from 'node:url'
@@ -50,14 +49,9 @@ const packageJsonTemplate = async (addTSBuild, fastifyVersion, platVersion) => {
50
49
  */
51
50
  export const createPackageJson = async (platVersion, fastifyVersion, logger, dir, addTSBuild = false, scripts = {}, dependencies = {}) => {
52
51
  const packageJsonFileName = join(dir, 'package.json')
53
- const isPackageJsonExists = await isFileAccessible(packageJsonFileName)
54
- if (!isPackageJsonExists) {
55
- const pkg = await packageJsonTemplate(addTSBuild, fastifyVersion, platVersion)
56
- Object.assign(pkg.scripts, scripts)
57
- Object.assign(pkg.dependencies, dependencies)
58
- await writeFile(packageJsonFileName, JSON.stringify(pkg, null, 2))
59
- logger.debug(`${packageJsonFileName} successfully created.`)
60
- } else {
61
- logger.debug(`${packageJsonFileName} found, skipping creation of package.json file.`)
62
- }
52
+ const pkg = await packageJsonTemplate(addTSBuild, fastifyVersion, platVersion)
53
+ Object.assign(pkg.scripts, scripts)
54
+ Object.assign(pkg.dependencies, dependencies)
55
+ await writeFile(packageJsonFileName, JSON.stringify(pkg, null, 2))
56
+ logger.debug(`${packageJsonFileName} successfully created.`)
63
57
  }
@@ -1,6 +1,6 @@
1
1
  import { join } from 'path'
2
- import { writeFile, mkdir } from 'fs/promises'
3
- import { isFileAccessible } from './utils.mjs'
2
+ import { writeFile } from 'fs/promises'
3
+ import { safeMkdir } from './utils.mjs'
4
4
 
5
5
  const JS_PLUGIN_WITH_TYPES_SUPPORT = `\
6
6
  /// <reference path="../global.d.ts" />
@@ -168,12 +168,7 @@ test('example decorator', async (t) => {
168
168
  `
169
169
 
170
170
  export async function generatePluginWithTypesSupport (logger, currentDir, isTypescript) {
171
- const accessible = await isFileAccessible('plugins', currentDir)
172
- if (accessible) {
173
- logger.info('Plugins folder "plugins" found, skipping creation of plugins folder.')
174
- return
175
- }
176
- await mkdir(join(currentDir, 'plugins'))
171
+ await safeMkdir(join(currentDir, 'plugins'))
177
172
  const pluginTemplate = isTypescript
178
173
  ? TS_PLUGIN_WITH_TYPES_SUPPORT
179
174
  : JS_PLUGIN_WITH_TYPES_SUPPORT
@@ -185,12 +180,7 @@ export async function generatePluginWithTypesSupport (logger, currentDir, isType
185
180
  }
186
181
 
187
182
  export async function generateRouteWithTypesSupport (logger, currentDir, isTypescript) {
188
- const accessible = await isFileAccessible('routes', currentDir)
189
- if (accessible) {
190
- logger.info('Routes folder "routes" found, skipping creation of routes folder.')
191
- return
192
- }
193
- await mkdir(join(currentDir, 'routes'))
183
+ await safeMkdir(join(currentDir, 'routes'))
194
184
  const routesTemplate = isTypescript
195
185
  ? TS_ROUTES_WITH_TYPES_SUPPORT
196
186
  : JS_ROUTES_WITH_TYPES_SUPPORT
@@ -202,15 +192,9 @@ export async function generateRouteWithTypesSupport (logger, currentDir, isTypes
202
192
  }
203
193
 
204
194
  export async function generateTests (logger, currentDir, isTypescript, mod, customizations) {
205
- const accessible = await isFileAccessible('tests', currentDir)
206
- if (accessible) {
207
- logger.info('Test folder found, skipping creation of tests.')
208
- return
209
- }
210
-
211
- await mkdir(join(currentDir, 'test'))
212
- await mkdir(join(currentDir, 'test', 'plugins'))
213
- await mkdir(join(currentDir, 'test', 'routes'))
195
+ await safeMkdir(join(currentDir, 'test'))
196
+ await safeMkdir(join(currentDir, 'test', 'plugins'))
197
+ await safeMkdir(join(currentDir, 'test', 'routes'))
214
198
 
215
199
  if (isTypescript) {
216
200
  await writeFile(join(currentDir, 'test', 'helper.ts'), testHelperTS(mod, customizations))
@@ -1,18 +1,17 @@
1
- import { getVersion, getDependencyVersion } from '../utils.mjs'
1
+ import { getVersion, getDependencyVersion, safeMkdir } from '../utils.mjs'
2
2
  import { createPackageJson } from '../create-package-json.mjs'
3
3
  import { createGitignore } from '../create-gitignore.mjs'
4
4
  import { getPkgManager } from '../get-pkg-manager.mjs'
5
5
  import parseArgs from 'minimist'
6
6
  import inquirer from 'inquirer'
7
7
  import which from 'which'
8
- import { mkdir, stat } from 'fs/promises'
9
8
  import pino from 'pino'
10
9
  import pretty from 'pino-pretty'
11
10
  import { execa } from 'execa'
12
11
  import ora from 'ora'
13
12
  import { getConnectionString, createDB } from './create-db.mjs'
14
13
  import askDir from '../ask-dir.mjs'
15
- import { getRunPackageManagerInstall, getUseTypescript, getPort } from '../cli-options.mjs'
14
+ import { getRunPackageManagerInstall, getUseTypescript, getPort, getInitGitRepository } from '../cli-options.mjs'
16
15
  import { createReadme } from '../create-readme.mjs'
17
16
  import { join } from 'node:path'
18
17
 
@@ -61,13 +60,6 @@ const createPlatformaticDB = async (_args, opts) => {
61
60
  const pkgManager = getPkgManager()
62
61
  const projectDir = opts.dir || await askDir(logger, join('.', 'platformatic-db'))
63
62
 
64
- // Create the project directory
65
- try {
66
- await stat(projectDir)
67
- logger.error(`Directory ${projectDir} already exists. Please choose another path.`)
68
- process.exit(1)
69
- } catch (err) {}
70
-
71
63
  const isRuntimeContext = opts.isRuntimeContext || false
72
64
  const toAsk = []
73
65
 
@@ -169,11 +161,13 @@ const createPlatformaticDB = async (_args, opts) => {
169
161
  when: !opts.skipGitHubActions,
170
162
  choices: [{ name: 'yes', value: true }, { name: 'no', value: false }]
171
163
  })
172
-
164
+ if (!opts.skipGitRepository) {
165
+ toAsk.push(getInitGitRepository())
166
+ }
173
167
  // Prompt for questions
174
168
  const wizardOptions = await inquirer.prompt(toAsk)
175
169
 
176
- await mkdir(projectDir, { recursive: true })
170
+ await safeMkdir(projectDir)
177
171
 
178
172
  const generatePlugin = args.plugin || wizardOptions.generatePlugin
179
173
  const useTypescript = args.typescript || wizardOptions.useTypescript
@@ -191,7 +185,8 @@ const createPlatformaticDB = async (_args, opts) => {
191
185
  typescript: useTypescript,
192
186
  staticWorkspaceGitHubAction: wizardOptions.staticWorkspaceGitHubAction,
193
187
  dynamicWorkspaceGitHubAction: wizardOptions.dynamicWorkspaceGitHubAction,
194
- runtimeContext: opts.runtimeContext
188
+ runtimeContext: opts.runtimeContext,
189
+ initGitRepository: wizardOptions.initGitRepository
195
190
  }
196
191
 
197
192
  await createDB(params, logger, projectDir, version)
@@ -1,9 +1,10 @@
1
- import { writeFile, mkdir, appendFile } from 'fs/promises'
1
+ import { writeFile, appendFile } from 'fs/promises'
2
2
  import { join } from 'path'
3
- import { addPrefixToEnv, findDBConfigFile, isFileAccessible } from '../utils.mjs'
3
+ import { addPrefixToEnv, safeMkdir } from '../utils.mjs'
4
4
  import { getTsConfig } from '../get-tsconfig.mjs'
5
5
  import { generatePlugins } from '../create-plugins.mjs'
6
6
  import { createDynamicWorkspaceGHAction, createStaticWorkspaceGHAction } from '../ghaction.mjs'
7
+ import { createGitRepository } from '../create-git-repository.mjs'
7
8
 
8
9
  const connectionStrings = {
9
10
  postgres: 'postgres://postgres:postgres@127.0.0.1:5432/postgres',
@@ -349,7 +350,8 @@ export async function createDB (params, logger, currentDir, version) {
349
350
  connectionString,
350
351
  staticWorkspaceGitHubAction,
351
352
  dynamicWorkspaceGitHubAction,
352
- runtimeContext
353
+ runtimeContext,
354
+ initGitRepository
353
355
  } = params
354
356
 
355
357
  const dbEnv = {
@@ -364,56 +366,33 @@ export async function createDB (params, logger, currentDir, version) {
364
366
  }
365
367
  connectionString = connectionString || getConnectionString(database)
366
368
  const createMigrations = !!migrations // If we don't define a migrations folder, we don't create it
367
- const accessibleConfigFilename = await findDBConfigFile(currentDir)
368
-
369
- if (accessibleConfigFilename === undefined) {
370
- const envPrefix = runtimeContext !== undefined ? `${runtimeContext.envPrefix}_` : ''
371
-
372
- const config = generateConfig(isRuntimeContext, migrations, plugin, types, typescript, version, envPrefix)
373
- await writeFile(join(currentDir, 'platformatic.db.json'), JSON.stringify(config, null, 2))
374
- logger.info('Configuration file platformatic.db.json successfully created.')
375
-
376
- const env = generateEnv(isRuntimeContext, hostname, port, connectionString, typescript, envPrefix)
377
- const envSample = generateEnv(isRuntimeContext, hostname, port, getConnectionString(database), typescript, envPrefix)
378
- const envFileExists = await isFileAccessible('.env', currentDir)
379
- await appendFile(join(currentDir, '.env'), env)
380
- await writeFile(join(currentDir, '.env.sample'), envSample)
381
- /* c8 ignore next 5 */
382
- if (envFileExists) {
383
- logger.info('Environment file .env found, appending new environment variables to existing .env file.')
384
- } else {
385
- logger.info('Environment file .env successfully created.')
386
- }
387
- } else {
388
- logger.info(`Configuration file ${accessibleConfigFilename} found, skipping creation of configuration file.`)
389
- }
369
+ const envPrefix = runtimeContext !== undefined ? `${runtimeContext.envPrefix}_` : ''
370
+
371
+ const config = generateConfig(isRuntimeContext, migrations, plugin, types, typescript, version, envPrefix)
372
+ await writeFile(join(currentDir, 'platformatic.db.json'), JSON.stringify(config, null, 2))
373
+ logger.info('Configuration file platformatic.db.json successfully created.')
374
+
375
+ const env = generateEnv(isRuntimeContext, hostname, port, connectionString, typescript, envPrefix)
376
+ const envSample = generateEnv(isRuntimeContext, hostname, port, getConnectionString(database), typescript, envPrefix)
377
+ await appendFile(join(currentDir, '.env'), env)
378
+ await writeFile(join(currentDir, '.env.sample'), envSample)
379
+ logger.info('Environment file .env found, appending new environment variables to existing .env file.')
390
380
 
391
381
  const migrationsFolderName = migrations
392
382
  if (createMigrations) {
393
- const isMigrationFolderExists = await isFileAccessible(migrationsFolderName, currentDir)
394
- if (!isMigrationFolderExists) {
395
- await mkdir(join(currentDir, migrationsFolderName), { recursive: true })
396
- logger.info(`Migrations folder ${migrationsFolderName} successfully created.`)
397
- } else {
398
- logger.info(`Migrations folder ${migrationsFolderName} found, skipping creation of migrations folder.`)
399
- }
383
+ await safeMkdir(join(currentDir, migrationsFolderName))
384
+ logger.info(`Migrations folder ${migrationsFolderName} successfully created.`)
400
385
  }
401
386
 
402
387
  const migrationFileNameDo = '001.do.sql'
403
388
  const migrationFileNameUndo = '001.undo.sql'
404
389
  const migrationFilePathDo = join(currentDir, migrationsFolderName, migrationFileNameDo)
405
390
  const migrationFilePathUndo = join(currentDir, migrationsFolderName, migrationFileNameUndo)
406
- const isMigrationFileDoExists = await isFileAccessible(migrationFilePathDo)
407
- const isMigrationFileUndoExists = await isFileAccessible(migrationFilePathUndo)
408
- if (!isMigrationFileDoExists && createMigrations) {
391
+ if (createMigrations) {
409
392
  await writeFile(migrationFilePathDo, moviesMigrationDo(database))
410
393
  logger.info(`Migration file ${migrationFileNameDo} successfully created.`)
411
- if (!isMigrationFileUndoExists) {
412
- await writeFile(migrationFilePathUndo, moviesMigrationUndo)
413
- logger.info(`Migration file ${migrationFileNameUndo} successfully created.`)
414
- }
415
- } else {
416
- logger.info(`Migration file ${migrationFileNameDo} found, skipping creation of migration file.`)
394
+ await writeFile(migrationFilePathUndo, moviesMigrationUndo)
395
+ logger.info(`Migration file ${migrationFileNameUndo} successfully created.`)
417
396
  }
418
397
 
419
398
  if (typescript === true) {
@@ -457,9 +436,14 @@ export async function createDB (params, logger, currentDir, version) {
457
436
  await createDynamicWorkspaceGHAction(logger, dbEnv, './platformatic.db.json', currentDir, typescript)
458
437
  }
459
438
 
439
+ if (initGitRepository) {
440
+ await createGitRepository(logger, currentDir)
441
+ }
442
+
460
443
  if (isRuntimeContext) {
461
444
  return addPrefixToEnv(isRuntimeContext)
462
445
  }
446
+
463
447
  return dbEnv
464
448
  }
465
449
 
package/src/ghaction.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import { join } from 'path'
2
- import { isFileAccessible } from './utils.mjs'
3
- import { writeFile, mkdir } from 'fs/promises'
2
+ import { isFileAccessible, safeMkdir } from './utils.mjs'
3
+ import { writeFile } from 'fs/promises'
4
4
  import columnify from 'columnify'
5
5
  function envAsString (env, indent) {
6
6
  const spaces = Array(indent * 2).join(' ')
@@ -125,49 +125,39 @@ ${envString}
125
125
  export const createDynamicWorkspaceGHAction = async (logger, env, config, projectDir, buildTS) => {
126
126
  const ghActionFileName = 'platformatic-dynamic-workspace-deploy.yml'
127
127
  const ghActionFilePath = join(projectDir, '.github', 'workflows', ghActionFileName)
128
- const isGithubActionExists = await isFileAccessible(ghActionFilePath)
129
- if (!isGithubActionExists) {
130
- await mkdir(join(projectDir, '.github', 'workflows'), { recursive: true })
131
- await writeFile(ghActionFilePath, dynamicWorkspaceGHTemplate(env, config, buildTS))
132
- logger.info('PR Previews are enabled for your app and the Github action was successfully created, please add the following secrets as repository secrets: ')
133
- const envToBeAdded = { ...env }
134
- delete envToBeAdded.PORT
135
- const secretsString = formatSecretsToAdd({
136
- PLATFORMATIC_DYNAMIC_WORKSPACE_ID: 'your workspace id',
137
- PLATFORMATIC_DYNAMIC_WORKSPACE_API_KEY: 'your workspace API key',
138
- ...envToBeAdded
139
- })
140
- logger.info(`\n ${secretsString}`)
141
- const isGitDir = await isFileAccessible('.git', projectDir)
142
- if (!isGitDir) {
143
- logger.warn('No git repository found. The Github action won\'t be triggered.')
144
- }
145
- } else {
146
- logger.info(`Github action file ${ghActionFilePath} found, skipping creation of github action file.`)
128
+ await safeMkdir(join(projectDir, '.github', 'workflows'), { recursive: true })
129
+ await writeFile(ghActionFilePath, dynamicWorkspaceGHTemplate(env, config, buildTS))
130
+ logger.info('PR Previews are enabled for your app and the Github action was successfully created, please add the following secrets as repository secrets: ')
131
+ const envToBeAdded = { ...env }
132
+ delete envToBeAdded.PORT
133
+ const secretsString = formatSecretsToAdd({
134
+ PLATFORMATIC_DYNAMIC_WORKSPACE_ID: 'your workspace id',
135
+ PLATFORMATIC_DYNAMIC_WORKSPACE_API_KEY: 'your workspace API key',
136
+ ...envToBeAdded
137
+ })
138
+ logger.info(`\n ${secretsString}`)
139
+ const isGitDir = await isFileAccessible('.git', projectDir)
140
+ if (!isGitDir) {
141
+ logger.warn('No git repository found. The Github action won\'t be triggered.')
147
142
  }
148
143
  }
149
144
 
150
145
  export const createStaticWorkspaceGHAction = async (logger, env, config, projectDir, buildTS) => {
151
146
  const ghActionFileName = 'platformatic-static-workspace-deploy.yml'
152
147
  const ghActionFilePath = join(projectDir, '.github', 'workflows', ghActionFileName)
153
- const isGithubActionExists = await isFileAccessible(ghActionFilePath)
154
- if (!isGithubActionExists) {
155
- await mkdir(join(projectDir, '.github', 'workflows'), { recursive: true })
156
- await writeFile(ghActionFilePath, staticWorkspaceGHTemplate(env, config, buildTS))
157
- logger.info('Github action successfully created, please add the following secrets as repository secrets: ')
158
- const envToBeAdded = { ...env }
159
- delete envToBeAdded.PORT
160
- const secretsString = formatSecretsToAdd({
161
- PLATFORMATIC_STATIC_WORKSPACE_ID: 'your workspace id',
162
- PLATFORMATIC_STATIC_WORKSPACE_API_KEY: 'your workspace API key',
163
- ...envToBeAdded
164
- })
165
- logger.info(`\n ${secretsString}`)
166
- const isGitDir = await isFileAccessible('.git', projectDir)
167
- if (!isGitDir) {
168
- logger.warn('No git repository found. The Github action won\'t be triggered.')
169
- }
170
- } else {
171
- logger.info(`Github action file ${ghActionFilePath} found, skipping creation of github action file.`)
148
+ await safeMkdir(join(projectDir, '.github', 'workflows'), { recursive: true })
149
+ await writeFile(ghActionFilePath, staticWorkspaceGHTemplate(env, config, buildTS))
150
+ logger.info('Github action successfully created, please add the following secrets as repository secrets: ')
151
+ const envToBeAdded = { ...env }
152
+ delete envToBeAdded.PORT
153
+ const secretsString = formatSecretsToAdd({
154
+ PLATFORMATIC_STATIC_WORKSPACE_ID: 'your workspace id',
155
+ PLATFORMATIC_STATIC_WORKSPACE_API_KEY: 'your workspace API key',
156
+ ...envToBeAdded
157
+ })
158
+ logger.info(`\n ${secretsString}`)
159
+ const isGitDir = await isFileAccessible('.git', projectDir)
160
+ if (!isGitDir) {
161
+ logger.warn('No git repository found. The Github action won\'t be triggered.')
172
162
  }
173
163
  }
package/src/index.mjs CHANGED
@@ -11,6 +11,7 @@ import commist from 'commist'
11
11
  import { getUsername, getVersion, minimumSupportedNodeVersions, isCurrentVersionSupported, findRuntimeConfigFile, getDependencyVersion } from './utils.mjs'
12
12
  import { createPackageJson } from './create-package-json.mjs'
13
13
  import { createGitignore } from './create-gitignore.mjs'
14
+ import { createGitRepository } from './create-git-repository.mjs'
14
15
 
15
16
  export async function chooseKind (argv, opts = {}) {
16
17
  const skip = opts.skip
@@ -107,6 +108,7 @@ export default createPlatformatic
107
108
  export {
108
109
  createPackageJson,
109
110
  createGitignore,
111
+ createGitRepository,
110
112
  getVersion,
111
113
  getDependencyVersion
112
114
  }
@@ -1,17 +1,16 @@
1
- import { getVersion, getDependencyVersion, convertServiceNameToPrefix } from '../utils.mjs'
1
+ import { getVersion, getDependencyVersion, convertServiceNameToPrefix, safeMkdir } from '../utils.mjs'
2
2
  import { createPackageJson } from '../create-package-json.mjs'
3
3
  import { createGitignore } from '../create-gitignore.mjs'
4
4
  import { getPkgManager } from '../get-pkg-manager.mjs'
5
5
  import { join, relative, resolve } from 'path'
6
6
  import inquirer from 'inquirer'
7
- import { mkdir, stat } from 'fs/promises'
8
7
  import pino from 'pino'
9
8
  import pretty from 'pino-pretty'
10
9
  import { execa } from 'execa'
11
10
  import ora from 'ora'
12
11
  import createRuntime from './create-runtime.mjs'
13
12
  import askDir from '../ask-dir.mjs'
14
- import { getPort, getRunPackageManagerInstall } from '../cli-options.mjs'
13
+ import { getInitGitRepository, getPort, getRunPackageManagerInstall } from '../cli-options.mjs'
15
14
  import generateName from 'boring-name-generator'
16
15
  import { chooseKind } from '../index.mjs'
17
16
  import { createReadme } from '../create-readme.mjs'
@@ -27,15 +26,9 @@ export async function createPlatformaticRuntime (_args) {
27
26
 
28
27
  const projectDir = await askDir(logger, join('.', 'platformatic-runtime'))
29
28
 
30
- // checks directory
31
- try {
32
- await stat(projectDir)
33
- logger.error(`Directory ${projectDir} already exists. Please choose another path.`)
34
- process.exit(1)
35
- } catch (err) {}
36
29
  const toAsk = []
37
30
  // Create the project directory
38
- await mkdir(projectDir, { recursive: true })
31
+ await safeMkdir(projectDir)
39
32
 
40
33
  const baseServicesDir = join(relative(process.cwd(), projectDir), 'services')
41
34
  const servicesDir = await askDir(logger, baseServicesDir, 'Where would you like to load your services from?')
@@ -67,13 +60,15 @@ export async function createPlatformaticRuntime (_args) {
67
60
  choices: [{ name: 'yes', value: true }, { name: 'no', value: false }]
68
61
  })
69
62
 
63
+ toAsk.push(getInitGitRepository())
70
64
  const {
71
65
  runPackageManagerInstall,
72
66
  staticWorkspaceGitHubAction,
73
- dynamicWorkspaceGitHubAction
67
+ dynamicWorkspaceGitHubAction,
68
+ initGitRepository
74
69
  } = await inquirer.prompt(toAsk)
75
70
 
76
- await mkdir(servicesDir, { recursive: true })
71
+ await safeMkdir(servicesDir)
77
72
 
78
73
  const fastifyVersion = await getDependencyVersion('fastify')
79
74
 
@@ -130,7 +125,8 @@ export async function createPlatformaticRuntime (_args) {
130
125
  entrypointPort,
131
126
  staticWorkspaceGitHubAction,
132
127
  dynamicWorkspaceGitHubAction,
133
- serviceNames: names
128
+ serviceNames: names,
129
+ initGitRepository
134
130
  }
135
131
 
136
132
  await createRuntime(params, logger, projectDir, version)
@@ -180,6 +176,7 @@ export async function createRuntimeService ({ servicesDir, names, logger }) {
180
176
  skipGitHubActions: true,
181
177
  skipPackageJson: true,
182
178
  skipGitignore: true,
179
+ skipGitRepository: true,
183
180
  port: '0',
184
181
  isRuntimeContext: true,
185
182
  runtimeContext: {
@@ -1,8 +1,8 @@
1
1
  import { readFile, writeFile, readdir, unlink } from 'fs/promises'
2
- import { findRuntimeConfigFile } from '../utils.mjs'
3
2
  import { join, relative, isAbsolute } from 'path'
4
3
  import * as desm from 'desm'
5
4
  import { createDynamicWorkspaceGHAction, createStaticWorkspaceGHAction } from '../ghaction.mjs'
5
+ import { createGitRepository } from '../create-git-repository.mjs'
6
6
 
7
7
  function generateConfig (version, path, entrypoint) {
8
8
  const config = {
@@ -25,23 +25,17 @@ async function createRuntime (params, logger, currentDir = process.cwd(), versio
25
25
  entrypoint,
26
26
  entrypointPort,
27
27
  staticWorkspaceGitHubAction,
28
- dynamicWorkspaceGitHubAction
28
+ dynamicWorkspaceGitHubAction,
29
+ initGitRepository
29
30
  } = params
30
-
31
31
  if (!version) {
32
32
  const pkg = await readFile(desm.join(import.meta.url, '..', '..', 'package.json'))
33
33
  version = JSON.parse(pkg).version
34
34
  }
35
- const accessibleConfigFilename = await findRuntimeConfigFile(currentDir)
36
-
37
- if (accessibleConfigFilename === undefined) {
38
- const path = isAbsolute(servicesDir) ? relative(currentDir, servicesDir) : servicesDir
39
- const config = generateConfig(version, path, entrypoint)
40
- await writeFile(join(currentDir, 'platformatic.runtime.json'), JSON.stringify(config, null, 2))
41
- logger.info('Configuration file platformatic.runtime.json successfully created.')
42
- } else {
43
- logger.info(`Configuration file ${accessibleConfigFilename} found, skipping creation of configuration file.`)
44
- }
35
+ const path = isAbsolute(servicesDir) ? relative(currentDir, servicesDir) : servicesDir
36
+ const config = generateConfig(version, path, entrypoint)
37
+ await writeFile(join(currentDir, 'platformatic.runtime.json'), JSON.stringify(config, null, 2))
38
+ logger.info('Configuration file platformatic.runtime.json successfully created.')
45
39
  let runtimeEnv = {}
46
40
  if (servicesDir && entrypoint && entrypointPort) {
47
41
  const servicesDirFullPath = isAbsolute(servicesDir)
@@ -59,6 +53,9 @@ async function createRuntime (params, logger, currentDir = process.cwd(), versio
59
53
  await createDynamicWorkspaceGHAction(logger, runtimeEnv, './platformatic.runtime.json', currentDir, false)
60
54
  }
61
55
 
56
+ if (initGitRepository) {
57
+ await createGitRepository(logger, currentDir)
58
+ }
62
59
  return {}
63
60
  }
64
61
  /**
@@ -1,18 +1,17 @@
1
- import { getVersion, getDependencyVersion } from '../utils.mjs'
1
+ import { getVersion, getDependencyVersion, safeMkdir } from '../utils.mjs'
2
2
  import { createPackageJson } from '../create-package-json.mjs'
3
3
  import { createGitignore } from '../create-gitignore.mjs'
4
4
  import { getPkgManager } from '../get-pkg-manager.mjs'
5
5
  import parseArgs from 'minimist'
6
6
  import { join } from 'path'
7
7
  import inquirer from 'inquirer'
8
- import { mkdir, stat } from 'fs/promises'
9
8
  import pino from 'pino'
10
9
  import pretty from 'pino-pretty'
11
10
  import { execa } from 'execa'
12
11
  import ora from 'ora'
13
12
  import createService from './create-service.mjs'
14
13
  import askDir from '../ask-dir.mjs'
15
- import { getRunPackageManagerInstall, getUseTypescript, getPort } from '../cli-options.mjs'
14
+ import { getRunPackageManagerInstall, getUseTypescript, getPort, getInitGitRepository } from '../cli-options.mjs'
16
15
  import { createReadme } from '../create-readme.mjs'
17
16
 
18
17
  const createPlatformaticService = async (_args, opts = {}) => {
@@ -37,13 +36,6 @@ const createPlatformaticService = async (_args, opts = {}) => {
37
36
  const projectDir = opts.dir || await askDir(logger, join('.', 'platformatic-service'))
38
37
  const isRuntimeContext = opts.isRuntimeContext || false
39
38
 
40
- // checks directory
41
- try {
42
- await stat(projectDir)
43
- logger.error(`Directory ${projectDir} already exists. Please choose another path.`)
44
- process.exit(1)
45
- } catch (err) {}
46
-
47
39
  const toAsk = []
48
40
  toAsk.push(getUseTypescript(args.typescript))
49
41
 
@@ -71,16 +63,20 @@ const createPlatformaticService = async (_args, opts = {}) => {
71
63
  choices: [{ name: 'yes', value: true }, { name: 'no', value: false }]
72
64
  })
73
65
  }
66
+ if (!opts.skipGitRepository) {
67
+ toAsk.push(getInitGitRepository())
68
+ }
74
69
  const {
75
70
  runPackageManagerInstall,
76
71
  useTypescript,
77
72
  port,
78
73
  staticWorkspaceGitHubAction,
79
- dynamicWorkspaceGitHubAction
74
+ dynamicWorkspaceGitHubAction,
75
+ initGitRepository
80
76
  } = await inquirer.prompt(toAsk)
81
77
 
82
78
  // Create the project directory
83
- await mkdir(projectDir, { recursive: true })
79
+ await safeMkdir(projectDir)
84
80
 
85
81
  const params = {
86
82
  isRuntimeContext,
@@ -89,7 +85,8 @@ const createPlatformaticService = async (_args, opts = {}) => {
89
85
  typescript: useTypescript,
90
86
  staticWorkspaceGitHubAction,
91
87
  dynamicWorkspaceGitHubAction,
92
- runtimeContext: opts.runtimeContext
88
+ runtimeContext: opts.runtimeContext,
89
+ initGitRepository
93
90
  }
94
91
 
95
92
  await createService(params, logger, projectDir, version)
@@ -117,7 +114,9 @@ const createPlatformaticService = async (_args, opts = {}) => {
117
114
 
118
115
  const spinner = ora('Generating types...').start()
119
116
  try {
120
- await execa(pkgManager, ['exec', 'platformatic', 'service', 'types'], { cwd: projectDir })
117
+ const options = ['exec', 'platformatic', 'service', 'types']
118
+ await execa(pkgManager, options, { cwd: projectDir })
119
+
121
120
  spinner.succeed('Types generated!')
122
121
  } catch (err) {
123
122
  logger.trace({ err })
@@ -1,10 +1,11 @@
1
1
  import { writeFile, readFile, appendFile } from 'fs/promises'
2
2
  import { join } from 'path'
3
3
  import * as desm from 'desm'
4
- import { addPrefixToEnv, findServiceConfigFile, isFileAccessible } from '../utils.mjs'
4
+ import { addPrefixToEnv } from '../utils.mjs'
5
5
  import { getTsConfig } from '../get-tsconfig.mjs'
6
6
  import { generatePlugins } from '../create-plugins.mjs'
7
7
  import { createDynamicWorkspaceGHAction, createStaticWorkspaceGHAction } from '../ghaction.mjs'
8
+ import { createGitRepository } from '../create-git-repository.mjs'
8
9
 
9
10
  const TS_OUT_DIR = 'dist'
10
11
 
@@ -72,7 +73,8 @@ async function createService (params, logger, currentDir = process.cwd(), versio
72
73
  typescript = false,
73
74
  staticWorkspaceGitHubAction,
74
75
  dynamicWorkspaceGitHubAction,
75
- runtimeContext
76
+ runtimeContext,
77
+ initGitRepository
76
78
  } = params
77
79
 
78
80
  const serviceEnv = {
@@ -88,41 +90,23 @@ async function createService (params, logger, currentDir = process.cwd(), versio
88
90
  const pkg = await readFile(desm.join(import.meta.url, '..', '..', 'package.json'))
89
91
  version = JSON.parse(pkg).version
90
92
  }
91
- const accessibleConfigFilename = await findServiceConfigFile(currentDir)
92
93
  const envPrefix = runtimeContext !== undefined ? `${runtimeContext.envPrefix}_` : ''
93
- if (accessibleConfigFilename === undefined) {
94
- const config = generateConfig(isRuntimeContext, version, typescript, envPrefix)
95
- await writeFile(join(currentDir, 'platformatic.service.json'), JSON.stringify(config, null, 2))
96
- logger.info('Configuration file platformatic.service.json successfully created.')
97
-
98
- const env = generateEnv(isRuntimeContext, hostname, port, typescript, envPrefix)
99
- const envFileExists = await isFileAccessible('.env', currentDir)
100
- await appendFile(join(currentDir, '.env'), env)
101
- await writeFile(join(currentDir, '.env.sample'), env)
102
- /* c8 ignore next 5 */
103
- if (envFileExists) {
104
- logger.info('Environment file .env found, appending new environment variables to existing .env file.')
105
- } else {
106
- logger.info('Environment file .env successfully created.')
107
- }
108
- } else {
109
- logger.info(`Configuration file ${accessibleConfigFilename} found, skipping creation of configuration file.`)
110
- }
94
+ const config = generateConfig(isRuntimeContext, version, typescript, envPrefix)
95
+ await writeFile(join(currentDir, 'platformatic.service.json'), JSON.stringify(config, null, 2))
96
+ logger.info('Configuration file platformatic.service.json successfully created.')
97
+
98
+ const env = generateEnv(isRuntimeContext, hostname, port, typescript, envPrefix)
99
+ await appendFile(join(currentDir, '.env'), env)
100
+ await writeFile(join(currentDir, '.env.sample'), env)
101
+ logger.info('Environment file .env found, appending new environment variables to existing .env file.')
111
102
 
112
103
  if (typescript === true) {
113
104
  const tsConfigFileName = join(currentDir, 'tsconfig.json')
114
- const isTsConfigExists = await isFileAccessible(tsConfigFileName)
115
- if (!isTsConfigExists) {
116
- const tsConfig = getTsConfig(TS_OUT_DIR)
117
- await writeFile(tsConfigFileName, JSON.stringify(tsConfig, null, 2))
118
- logger.info(
119
- `Typescript configuration file ${tsConfigFileName} successfully created.`
120
- )
121
- } else {
122
- logger.info(
123
- `Typescript configuration file ${tsConfigFileName} found, skipping creation of typescript configuration file.`
124
- )
125
- }
105
+ const tsConfig = getTsConfig(TS_OUT_DIR)
106
+ await writeFile(tsConfigFileName, JSON.stringify(tsConfig, null, 2))
107
+ logger.info(
108
+ `Typescript configuration file ${tsConfigFileName} successfully created.`
109
+ )
126
110
  }
127
111
 
128
112
  if (!isRuntimeContext) {
@@ -139,7 +123,9 @@ async function createService (params, logger, currentDir = process.cwd(), versio
139
123
  if (isRuntimeContext) {
140
124
  return addPrefixToEnv(serviceEnv, runtimeContext.envPrefix)
141
125
  }
142
-
126
+ if (initGitRepository) {
127
+ await createGitRepository(logger, currentDir)
128
+ }
143
129
  return serviceEnv
144
130
  }
145
131
 
package/src/utils.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import { execa } from 'execa'
2
- import { access, constants, readFile } from 'fs/promises'
2
+ import { access, constants, mkdir, readFile } from 'fs/promises'
3
3
  import { resolve, join, dirname } from 'path'
4
4
  import { createRequire } from 'module'
5
5
  import semver from 'semver'
@@ -102,3 +102,11 @@ export function addPrefixToEnv (env, prefix) {
102
102
  })
103
103
  return output
104
104
  }
105
+
106
+ export async function safeMkdir (dir) {
107
+ try {
108
+ await mkdir(dir, { recursive: true })
109
+ } catch (err) {
110
+ // do nothing
111
+ }
112
+ }