Skip to content

Commit 08fbc67

Browse files
committed
add update git deps script, fix inventory crashes
1 parent 3bf34a8 commit 08fbc67

File tree

5 files changed

+178
-7
lines changed

5 files changed

+178
-7
lines changed

.cursor/rules/vars-usage.mdc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,5 @@ Ask AI
1414
- Some other global variables that can be used without window prefixes are listed in src/globals.d.ts
1515

1616
Rationale: This ensures a clean separation between the Mineflayer logic (server-side/game logic) and the renderer (client-side/view logic), making the renderer portable and testable, and maintains proper usage of global state.
17+
18+
For more general project contributing guides see CONTRIBUTING.md on like how to setup the project. Use pnpm tsc if needed to validate result with typechecking the whole project.

CONTRIBUTING.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,8 +177,13 @@ New React components, improve UI (including mobile support).
177177

178178
## Updating Dependencies
179179

180-
1. Ensure mineflayer fork is up to date with the latest version of mineflayer original repo
180+
1. Use `pnpm update-git-deps` to check and update git dependencies (like mineflayer fork, prismarine packages etc). The script will:
181+
- Show which git dependencies have updates available
182+
- Ask if you want to update them
183+
- Skip dependencies listed in `pnpm.updateConfig.ignoreDependencies`
184+
181185
2. Update PrismarineJS dependencies to the latest version: `minecraft-data` (be sure to replace the version twice in the package.json), `mineflayer`, `minecraft-protocol`, `prismarine-block`, `prismarine-chunk`, `prismarine-item`, ...
186+
182187
3. If `minecraft-protocol` patch fails, do this:
183188
1. Remove the patch from `patchedDependencies` in `package.json`
184189
2. Run `pnpm patch minecraft-protocol`, open patch directory

package.json

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@
3131
"run-playground": "run-p watch-mesher watch-other-workers watch-playground",
3232
"run-all": "run-p start run-playground",
3333
"build-playground": "rsbuild build --config renderer/rsbuild.config.ts",
34-
"watch-playground": "rsbuild dev --config renderer/rsbuild.config.ts"
34+
"watch-playground": "rsbuild dev --config renderer/rsbuild.config.ts",
35+
"update-git-deps": "tsx scripts/updateGitDeps.ts"
3536
},
3637
"keywords": [
3738
"prismarine",
@@ -210,7 +211,10 @@
210211
"prismarine-item": "latest"
211212
},
212213
"updateConfig": {
213-
"ignoreDependencies": []
214+
"ignoreDependencies": [
215+
"browserfs",
216+
"google-drive-browserfs"
217+
]
214218
},
215219
"patchedDependencies": {
216220

pnpm-lock.yaml

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

scripts/updateGitDeps.ts

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
import fs from 'fs'
2+
import path from 'path'
3+
import yaml from 'yaml'
4+
import { execSync } from 'child_process'
5+
import { createInterface } from 'readline'
6+
7+
interface LockfilePackage {
8+
specifier: string
9+
version: string
10+
}
11+
12+
interface Lockfile {
13+
importers: {
14+
'.': {
15+
dependencies?: Record<string, LockfilePackage>
16+
devDependencies?: Record<string, LockfilePackage>
17+
}
18+
}
19+
}
20+
21+
interface PackageJson {
22+
pnpm?: {
23+
updateConfig?: {
24+
ignoreDependencies?: string[]
25+
}
26+
}
27+
}
28+
29+
async function prompt(question: string): Promise<string> {
30+
const rl = createInterface({
31+
input: process.stdin,
32+
output: process.stdout
33+
})
34+
35+
return new Promise(resolve => {
36+
rl.question(question, answer => {
37+
rl.close()
38+
resolve(answer.toLowerCase().trim())
39+
})
40+
})
41+
}
42+
43+
async function getLatestCommit(owner: string, repo: string): Promise<string> {
44+
const response = await fetch(`https://api.github.com/repos/${owner}/${repo}/commits/HEAD`)
45+
if (!response.ok) {
46+
throw new Error(`Failed to fetch latest commit: ${response.statusText}`)
47+
}
48+
const data = await response.json()
49+
return data.sha
50+
}
51+
52+
function extractGitInfo(specifier: string): { owner: string; repo: string; branch: string } | null {
53+
const match = specifier.match(/github:([^/]+)\/([^#]+)(?:#(.+))?/)
54+
if (!match) return null
55+
return {
56+
owner: match[1],
57+
repo: match[2],
58+
branch: match[3] || 'master'
59+
}
60+
}
61+
62+
function extractCommitHash(version: string): string | null {
63+
const match = version.match(/https:\/\/codeload\.github\.com\/[^/]+\/[^/]+\/tar\.gz\/([a-f0-9]+)/)
64+
return match ? match[1] : null
65+
}
66+
67+
function getIgnoredDependencies(): string[] {
68+
try {
69+
const packageJsonPath = path.join(process.cwd(), 'package.json')
70+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8')) as PackageJson
71+
return packageJson.pnpm?.updateConfig?.ignoreDependencies || []
72+
} catch (error) {
73+
console.warn('Failed to read package.json for ignored dependencies:', error)
74+
return []
75+
}
76+
}
77+
78+
async function main() {
79+
const lockfilePath = path.join(process.cwd(), 'pnpm-lock.yaml')
80+
const lockfileContent = fs.readFileSync(lockfilePath, 'utf8')
81+
const lockfile = yaml.parse(lockfileContent) as Lockfile
82+
83+
const ignoredDependencies = new Set(getIgnoredDependencies())
84+
console.log('Ignoring dependencies:', Array.from(ignoredDependencies).join(', ') || 'none')
85+
86+
const dependencies = {
87+
...lockfile.importers['.'].dependencies,
88+
...lockfile.importers['.'].devDependencies
89+
}
90+
91+
const updates: Array<{
92+
name: string
93+
currentHash: string
94+
latestHash: string
95+
gitInfo: ReturnType<typeof extractGitInfo>
96+
}> = []
97+
98+
console.log('\nChecking git dependencies...')
99+
for (const [name, pkg] of Object.entries(dependencies)) {
100+
if (ignoredDependencies.has(name)) {
101+
console.log(`Skipping ignored dependency: ${name}`)
102+
continue
103+
}
104+
105+
if (!pkg.specifier.startsWith('github:')) continue
106+
107+
const gitInfo = extractGitInfo(pkg.specifier)
108+
if (!gitInfo) continue
109+
110+
const currentHash = extractCommitHash(pkg.version)
111+
if (!currentHash) continue
112+
113+
try {
114+
process.stdout.write(`Checking ${name}... `)
115+
const latestHash = await getLatestCommit(gitInfo.owner, gitInfo.repo)
116+
if (currentHash !== latestHash) {
117+
console.log('update available')
118+
updates.push({ name, currentHash, latestHash, gitInfo })
119+
} else {
120+
console.log('up to date')
121+
}
122+
} catch (error) {
123+
console.log('failed')
124+
console.error(`Error checking ${name}:`, error)
125+
}
126+
}
127+
128+
if (updates.length === 0) {
129+
console.log('\nAll git dependencies are up to date!')
130+
return
131+
}
132+
133+
console.log('\nThe following git dependencies can be updated:')
134+
for (const update of updates) {
135+
console.log(`\n${update.name}:`)
136+
console.log(` Current: ${update.currentHash}`)
137+
console.log(` Latest: ${update.latestHash}`)
138+
console.log(` Repo: ${update.gitInfo!.owner}/${update.gitInfo!.repo}`)
139+
}
140+
141+
const answer = await prompt('\nWould you like to update these dependencies? (y/N): ')
142+
if (answer === 'y' || answer === 'yes') {
143+
let newLockfileContent = lockfileContent
144+
for (const update of updates) {
145+
newLockfileContent = newLockfileContent.replace(
146+
new RegExp(update.currentHash, 'g'),
147+
update.latestHash
148+
)
149+
}
150+
fs.writeFileSync(lockfilePath, newLockfileContent)
151+
console.log('\nUpdated pnpm-lock.yaml with new commit hashes')
152+
console.log('Running pnpm install to apply changes...')
153+
execSync('pnpm install', { stdio: 'inherit' })
154+
console.log('Done!')
155+
} else {
156+
console.log('\nNo changes were made.')
157+
}
158+
}
159+
160+
main().catch(console.error)

0 commit comments

Comments
 (0)