-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.lua
162 lines (145 loc) · 5.77 KB
/
main.lua
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
157
158
159
160
161
162
local system_os, system_arch = jit.os, jit.arch;
local format = string.format;
local os_execute = os.execute;
local uv = require('uv');
local path = require('path');
local extension = require('discordia-extensions');
local bin_package = require('./package');
local cwd = uv.cwd();
local stdin = uv.new_tty(0, true); ---@diagnostic disable-line
local stdout = uv.new_tty(1, false); ---@diagnostic disable-line
local stderr = uv.new_tty(2, false); ---@diagnostic disable-line
local MAX_PERMS = tonumber(777, 8); ---@diagnostic disable-line
local BUILD_NAME = 'build';
local LIBRARY_EXT = '.dll';
local VERSION_FORMAT = 'Laura version: %s';
local REPO_FORMAT = 'GitHub Open Source Repository <%s>';
local SPLIT_FORMAT = '\n======= %s =======';
local COPY_FORMAT = 'copy /v /y "%s" "%s"';
local COPY_FUSED_FORMAT = 'copy /b /y "%s"+"%s" "%s"';
local LOVE2D = path.join('C:', 'Program Files', 'LOVE');
local LOVE2D_EXE = path.join(LOVE2D, 'love.exe');
local ZIP_COMMANDLINE = path.join('C:', 'Program Files', '7-Zip', '7z.exe');
local LOVE2D_FILES = {'license.txt', 'SDL2.dll', 'OpenAL32.dll', 'love.dll', 'lua51.dll', 'mpg123.dll', 'msvcp120.dll', 'msvcr120.dll'};
local fsExists = function(check_path, target_type, msg)
local data = uv.fs_stat(check_path);
return assert(data and data.type == target_type, msg);
end;
local qexecute = function(command)
local res, _, code = os_execute(command);
assert(res and code == 0, 'execute command encountered an error');
return res, _, code;
end;
local scanDirectory; scanDirectory = function(dir, callback)
local handle = assert(uv.fs_scandir(dir));
local name, t;
repeat
name, t = uv.fs_scandir_next(handle);
if (t == 'file') then
callback(dir, name);
elseif (t == 'directory' and name ~= BUILD_NAME) then
scanDirectory(path.join(dir, name), callback);
end;
until not name;
end;
local prepare = function()
-- Check for 7 Zip --
if (system_os == 'Windows') then
local zipper = uv.fs_stat(ZIP_COMMANDLINE);
assert(zipper and zipper.type == 'file', 'Only 7-Zip is supported to build the project on Windows');
end;
-- Make a build folder --
local data = uv.fs_stat(BUILD_NAME);
if ((not data) or (data and data.type ~= 'directory')) then
assert(uv.fs_mkdir(BUILD_NAME, MAX_PERMS));
end;
end;
local clear = function()
local data = uv.fs_stat(BUILD_NAME);
if (data and data.type ~= 'directory') then
assert(uv.fs_rmdir(BUILD_NAME))
end;
end;
local createLoveArchive = function()
local thread = coroutine.running();
local handle;
local filename = path.basename(cwd)..'.love';
local archive_location = path.join(BUILD_NAME, filename);
if (system_os == 'Windows') then
handle = assert(uv.spawn(ZIP_COMMANDLINE, {
cwd = cwd;
args = {'a', '-tzip', archive_location, '-x!tests', '-x!build', '-x!.vscode', '-x!cdeps', '-xr!*.dll'};
stdio = {stdin, stdout, stderr};
}, function(code)
assert(code == 0, '7-Zip returned '..tostring(code)..' exit code');
fsExists(archive_location, 'file', 'failed to find file ('..filename..') after 7-Zip archiving');
handle:close();
coroutine.resume(thread);
end));
end;
print('Creating love archive...');
coroutine.yield();
print('Created '..archive_location);
return archive_location;
end;
local createExecutable = function(archive)
local filename = path.basename(archive):sub(1, -6)..'.exe';
local executable_location = path.join(BUILD_NAME, filename);
if (system_os == 'Windows') then
print('Created fused executable...', format(COPY_FUSED_FORMAT, LOVE2D_EXE, archive, executable_location));
local c_res, _, c_code = qexecute(format(COPY_FUSED_FORMAT, LOVE2D_EXE, archive, executable_location));
assert(c_res and c_code == 0, 'copy command encountered an error');
fsExists(executable_location, 'file', 'failed to find file ('..filename..') after copy');
print('Deleting archive...');
assert(uv.fs_unlink(archive));
end;
end;
local copyLove2DFiles = function()
local n = #LOVE2D_FILES;
for i = 1, n do
local filename = LOVE2D_FILES[i];
local file_path = path.join(LOVE2D, filename);
local build_path = path.join(BUILD_NAME, filename);
print('Checking file ('..filename..') in Love2D directory');
fsExists(file_path, 'file', 'file ('..filename..') not found in Love2D directory');
print('Copying file ('..filename..')');
qexecute(format(COPY_FORMAT, file_path, build_path));
fsExists(build_path, 'file', 'failed to find file ('..filename..') after copy');
print('Copy found at', build_path..'\n');
end;
end;
local copyGameLibs = function()
scanDirectory('.', function(dir, filename)
if (path.extname(filename) == LIBRARY_EXT) then
local full_path = path.join(dir, filename);
local build_path = path.join(BUILD_NAME, filename);
print('Copying file ('..filename..')', full_path, build_path);
qexecute(format(COPY_FORMAT, full_path, build_path));
fsExists(build_path, 'file', 'failed to find file ('..filename..') after copy');
print('Copy found at', build_path..'\n');
end;
end);
end;
coroutine.wrap(function()
local version_display = format(VERSION_FORMAT, bin_package.version);
uv.set_process_title(version_display);
print(format(SPLIT_FORMAT, version_display));
print(format(REPO_FORMAT, bin_package.homepage));
print('Operating System: '..system_os..' '..system_arch);
assert(system_os == 'Windows', 'windows only executable');
print(format(SPLIT_FORMAT, 'Clearing old build'));
clear();
print(format(SPLIT_FORMAT, 'Checking for dependencies'));
prepare();
print(format(SPLIT_FORMAT, 'Creating .love'));
local archive = createLoveArchive();
print(format(SPLIT_FORMAT, 'Creating executable'));
createExecutable(archive);
print(format(SPLIT_FORMAT, 'Importing Love2D files'));
copyLove2DFiles();
print(format(SPLIT_FORMAT, 'Importing Libraries'));
copyGameLibs();
print(format(SPLIT_FORMAT, 'done'));
print('Build located at '..uv.fs_realpath(BUILD_NAME));
end)();
uv.run();