hachem.wtf
aboutsummaryrefslogtreecommitdiff
path: root/cli/commands/merge.js
blob: 138dd54773e5d7fa543e4592adc9cbaaa326f5b1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
const fs = require("fs-extra")
const path = require("path")
const { spawn } = require("child_process")
const archiver = require("archiver")

const { LoadConfig } = require("../../lib/config")
const { serverDir } = require("./generate")

const config = LoadConfig()

const 
{
    server_location,
    backup_location,
    merge_pre_command,
    merge_post_command
} = config

const RunCommand = (command) =>
{
    return new Promise((resolve) =>
    {
        console.log(`  Running: ${command}`)
        
        const proc = spawn(command, [], { shell: true, stdio: "inherit" })

        proc.on("close", (code) =>
        {
            if (code === 0)
                console.log("  Command completed.")
            else
                console.log(`  Command exited with code ${code}`)
            resolve(code)
        })

        proc.on("error", (err) =>
        {
            console.error("  Command failed:", err.message)
            resolve(1)
        })
    })
}

const CreateBackup = (sourceDir, backupDir) =>
{
    return new Promise(async (resolve, reject) =>
    {
        const now = new Date()
        const timestamp = now.toISOString()
            .replace(/[:.]/g, "-")
            .replace("T", "_")
            .slice(0, 19)
        
        const zipName = `backup_${timestamp}.zip`
        const zipPath = path.join(backupDir, zipName)

        await fs.ensureDir(backupDir)

        const output = fs.createWriteStream(zipPath)
        const archive = archiver("zip", { zlib: { level: 9 } })

        output.on("close", () =>
        {
            console.log(`  Created backup: ${zipName} (${archive.pointer()} bytes)`)
            resolve(zipPath)
        })

        archive.on("error", err => reject(err))

        archive.pipe(output)
        archive.directory(sourceDir, false)
        archive.finalize()
    })
}

const Merge = async () =>
{
    if (!server_location || !backup_location)
    {
        console.log("  Error: server_location and backup_location must be set in config.")
        return
    }

    if (!await fs.pathExists(serverDir))
    {
        console.log("  Error: No generated files found. Run 'generate' first.")
        return
    }

    // Run pre-command
    if (merge_pre_command)
    {
        console.log("\n  Running pre-merge command...")
        await RunCommand(merge_pre_command)
        console.log("")
    }

    // Check if server location exists and back it up
    if (await fs.pathExists(server_location))
    {
        console.log(`  Backing up ${server_location}...`)
        try
        {
            await CreateBackup(server_location, backup_location)
        }
        catch (err)
        {
            console.error("  Failed to create backup:", err.message)
            return
        }
    }
    else
    {
        console.log("  Server location doesn't exist, creating it...")
        await fs.ensureDir(server_location)
    }

    // Move generated files to server location
    console.log("  Moving generated files to server location...")
    try
    {
        const items = await fs.readdir(serverDir)
        for (const item of items)
        {
            const src = path.join(serverDir, item)
            const dest = path.join(server_location, item)

            // Remove existing item at destination
            if (await fs.pathExists(dest))
                await fs.remove(dest)

            await fs.move(src, dest)
            console.log(`    Moved: ${item}`)
        }

        // Remove the now-empty server directory
        await fs.remove(serverDir)

        console.log("  Merge complete!")
    }
    catch (err)
    {
        console.error("  Failed to move files:", err.message)
        return
    }

    // Run post-command
    if (merge_post_command)
    {
        console.log("\n  Running post-merge command...")
        await RunCommand(merge_post_command)
    }
}

module.exports = { Merge }