@neurodevs/meta-node 0.0.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.
- package/.nvmrc +1 -0
- package/.vscode/launch.json +58 -0
- package/.vscode/settings.json +67 -0
- package/.vscode/tasks.json +112 -0
- package/LICENSE +21 -0
- package/README.md +2 -0
- package/build/.spruce/settings.json +11 -0
- package/build/__tests__/modules/GitAutocloner.test.d.ts +28 -0
- package/build/__tests__/modules/GitAutocloner.test.js +158 -0
- package/build/__tests__/modules/GitAutocloner.test.js.map +1 -0
- package/build/__tests__/modules/NpmAutopackage.test.d.ts +24 -0
- package/build/__tests__/modules/NpmAutopackage.test.js +136 -0
- package/build/__tests__/modules/NpmAutopackage.test.js.map +1 -0
- package/build/index.d.ts +6 -0
- package/build/index.js +32 -0
- package/build/index.js.map +1 -0
- package/build/modules/GitAutocloner.d.ts +38 -0
- package/build/modules/GitAutocloner.js +84 -0
- package/build/modules/GitAutocloner.js.map +1 -0
- package/build/modules/NpmAutopackage.d.ts +44 -0
- package/build/modules/NpmAutopackage.js +83 -0
- package/build/modules/NpmAutopackage.js.map +1 -0
- package/build/scripts/runAutopackage.d.ts +1 -0
- package/build/scripts/runAutopackage.js +26 -0
- package/build/scripts/runAutopackage.js.map +1 -0
- package/build/testDoubles/Autocloner/FakeAutocloner.d.ts +8 -0
- package/build/testDoubles/Autocloner/FakeAutocloner.js +18 -0
- package/build/testDoubles/Autocloner/FakeAutocloner.js.map +1 -0
- package/eslint.config.mjs +3 -0
- package/package.json +66 -0
- package/src/.spruce/settings.json +11 -0
- package/src/__tests__/modules/GitAutocloner.test.ts +149 -0
- package/src/__tests__/modules/NpmAutopackage.test.ts +124 -0
- package/src/index.ts +12 -0
- package/src/modules/GitAutocloner.ts +115 -0
- package/src/modules/NpmAutopackage.ts +124 -0
- package/src/scripts/runAutopackage.ts +25 -0
- package/src/testDoubles/Autocloner/FakeAutocloner.ts +19 -0
- package/tsconfig.json +39 -0
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import AbstractSpruceTest, {
|
|
2
|
+
test,
|
|
3
|
+
assert,
|
|
4
|
+
generateId,
|
|
5
|
+
} from '@sprucelabs/test-utils'
|
|
6
|
+
import NpmAutopackage, {
|
|
7
|
+
Autopackage,
|
|
8
|
+
AutopackageOptions,
|
|
9
|
+
} from '../../modules/NpmAutopackage'
|
|
10
|
+
|
|
11
|
+
export default class NpmAutopackageTest extends AbstractSpruceTest {
|
|
12
|
+
private static instance: Autopackage
|
|
13
|
+
|
|
14
|
+
protected static async beforeEach() {
|
|
15
|
+
await super.beforeEach()
|
|
16
|
+
|
|
17
|
+
this.fakeExecToPreventActual()
|
|
18
|
+
this.fakeChdirToPreventActual()
|
|
19
|
+
|
|
20
|
+
this.instance = await this.NpmAutopackage()
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
@test()
|
|
24
|
+
protected static async createsNpmAutopackageInstance() {
|
|
25
|
+
assert.isTruthy(this.instance, 'Should create an instance!')
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
@test()
|
|
29
|
+
protected static async firstCallsChdirToInstallDir() {
|
|
30
|
+
assert.isEqual(
|
|
31
|
+
this.callsToChdir[0],
|
|
32
|
+
this.installDir,
|
|
33
|
+
'Should have changed dir!'
|
|
34
|
+
)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
@test()
|
|
38
|
+
protected static async thenCallsSpruceCreateModule() {
|
|
39
|
+
assert.isEqual(
|
|
40
|
+
this.callsToExecSync[0],
|
|
41
|
+
this.createModuleCmd,
|
|
42
|
+
'Should have called "spruce create.module"!'
|
|
43
|
+
)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
@test()
|
|
47
|
+
protected static async thenCallsChdirToNewlyCreatedDir() {
|
|
48
|
+
assert.isEqual(
|
|
49
|
+
this.callsToChdir[1],
|
|
50
|
+
`${this.installDir}/${this.packageName}`,
|
|
51
|
+
'Should have changed dir!'
|
|
52
|
+
)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
@test()
|
|
56
|
+
protected static async thenSetsUpNewGitRepo() {
|
|
57
|
+
assert.isEqualDeep(
|
|
58
|
+
this.callsToExecSync.slice(1, 5),
|
|
59
|
+
[
|
|
60
|
+
'git init',
|
|
61
|
+
'git add .',
|
|
62
|
+
'git commit -m "patch: create module"',
|
|
63
|
+
`git remote add origin "https://github.com/${this.gitNamespace}/${this.packageName}.git"`,
|
|
64
|
+
],
|
|
65
|
+
'Should have called "git init"!'
|
|
66
|
+
)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
@test()
|
|
70
|
+
protected static async thenCallsSpruceSetupVscode() {
|
|
71
|
+
assert.isEqual(
|
|
72
|
+
this.callsToExecSync[5],
|
|
73
|
+
'spruce setup.vscode --all true',
|
|
74
|
+
'Should have called "spruce setup.vscode"!'
|
|
75
|
+
)
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
@test()
|
|
79
|
+
protected static async thenGitCommitsVscodeChanges() {
|
|
80
|
+
assert.isEqualDeep(
|
|
81
|
+
this.callsToExecSync.slice(6, 8),
|
|
82
|
+
['git add .', 'git commit -m "patch: setup vscode"'],
|
|
83
|
+
'Should have committed vscode changes!'
|
|
84
|
+
)
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
private static fakeExecToPreventActual() {
|
|
88
|
+
// @ts-ignore
|
|
89
|
+
NpmAutopackage.execSync = (cmd: string) => {
|
|
90
|
+
this.callsToExecSync.push(cmd)
|
|
91
|
+
}
|
|
92
|
+
this.callsToExecSync = []
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
private static fakeChdirToPreventActual() {
|
|
96
|
+
NpmAutopackage.chdir = (dir: string) => {
|
|
97
|
+
this.callsToChdir.push(dir)
|
|
98
|
+
}
|
|
99
|
+
this.callsToChdir = []
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
private static callsToExecSync: string[] = []
|
|
103
|
+
private static callsToChdir: string[] = []
|
|
104
|
+
|
|
105
|
+
private static readonly packageName = generateId()
|
|
106
|
+
private static readonly packageDescription = generateId()
|
|
107
|
+
private static readonly gitNamespace = generateId()
|
|
108
|
+
private static readonly npmNamespace = generateId()
|
|
109
|
+
private static readonly installDir = generateId()
|
|
110
|
+
|
|
111
|
+
private static readonly createModuleCmd = `spruce create.module --name "${this.packageName}" --destination "${this.installDir}/${this.packageName}" --description "${this.packageDescription}"`
|
|
112
|
+
|
|
113
|
+
private static readonly defaultOptions = {
|
|
114
|
+
name: this.packageName,
|
|
115
|
+
description: this.packageDescription,
|
|
116
|
+
gitNamespace: this.gitNamespace,
|
|
117
|
+
npmNamespace: this.npmNamespace,
|
|
118
|
+
installDir: this.installDir,
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
private static NpmAutopackage(options?: Partial<AutopackageOptions>) {
|
|
122
|
+
return NpmAutopackage.Create({ ...this.defaultOptions, ...options })
|
|
123
|
+
}
|
|
124
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// Autopackage
|
|
2
|
+
|
|
3
|
+
export { default as NpmAutopackage } from './modules/NpmAutopackage'
|
|
4
|
+
export * from './modules/NpmAutopackage'
|
|
5
|
+
|
|
6
|
+
// Autocloner
|
|
7
|
+
|
|
8
|
+
export { default as GitAutocloner } from './modules/GitAutocloner'
|
|
9
|
+
export * from './modules/GitAutocloner'
|
|
10
|
+
|
|
11
|
+
export { default as FakeAutocloner } from './testDoubles/Autocloner/FakeAutocloner'
|
|
12
|
+
export * from './testDoubles/Autocloner/FakeAutocloner'
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { execSync } from 'child_process'
|
|
2
|
+
import { existsSync } from 'fs'
|
|
3
|
+
import { chdir } from 'process'
|
|
4
|
+
|
|
5
|
+
export default class GitAutocloner implements Autocloner {
|
|
6
|
+
public static Class?: AutoclonerConstructor
|
|
7
|
+
public static execSync = execSync
|
|
8
|
+
public static existsSync = existsSync
|
|
9
|
+
|
|
10
|
+
private urls!: string[]
|
|
11
|
+
private dirPath!: string
|
|
12
|
+
private currentUrl!: string
|
|
13
|
+
private currentError!: any
|
|
14
|
+
private log = console
|
|
15
|
+
|
|
16
|
+
protected constructor() {}
|
|
17
|
+
|
|
18
|
+
public static Create() {
|
|
19
|
+
return new (this.Class ?? this)()
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
public async run(options: AutoclonerOptions) {
|
|
23
|
+
const { urls, dirPath } = options
|
|
24
|
+
|
|
25
|
+
this.urls = urls
|
|
26
|
+
this.dirPath = dirPath
|
|
27
|
+
|
|
28
|
+
this.throwIfDirPathDoesNotExist()
|
|
29
|
+
this.changeDirectoryToDirPath()
|
|
30
|
+
this.cloneReposFromUrls()
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
private throwIfDirPathDoesNotExist() {
|
|
34
|
+
if (!this.dirPathExists) {
|
|
35
|
+
throw new Error(this.dirPathDoesNotExistMessage)
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
private get dirPathDoesNotExistMessage() {
|
|
40
|
+
return `dirPath does not exist: ${this.dirPath}!`
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
private changeDirectoryToDirPath() {
|
|
44
|
+
chdir(this.dirPath)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
private cloneReposFromUrls() {
|
|
48
|
+
this.urls.forEach((url) => {
|
|
49
|
+
this.currentUrl = url
|
|
50
|
+
this.cloneCurrentUrl()
|
|
51
|
+
})
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
private cloneCurrentUrl() {
|
|
55
|
+
if (!this.currentRepoExists) {
|
|
56
|
+
this.tryToCloneRepo()
|
|
57
|
+
} else {
|
|
58
|
+
this.log.info(this.repoExistsMessage)
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
private tryToCloneRepo() {
|
|
63
|
+
try {
|
|
64
|
+
this.execSync(`git clone ${this.currentUrl}`)
|
|
65
|
+
} catch (err: any) {
|
|
66
|
+
this.currentError = err
|
|
67
|
+
this.throwGitCloneFailed()
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
private throwGitCloneFailed() {
|
|
72
|
+
throw new Error(this.gitCloneFailedMessage)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
private get gitCloneFailedMessage() {
|
|
76
|
+
return `Git clone failed for repo: ${this.currentUrl}!\n\n${this.currentError}\n\n`
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
private get dirPathExists() {
|
|
80
|
+
return this.existsSync(this.dirPath)
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
private get currentRepoName() {
|
|
84
|
+
return this.currentUrl.match(this.regex)![1]
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
private get currentRepoExists() {
|
|
88
|
+
return this.existsSync(this.currentRepoName)
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
private get repoExistsMessage() {
|
|
92
|
+
return `Repo already exists, skipping: ${this.currentRepoName}!`
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
private get existsSync() {
|
|
96
|
+
return GitAutocloner.existsSync
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
private get execSync() {
|
|
100
|
+
return GitAutocloner.execSync
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
private readonly regex = /\/([a-zA-Z0-9_.-]+)\.git/
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export interface Autocloner {
|
|
107
|
+
run(options: AutoclonerOptions): Promise<void>
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export type AutoclonerConstructor = new () => Autocloner
|
|
111
|
+
|
|
112
|
+
export interface AutoclonerOptions {
|
|
113
|
+
urls: string[]
|
|
114
|
+
dirPath: string
|
|
115
|
+
}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { execSync } from 'child_process'
|
|
2
|
+
|
|
3
|
+
export default class NpmAutopackage implements Autopackage {
|
|
4
|
+
public static Class?: AutopackageConstructor
|
|
5
|
+
public static chdir = process.chdir
|
|
6
|
+
public static execSync = execSync
|
|
7
|
+
|
|
8
|
+
private packageName: string
|
|
9
|
+
private packageDescription: string
|
|
10
|
+
private gitNamespace: string
|
|
11
|
+
private installDir: string
|
|
12
|
+
|
|
13
|
+
protected constructor(options: AutopackageOptions) {
|
|
14
|
+
const { name, description, gitNamespace, installDir } = options
|
|
15
|
+
|
|
16
|
+
this.packageName = name
|
|
17
|
+
this.packageDescription = description
|
|
18
|
+
this.gitNamespace = gitNamespace
|
|
19
|
+
this.installDir = installDir
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
public static async Create(options: AutopackageOptions) {
|
|
23
|
+
const instance = new (this.Class ?? this)(options)
|
|
24
|
+
await instance.createPackage()
|
|
25
|
+
|
|
26
|
+
return instance
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
public async createPackage() {
|
|
30
|
+
this.execCreateModule()
|
|
31
|
+
this.execGitSetup()
|
|
32
|
+
this.execSetupVscode()
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
private execCreateModule() {
|
|
36
|
+
this.chdirToInstallDir()
|
|
37
|
+
this.exec(this.createModuleCmd)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
private execGitSetup() {
|
|
41
|
+
this.chdirToNewPackageDir()
|
|
42
|
+
|
|
43
|
+
this.gitInit()
|
|
44
|
+
this.gitAdd()
|
|
45
|
+
this.gitCommitCreateModule()
|
|
46
|
+
this.gitRemoteAddOrigin()
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
private gitInit() {
|
|
50
|
+
this.exec(this.initCmd)
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
private gitAdd() {
|
|
54
|
+
this.exec(this.addCmd)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
private gitCommitCreateModule() {
|
|
58
|
+
this.exec(this.commitCreateCmd)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
private gitRemoteAddOrigin() {
|
|
62
|
+
this.exec(this.addRemoteCmd)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
private execSetupVscode() {
|
|
66
|
+
this.exec(this.setupVscodeCmd)
|
|
67
|
+
|
|
68
|
+
this.gitAdd()
|
|
69
|
+
this.gitCommitSetupVscode()
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
private gitCommitSetupVscode() {
|
|
73
|
+
this.exec(this.commitVscodeCmd)
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
private chdirToInstallDir() {
|
|
77
|
+
this.chdir(this.installDir)
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
private chdirToNewPackageDir() {
|
|
81
|
+
this.chdir(this.packageDir)
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
private get packageDir() {
|
|
85
|
+
return `${this.installDir}/${this.packageName}`
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
private get chdir() {
|
|
89
|
+
return NpmAutopackage.chdir
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
private get exec() {
|
|
93
|
+
return NpmAutopackage.execSync
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
private get createModuleCmd() {
|
|
97
|
+
return `spruce create.module --name "${this.packageName}" --destination "${this.installDir}/${this.packageName}" --description "${this.packageDescription}"`
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
private readonly initCmd = 'git init'
|
|
101
|
+
private readonly addCmd = 'git add .'
|
|
102
|
+
private readonly commitCreateCmd = 'git commit -m "patch: create module"'
|
|
103
|
+
|
|
104
|
+
private get addRemoteCmd() {
|
|
105
|
+
return `git remote add origin "https://github.com/${this.gitNamespace}/${this.packageName}.git"`
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
private readonly setupVscodeCmd = 'spruce setup.vscode --all true'
|
|
109
|
+
private readonly commitVscodeCmd = 'git commit -m "patch: setup vscode"'
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export interface Autopackage {
|
|
113
|
+
createPackage(): Promise<void>
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export interface AutopackageOptions {
|
|
117
|
+
name: string
|
|
118
|
+
description: string
|
|
119
|
+
gitNamespace: string
|
|
120
|
+
npmNamespace: string
|
|
121
|
+
installDir: string
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export type AutopackageConstructor = new () => Autopackage
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { execSync } from 'child_process'
|
|
2
|
+
import NpmAutopackage from '../modules/NpmAutopackage'
|
|
3
|
+
|
|
4
|
+
async function run() {
|
|
5
|
+
console.log('Running...')
|
|
6
|
+
|
|
7
|
+
await NpmAutopackage.Create({
|
|
8
|
+
name: 'node-xyz',
|
|
9
|
+
description: 'XYZ, yo',
|
|
10
|
+
gitNamespace: 'neurodevs',
|
|
11
|
+
npmNamespace: 'neurodevs',
|
|
12
|
+
installDir: '/Users/ericthecurious/dev',
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
console.log('Opening in VSCode...')
|
|
16
|
+
execSync('code .')
|
|
17
|
+
console.log('Done!')
|
|
18
|
+
|
|
19
|
+
process.exit(0)
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
run().catch((err) => {
|
|
23
|
+
console.error(err)
|
|
24
|
+
process.exit(1)
|
|
25
|
+
})
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Autocloner, AutoclonerOptions } from '../../modules/GitAutocloner'
|
|
2
|
+
|
|
3
|
+
export default class FakeGitAutocloner implements Autocloner {
|
|
4
|
+
public static numCallsToConstructor = 0
|
|
5
|
+
public static callsToRun: AutoclonerOptions[] = []
|
|
6
|
+
|
|
7
|
+
public constructor() {
|
|
8
|
+
FakeGitAutocloner.numCallsToConstructor++
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
public async run(options: AutoclonerOptions) {
|
|
12
|
+
FakeGitAutocloner.callsToRun.push(options)
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
public static resetTestDouble() {
|
|
16
|
+
FakeGitAutocloner.numCallsToConstructor = 0
|
|
17
|
+
FakeGitAutocloner.callsToRun = []
|
|
18
|
+
}
|
|
19
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"skipLibCheck": true,
|
|
4
|
+
"module": "commonjs",
|
|
5
|
+
"esModuleInterop": true,
|
|
6
|
+
"target": "ES2020",
|
|
7
|
+
"lib": [
|
|
8
|
+
"DOM",
|
|
9
|
+
"ES2022"
|
|
10
|
+
],
|
|
11
|
+
"declaration": true,
|
|
12
|
+
"noImplicitAny": true,
|
|
13
|
+
"allowJs": true,
|
|
14
|
+
"forceConsistentCasingInFileNames": true,
|
|
15
|
+
"noImplicitReturns": true,
|
|
16
|
+
"strict": true,
|
|
17
|
+
"noUnusedLocals": true,
|
|
18
|
+
"resolveJsonModule": true,
|
|
19
|
+
"moduleResolution": "node",
|
|
20
|
+
"sourceMap": false,
|
|
21
|
+
"outDir": "build",
|
|
22
|
+
"baseUrl": "src",
|
|
23
|
+
"experimentalDecorators": true,
|
|
24
|
+
"paths": {
|
|
25
|
+
"#spruce/*": [
|
|
26
|
+
".spruce/*"
|
|
27
|
+
]
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
"include": [
|
|
31
|
+
"./src/*.ts",
|
|
32
|
+
"./src/**/*.ts",
|
|
33
|
+
"./src/.spruce/**/*"
|
|
34
|
+
],
|
|
35
|
+
"exclude": [
|
|
36
|
+
"build",
|
|
37
|
+
"esm"
|
|
38
|
+
]
|
|
39
|
+
}
|