Skip to content

Commit

Permalink
build: 🚧 Dev Environment changes
Browse files Browse the repository at this point in the history
  • Loading branch information
Krutoy242 committed Jan 20, 2024
1 parent 2f2f48e commit 3b4e192
Show file tree
Hide file tree
Showing 6 changed files with 312 additions and 197 deletions.
30 changes: 24 additions & 6 deletions dev/TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,33 @@
- [ ] ✏️ Buff advanced generators
- [ ] 📖 remove Eldritch Knowledge Rewards since newbies eat them all at once
- [ ] ✏️ adv Rock Crystals Beneficate In QMD
- [ ] ✏️ steel And Up Turbine Upgrades Not Working
- [ ] 📖 note That Mithminite Armor Simplify Bores
- [ ] ⚡ Replace `utils.rh` with subcommands to improve performance. `IItemStack.ores` is slow.
- [ ] ✏️ QMDs `Sodium Chlorde` and `Sodium Nitrate` unify
- [ ] 🌍 Fix Biome Tweaker block replacementsafter AdvRock filler block change
- [ ] 🌍 Fix Biome Tweaker block replacements after AdvRock filler block change
- [ ] 🖼️ Optimize Bibliocraft textures
- [ ] ✏️ addVoidBeaconTab
- [ ] addSkyblockTpMechanic
- [ ] Fix Myrmexes have double JER trade tabs
- [ ] ✏️ add Void Beacon Tab
- [ ] 📖 add E2E book notes and quest about Skyblock Tp Mechanic
- [ ] fix Black Quartz And Certus Untransformable Portal Spread
- [ ] 🌍 Remove Poison Ivy from OTG generator
- [ ] 🧩 make Backpacks Unbreakable to prevent destroying for several reasons
- [ ] 📖 Getting Fire fix quest
- [ ] 📖 Touching portal not working on server
- [ ] 📖 15 health for portal should be shared for whole team
- [ ] 📖 Piston Rewards add amount of reward
- [ ] ✏️ Completely disable OreDict melting
- [ ] Install Pixel Reality - Luminance
- [ ] 📖 Add "Crafting" upgrade to Compressing robot
- [ ] 📖 Add note about Assembler+Battery+Bottle
- [ ] ✏️ Native Clusters should be made into Dirty Ores to prevent multiplication of recipes
- [ ] 🟢 Add https://legacy.curseforge.com/minecraft/mc-mods/advanced-smelter
- [ ] 💿 Add null check to fix Dynamism Table https://discord.com/channels/911676461050642432/1195650557004755056/1197080356604616704
- [ ] 📖 Fix "Completed chapter" message
- [ ] 🦆 Rewrite Goose logic https://github.com/friendlyhj/ZenUtils/issues/33
- [x] ✏️ TE Sawmill fix Spectre wood => Planks (remove Camuflaged Panelling from game)
- [ ] ✏️ Fix enderman still drop ghost Mysical Flesh
- [ ] 🌍 Terra Nova (112) regenerate JER
- [ ] 🟠 When update Precision Mining add `438451` to server-setup-config
- [ ] ✏️ Remove removed item from Overworld Explorer villager trades

```sh
/bcore_ticktime
Expand Down
142 changes: 142 additions & 0 deletions dev/build/build_utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
import type { Options } from 'fast-glob'
import type { InputFieldOptions } from 'terminal-kit/Terminal.js'

import { relative } from 'node:path'
import process from 'node:process'

import boxen from 'boxen'
import chalk from 'chalk'
import fast_glob from 'fast-glob'
import fse from 'fs-extra'
import logUpdate from 'log-update'
import terminal_kit from 'terminal-kit'

import {
end,
write,
} from '../lib/utils.js'

const { rmSync } = fse

const { terminal: term } = terminal_kit

/**
* Globs with default options `dot: true, onlyFiles: false`
*/
export function globs(source: string | string[], options?: Options) {
return fast_glob.sync(source, { dot: true, onlyFiles: false, ...options })
}

export function getIgnoredFiles(ignored: any) {
return globs(
ignored._rules.filter((r: { negative: any }) => !r.negative).map((r: { pattern: any }) => r.pattern),
{ ignore: ignored._rules.filter((r: { negative: any }) => r.negative).map((r: { pattern: any }) => r.pattern) }
)
}

/**
* @param {string | readonly string[]} fileArg list of globs of files to remove
*/
export function removeFiles(fileArg: readonly string[] | string) {
const files = [fileArg].flat(2)
/** @type {string[]} */
const removed: string[] = []
files.forEach((file) => {
try {
rmSync(file, { recursive: true, maxRetries: 1 })
removed.push(file)
}
catch (error) {
process.stdout.write(`\n${chalk.red(`Cannot remove: ${chalk.blue(file)}`)}\n`)
}
})
return `removed: ${removed.length}\n${
removed.map(s => chalk.gray(relative(process.cwd(), s))).join('\n')
}`
}

export const style = {
trace : chalk.hex('#7b4618'),
info : chalk.hex('#915c27'),
log : chalk.hex('#ad8042'),
label : chalk.hex('#bfab67'),
string: chalk.hex('#bfc882'),
number: chalk.hex('#a4b75c'),
status: chalk.hex('#647332'),
chose : chalk.hex('#3e4c22'),
end : chalk.hex('#2e401c'),
}

/**
* Write task in log and execute it
* @param s Name of the tast would be printed in Log
* @param fn Function of task
* @param cwd Optional working path where task is executed
*/
export function doTask(s: string, fn: () => void, cwd?: string) {
const oldCwd = process.cwd()
if (cwd) process.chdir(cwd)
write(style.label(s))
end(fn())
if (cwd) process.chdir(oldCwd)
}

/*
█████╗ ██╗ ██╗████████╗ ██████╗ ███╗ ███╗ █████╗ ████████╗██╗ ██████╗ ███╗ ██╗
██╔══██╗██║ ██║╚══██╔══╝██╔═══██╗████╗ ████║██╔══██╗╚══██╔══╝██║██╔═══██╗████╗ ██║
███████║██║ ██║ ██║ ██║ ██║██╔████╔██║███████║ ██║ ██║██║ ██║██╔██╗ ██║
██╔══██║██║ ██║ ██║ ██║ ██║██║╚██╔╝██║██╔══██║ ██║ ██║██║ ██║██║╚██╗██║
██║ ██║╚██████╔╝ ██║ ╚██████╔╝██║ ╚═╝ ██║██║ ██║ ██║ ██║╚██████╔╝██║ ╚████║
╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═══╝
*/

let STEP = 1

/**
* Prompt user to write something and press ENTER or ESC
* @param message message to show
* @param options message to show
* @returns inputted string or undefined
*/
export async function enterString(message: string, options?: InputFieldOptions) {
const msg = `[${STEP++}] ${message}`
term(style.trace(msg.replace(/(ENTER|ESC)/g, style.info('$1'))))
const result = await term.inputField({
cancelable: true,
...(options ?? {}),
}).promise
term('\n')
return result
}

/**
* Prompt user to press ENTER or ESC
* @param message message to show
* @param condition repeat until true
* @returns `true` if ENTER pressed, `false` otherwise
*/
export async function pressEnterOrEsc(message: string, condition?: () => Promise<boolean>) {
let oneTime = 0
while (condition ? !(await condition()) : !oneTime++)
if ((await enterString(message)) === undefined) return false

return true
}

export function getBoxForLabel(label: string) {
logUpdate.done()
return function updateBox(...args: any[]) {
return logUpdate(
boxen(
args.map((v, i) => Object.values(style)[i](String(v))).join(' '),
{
borderStyle: 'round',
borderColor: '#22577a',
width : 50,
padding : { left: 1, right: 1 },
title : style.info(label),
}
)
)
}
}
122 changes: 122 additions & 0 deletions dev/build/sftp.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
import { join, parse } from 'node:path'
import process from 'node:process'

import fse from 'fs-extra'
import git_describe from 'git-describe'
import replace_in_file from 'replace-in-file'
import Client from 'ssh2-sftp-client'

import {
end,
loadJson,
} from '../lib/utils.js'
import { getBoxForLabel, globs, pressEnterOrEsc, style } from './build_utils'

const { readFileSync, writeFileSync } = fse

const { gitDescribeSync } = git_describe
export async function manageSFTP(
serverRemoveDirs: string[] = [
'bansoukou',
'config',
'mods',
'patchouli_books',
'resources',
'schematics',
'scripts',
'structures',
],
serverSetupConfig: string = 'server/server-setup-config.yaml'
) {
const sftpConfigs = globs('secrets/sftp_servers/*/sftp.json').map((filename) => {
const dir = parse(filename).dir
return {
dir,
label : dir.split('/').pop(),
config: loadJson(filename) as { [key: string]: string },
}
})

const currentVersion = gitDescribeSync().tag

const serverConfigTmp = '~tmp-server-setup-config.yaml'
const confText = readFileSync(serverSetupConfig, 'utf8')
.replace(
/(additionalFiles:\s*)\n {4}\S.*$\n {4}\S.*$/m,
`$1
- url: https://mediafilez.forgecdn.net/files/4886/383/mc2discord-forge-1.12.2-3.3.1.jar
destination: mods/mc2discord-forge-1.12.2-3.3.1.jar`
)
// .replace(
// /(localFiles:\s*)\n/m,
// `$1
// - url: https://mediafilez.forgecdn.net/files/4886/383/mc2discord-forge-1.12.2-3.3.1.jar
// destination: mods/mc2discord-forge-1.12.2-3.3.1.jar`
// )
writeFileSync(serverConfigTmp, confText)

for (const conf of sftpConfigs) {
if (!(await pressEnterOrEsc(
`To upload SFTP ${style.string(conf.label)} press ENTER. Press ESC to skip.`
)))
continue

const sftp = new Client()
const updateBox = getBoxForLabel(conf.label)

updateBox('Establishing connection')
try {
await sftp.connect(conf.config)
}
catch (error) {
end('Cant connect to SFTP')
continue
}

updateBox('Removing folders')
const stillToRemove = serverRemoveDirs.slice(0)
await Promise.all(
serverRemoveDirs.map(async (dir) => {
try {
if (!(await sftp.stat(dir)).isDirectory) return
await sftp.rmdir(dir, true)
stillToRemove.splice(stillToRemove.indexOf(dir), 1)
updateBox('Still to remove:', stillToRemove.join(', '))
}
catch (error) {}
})
)

updateBox(`Copy ${serverConfigTmp}`)
await sftp.fastPut(serverConfigTmp, 'server-setup-config.yaml')

updateBox('Change and copy server overrides')
const title = `+ Server Started! +`
const spaces = (' ').repeat(Math.max(1, (title.length - currentVersion.length) / 2) | 0)
const replaceResult = replace_in_file.sync({
files : join(conf.dir, 'overrides/config/mc2discord.toml'),
from : /(start\s*=\s*")[^"]+"/,
to : `$1\`\`\`diff\\n${title}\\n${spaces}${currentVersion}\\n\`\`\`"`,
countMatches: true,
disableGlobs: true,
})

updateBox('Remove', 'serverstarter.lock')
sftp.delete('serverstarter.lock', true)

if (replaceResult.length === 0)
throw new Error('Nothing replaced! Code failure')

let fileCounter = 0
sftp.on('upload', () => updateBox('Copy overrides', ++fileCounter))
await sftp.uploadDir(join(conf.dir, 'overrides'), './')

await sftp.end()
}
}

// Launch file
if (import.meta.url === (await import('node:url')).pathToFileURL(process.argv[1]).href) {
await manageSFTP()
process.exit(0)
}
Loading

0 comments on commit 3b4e192

Please sign in to comment.