Initial push
All checks were successful
Build / Build (push) Successful in 39s

This commit is contained in:
marked 2025-04-05 18:27:50 +02:00
commit e517b193e5
20 changed files with 1237 additions and 0 deletions

46
lune/manager/build.luau Normal file
View file

@ -0,0 +1,46 @@
--!strict
local common = require("./common")
local progress_bar = require("@pkg/progress")
local result = require("@pkg/result")
export type ReplicatorData = {
remote_output: string,
replicator: string,
}
local function build(configuration: string, replicator_data: ReplicatorData?)
local progress = progress_bar.new():with_stage("init", "Initializing"):with_stage("build", "Building project")
if replicator_data then
progress:with_stage("replicate", "Replicating to remote server")
end
progress:start() -- init
progress:next_stage() -- build
local build_result = common.spawn(`dotnet build -c {configuration}`)
if not build_result.ok then
progress:stop()
return result(false, `Failed to build:\n{build_result.err}`)
end
if replicator_data then
progress:next_stage() -- replicate
progress:pause()
local replicator: common.Replicator = (require)(`./replicators/{replicator_data.replicator}`)
local replication_result = replicator(`src/bin/{configuration}/net8.0`, replicator_data.remote_output)
if not replication_result.ok then
progress:stop()
return result(false, `Failed to replicate build:\n{replication_result.err}`)
end
progress:unpause()
end
progress:stop() -- finish
print(build_result.val.stdout)
return result(true, nil)
end
return build

46
lune/manager/common.luau Normal file
View file

@ -0,0 +1,46 @@
--!strict
local process = require("@lune/process")
local stdio = require("@lune/stdio")
local result = require("@pkg/result")
local function c_print(msg: string)
stdio.write(`{stdio.color("blue")}[info]{stdio.color("reset")} {msg}\n`)
end
local function c_warn(msg: string)
stdio.write(`{stdio.color("yellow")}[warn]{stdio.color("reset")} {msg}\n`)
end
local function c_error(msg: string)
stdio.ewrite(`{stdio.color("red")}[error]{stdio.color("reset")} {msg}\n`)
end
local function c_spawn(command: string): result.Identity<process.SpawnResult>
local args = string.split(command, " ")
local program = table.remove(args, 1)
if not program then
return result(false, "Couldn't find program in command.")
end
local spawn_result = process.spawn(program, args)
if not spawn_result.ok then
return result(false, spawn_result.stderr)
end
return result(true, spawn_result)
end
local common = {
default_name = "CSSharpTemplate",
print = c_print,
warn = c_warn,
error = c_error,
spawn = c_spawn,
}
export type Replicator = (dist_folder: string, remote_output: string) -> result.Identity<nil>
return common

67
lune/manager/init.luau Normal file
View file

@ -0,0 +1,67 @@
--!strict
local process = require("@lune/process")
local common = require("./common")
local frkcli = require("@pkg/frkcli")
local cli = frkcli.new_subcommands("build_cli", "CLI for automatic basic C# tasks")
local command_build = cli:add_subcommand(
"build",
[[
Build the project.
Additionally, you can use a replicator to replicate your built plugin to:
1. A docker container:
`lune run manager -- build --replicator docker --remote-output container-id:/path/to/plugin`
2. A remote machine:
`lune run manager -- build --replicator ssh --remote-output username@hostname:/path/to/plugin`
3. A docker container on a remote machine:
`lune run manager -- build --replicator docker-ssh --remote-output username@hostname->container-id:/path/to/plugin`
You can also use a custom replicator, as long as it's located inside `lune/manager/replicators`.
]]
)
command_build:add_option(
"configuration",
{ help = "The configuration to use for building the project", aliases = { "c" }, default = "Debug" }
)
command_build:add_option(
"remote-output",
{ help = "Path on a remote machine to copy the built project to", aliases = { "o" }, default = "" }
)
command_build:add_option(
"replicator",
{ help = "Replicator to use for copying builds to a remote machine", aliases = { "r" }, default = "ssh" }
)
local command_setup = cli:add_subcommand("setup", "Setup the project")
command_setup:add_positional("name", { help = "Name of the project", default = nil })
command_setup:add_flag("force", { help = "Force the setup?", aliases = { "f" } })
local parsed, err = cli:parse(process.args)
if err ~= nil then
error(err)
end
assert(parsed ~= nil)
local values = parsed.result.values
local flags = parsed.result.flags
if parsed.command == "build" then
local replicator_data = nil
if values.remote_output ~= "" then
replicator_data = {
remote_output = values.remote_output,
replicator = values.replicator,
}
end
require("./build")(values.configuration, replicator_data)
elseif parsed.command == "setup" then
local setup = require("./setup")
local result = setup(values.name, flags.force)
if not result.ok then
common.error(result.err)
end
end

View file

@ -0,0 +1,16 @@
--!strict
local process = require("@lune/process")
local common = require("../common")
local result = require("@pkg/result")
local function docker_replicator(dist_folder: string, remote_output: string): result.Identity<nil>
local copy_result = process.spawn("docker", { "cp", "-r", dist_folder, remote_output })
if not copy_result.ok then
return result(false, `Failed to copy files:\n{copy_result.stderr}`)
end
return result(true, nil)
end
return docker_replicator :: common.Replicator

View file

@ -0,0 +1,41 @@
--!strict
local process = require("@lune/process")
local common = require("../common")
local result = require("@pkg/result")
local function ssh_docker_replicator(dist_folder: string, remote_output: string): result.Identity<nil>
local split = string.split(remote_output, "->")
local remote_machine = split[1]
if not remote_machine then
return result(false, "Couldn't get the remote machine to ssh into.")
end
local docker_path = split[2]
if not docker_path then
return result(false, "Couldn't get the docker container path for the remote machine.")
end
local ssh_copy_result = process.spawn(
"scp",
{ "-r", "-O", dist_folder, `{remote_machine}:/tmp/cssharp-replicate` },
{ stdio = "forward" }
)
if not ssh_copy_result.ok then
return result(false, `Failed to copy files to the remote machine:\n{ssh_copy_result.stderr}`)
end
local docker_copy_result = process.spawn(
"ssh",
{ "-t", remote_machine, `"docker cp -r /tmp/cssharp-replicate {docker_path}"` },
{ stdio = "forward" }
)
if not docker_copy_result.ok then
return result(false, `Failed to copy files via docker on the remote machine:\n{docker_copy_result.stderr}`)
end
return result(true, nil)
end
return ssh_docker_replicator :: common.Replicator

View file

@ -0,0 +1,16 @@
--!strict
local process = require("@lune/process")
local common = require("../common")
local result = require("@pkg/result")
local function ssh_replicator(dist_folder: string, remote_output: string): result.Identity<nil>
local copy_result = process.spawn("scp", { "-r", "-O", dist_folder, remote_output }, { stdio = "forward" })
if not copy_result.ok then
return result(false, `Failed to copy files:\n{copy_result.stderr}`)
end
return result(true, nil)
end
return ssh_replicator :: common.Replicator

69
lune/manager/setup.luau Normal file
View file

@ -0,0 +1,69 @@
--!strict
local fs = require("@lune/fs")
local common = require("./common")
local progress_bar = require("@pkg/progress")
local result = require("@pkg/result")
local function setup(name: string, force: boolean): result.Identity<nil>
local progress = progress_bar
.new()
:with_stage("init", "Initializing")
:with_stage("prepare", "Cleaning up defaults")
:with_stage("modify", "Replacing default names")
:with_stage("generate", "Generating .sln")
progress:start() -- init
if not fs.metadata(`{common.default_name}.sln`).exists and not force then
progress:stop()
return result(false, "Aborting -- the template is already set up.")
end
progress:next_stage() -- prepare
fs.removeFile(`{common.default_name}.sln`)
fs.removeFile(`PROJECT-SETUP.md`)
progress:next_stage() -- modify
fs.move(`src/{common.default_name}.cs`, `src/{name}.cs`)
fs.move(`src/{common.default_name}.csproj`, `src/{name}.csproj`)
do
local main_src = fs.readFile(`src/{name}.cs`)
local edited_src = string.gsub(main_src, common.default_name, name)
fs.writeFile(`src/{name}.cs`, edited_src)
end
progress:next_stage() -- generate
do
local res = common.spawn(`dotnet new sln --name {name}`)
if not res.ok then
return result(false, `Failed to create new sln:\n{res.err}`)
end
end
do
local res = common.spawn("dotnet sln add src")
if not res.ok then
return result(false, `Failed to add src to sln:\n{res.err}`)
end
end
do
local sln_src = fs.readFile(`{name}.sln`)
local by_line = string.split(sln_src, "\n")
for _ = 1, 3 do
table.remove(by_line, 3)
end
local concated = table.concat(by_line, "\n")
fs.writeFile(`{name}.sln`, concated)
end
progress:stop() -- finish
return result(true, nil)
end
return setup