@ast-grep/create-lang 0.0.0-prerelease-1 → 0.0.0-prerelease-3

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/README.md ADDED
@@ -0,0 +1,28 @@
1
+ # @ast-grep/create-lang
2
+
3
+ ## Usage
4
+
5
+ ```bash
6
+ # create a new language package in current directory
7
+ pnpm create @ast-grep/lang
8
+ # create package in a specific directory
9
+ pnpm create @ast-grep/lang some-dir
10
+ ```
11
+
12
+ You will be prompted to enter the language name, the language file extension, package name and tree-sitter grammar package.
13
+
14
+ Note the tree-sitter grammar package is different from the package name. package name is the repo you create, tree-sitter package should be a package already published on npm.
15
+
16
+
17
+ ## Commands
18
+ After the package is created, you can use these commands:
19
+
20
+ ```bash
21
+ pnpm source # copy tree-sitter grammar files to the src folder
22
+ pnpm build # build the tree-sitter grammar files to dynamic lib
23
+ pnpm test # test the tree-sitter grammar files
24
+ ```
25
+
26
+ ### Test file
27
+
28
+ You can edit `nursery.js` to add test case for your language.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ast-grep/create-lang",
3
- "version": "0.0.0-prerelease-1",
3
+ "version": "0.0.0-prerelease-3",
4
4
  "private": false,
5
5
  "description": "",
6
6
  "main": "index.js",
@@ -12,6 +12,12 @@
12
12
  "bin": {
13
13
  "create-lang": "index.js"
14
14
  },
15
+ "files": [
16
+ "index.js",
17
+ "template/.gitignore",
18
+ "template/.npmignore",
19
+ "template"
20
+ ],
15
21
  "dependencies": {
16
22
  "prompts": "2.4.2"
17
23
  },
@@ -20,7 +26,7 @@
20
26
  "registry": "https://registry.npmjs.org/"
21
27
  },
22
28
  "devDependencies": {
23
- "@types/node": "22.10.5",
29
+ "@types/node": "22.10.7",
24
30
  "@types/prompts": "^2.4.9",
25
31
  "typescript": "^5.7.3"
26
32
  },
@@ -0,0 +1,30 @@
1
+ # Logs
2
+ logs
3
+ *.log
4
+ npm-debug.log*
5
+ yarn-debug.log*
6
+ yarn-error.log*
7
+ pnpm-debug.log*
8
+ lerna-debug.log*
9
+
10
+ node_modules
11
+ dist
12
+ dist-ssr
13
+ *.local
14
+
15
+ # Editor directories and files
16
+ .vscode/*
17
+ !.vscode/extensions.json
18
+ .idea
19
+ .DS_Store
20
+ *.suo
21
+ *.ntvs*
22
+ *.njsproj
23
+ *.sln
24
+ *.sw?
25
+
26
+ # ignore generated parser files
27
+ parser.so
28
+ type.d.ts
29
+ # do not include copied directories
30
+ src
File without changes
@@ -22,7 +22,8 @@
22
22
  "author": "",
23
23
  "license": "ISC",
24
24
  "dependencies": {
25
- "@ast-grep/setup-lang": "0.0.2"
25
+ "@ast-grep/setup-lang": "0.0.2",
26
+ "tree-sitter-cli": "0.24.6"
26
27
  },
27
28
  "peerDependencies": {
28
29
  "tree-sitter-cli": "0.24.6"
package/index.d.ts DELETED
@@ -1 +0,0 @@
1
- export {};
package/index.ts DELETED
@@ -1,131 +0,0 @@
1
- import prompts from 'prompts'
2
- import path from 'node:path'
3
- import fs from 'node:fs/promises'
4
- import { execSync } from 'node:child_process'
5
-
6
- function required(s: string): string | true {
7
- if (s.length === 0) {
8
- return 'This value is required'
9
- }
10
- return true
11
- }
12
-
13
- // https://github.com/vitejs/vite/blob/76082e3d3033b09b02b6db64de6e36942593c753/packages/create-vite/src/index.ts#L557
14
- function isValidPackageName(projectName: string) {
15
- return /^(?:@[a-z\d\-*~][a-z\d\-*._~]*\/)?[a-z\d\-~][a-z\d\-._~]*$/.test(
16
- projectName,
17
- ) || 'Invalid package name'
18
- }
19
-
20
-
21
- function askConfiguration() {
22
- return prompts([
23
- {
24
- type: 'text',
25
- name: 'name',
26
- message: 'Language name',
27
- validate: required,
28
- },
29
- {
30
- type: 'text',
31
- name: 'packageName',
32
- message: 'Package name',
33
- validate: isValidPackageName,
34
- initial: (_, answers) => `my-dynamic-lang-${answers.name}`,
35
- },
36
- {
37
- type: 'text',
38
- name: 'treeSitterPackage',
39
- message: 'Tree-sitter package to use',
40
- validate: isValidPackageName,
41
- initial: (_, answers) => `tree-sitter-${answers.name}`,
42
- },
43
- {
44
- type: 'list',
45
- name: 'extensions',
46
- message: 'File extensions used by the language, comma separated',
47
- separator: ',',
48
- validate: required,
49
- },
50
- {
51
- type: 'text',
52
- name: 'expandoChar',
53
- message: 'Expando char used in pattern',
54
- initial: '$',
55
- validate: (value) => {
56
- return value.length === 1 ? true : 'Expando char must be a single character'
57
- }
58
- },
59
- {
60
- type: 'confirm',
61
- name: 'includeDotFiles',
62
- message: 'Include gitignore and npm publish files?',
63
- initial: true,
64
- }
65
- ], {
66
- onCancel: () => {
67
- process.exit(1)
68
- }
69
- })
70
- }
71
-
72
- type Answers = Awaited<ReturnType<typeof askConfiguration>>
73
-
74
- function copyTemplate(targetDir: string, includeDotFiles: boolean) {
75
- const templateDir = path.join(__dirname, 'template')
76
- return fs.cp(templateDir, targetDir, {
77
- recursive: true, // Copy all files and folders
78
- // includes hidden files if `includeDotFiles` is true
79
- filter: (src) => {
80
- const basename = path.basename(src)
81
- return includeDotFiles || !basename.startsWith('.')
82
- }
83
- })
84
- }
85
-
86
- async function renameFiles(dir: string, answer: Answers) {
87
- const name: Record<string, string> = {
88
- $$PACKAGE_NAME$$: answer.packageName,
89
- $$NAME$$: answer.name,
90
- $$TREE_SITTER_PACKAGE$$: answer.treeSitterPackage,
91
- $$EXTENSIONS$$: JSON.stringify(answer.extensions),
92
- $$EXPANDO_CHAR$$: answer.expandoChar,
93
- }
94
- for (const file of await fs.readdir(dir)) {
95
- const filePath = path.join(dir, file)
96
- const stats = await fs.stat(filePath)
97
- if (stats.isDirectory()) {
98
- renameFiles(filePath, answer)
99
- } else {
100
- const content = await fs.readFile(filePath, 'utf-8')
101
- const newContent = content.replace(/(\$\$[A-Z_]+\$\$)/g, (match) => {
102
- return name[match] || match
103
- })
104
- await fs.writeFile(filePath, newContent)
105
- }
106
- }
107
- }
108
- function installTreeSitterPackage(cwd: string, answer: Answers) {
109
- console.log('Installing tree-sitter package...')
110
- execSync(`pnpm install ${answer.treeSitterPackage} --save-dev --save-exact`, {
111
- cwd,
112
- })
113
- console.log('Copying source code...')
114
- execSync('pnpm run source', { cwd })
115
- console.log('Compiling')
116
- execSync('pnpm run build', { cwd })
117
- }
118
-
119
- async function main() {
120
- let cwd = process.cwd()
121
- if (process.argv.length > 2) {
122
- const targetDir = process.argv[2]
123
- cwd = path.join(cwd, targetDir)
124
- }
125
- const config = await askConfiguration()
126
- await copyTemplate(cwd, config.includeDotFiles)
127
- await renameFiles(cwd, config)
128
- installTreeSitterPackage(cwd, config)
129
- }
130
-
131
- main()
package/tsconfig.json DELETED
@@ -1,3 +0,0 @@
1
- {
2
- "extends": "../../tsconfig.json"
3
- }