mirror of
https://github.com/TangentFoxy/love-release.git
synced 2025-07-27 18:42:20 +00:00
Rewrite in Lua with LuaRocks
This commit is contained in:
44
.gitignore
vendored
Normal file
44
.gitignore
vendored
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
### Lua ###
|
||||||
|
# LDoc
|
||||||
|
/doc
|
||||||
|
|
||||||
|
# Compiled Lua sources
|
||||||
|
luac.out
|
||||||
|
|
||||||
|
# luarocks build files
|
||||||
|
*.src.rock
|
||||||
|
*.zip
|
||||||
|
*.tar.gz
|
||||||
|
|
||||||
|
# Object files
|
||||||
|
*.o
|
||||||
|
*.os
|
||||||
|
*.ko
|
||||||
|
*.obj
|
||||||
|
*.elf
|
||||||
|
|
||||||
|
# Precompiled Headers
|
||||||
|
*.gch
|
||||||
|
*.pch
|
||||||
|
|
||||||
|
# Libraries
|
||||||
|
*.lib
|
||||||
|
*.a
|
||||||
|
*.la
|
||||||
|
*.lo
|
||||||
|
*.def
|
||||||
|
*.exp
|
||||||
|
|
||||||
|
# Shared objects (inc. Windows DLLs)
|
||||||
|
*.dll
|
||||||
|
*.so
|
||||||
|
*.so.*
|
||||||
|
*.dylib
|
||||||
|
|
||||||
|
# Executables
|
||||||
|
*.exe
|
||||||
|
*.out
|
||||||
|
*.app
|
||||||
|
*.i*86
|
||||||
|
*.x86_64
|
||||||
|
*.hex
|
85
README.md
Normal file
85
README.md
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
# love-release
|
||||||
|
[](LICENSE)
|
||||||
|
|
||||||
|
[Lua][lua] 5.1 script that makes [LÖVE][love] game release easier (previously Bash script).
|
||||||
|
Automates LÖVE [Game Distribution][game_dist].
|
||||||
|
LÖVE [forum topic][forum_topic].
|
||||||
|
Available as a [LuaRocks][luarocks] [package][package].
|
||||||
|
|
||||||
|
## Features
|
||||||
|
love-release makes your LÖVE game release easier. It can create from your sources Windows executables, MacOS X applications, Debian packages and simple LÖVE files.
|
||||||
|
|
||||||
|
love-release creates only one LÖVE file in a release directory and keeps it synced with your sources.
|
||||||
|
|
||||||
|
love-release can extract its informations from the environment: it guesses your game's title from the directory where it's stored, selects by default the latest LÖVE version from the web or uses its latest bundled LÖVE version, then parses the `conf.lua` file to extract even more informations such as the real LÖVE version your project uses.
|
||||||
|
|
||||||
|
### Configuration
|
||||||
|
love-release prints to the command-line a Lua table containing the informations it uses to generate your project. These informations can be stored in your `conf.lua` file to be used later.
|
||||||
|
|
||||||
|
```lua
|
||||||
|
function love.conf(t)
|
||||||
|
t.releases = {
|
||||||
|
title = nil, -- The project title (string)
|
||||||
|
package = nil, -- The project command and package name (string)
|
||||||
|
loveVersion = nil, -- The project LÖVE version
|
||||||
|
version = nil, -- The project version
|
||||||
|
author = nil, -- Your name (string)
|
||||||
|
email = nil, -- Your email (string)
|
||||||
|
description = nil, -- The project description (string)
|
||||||
|
homepage = nil, -- The project homepage (string)
|
||||||
|
identifier = nil, -- The project Uniform Type Identifier (string)
|
||||||
|
releaseDirectory = nil, -- Where to store the project releases (string)
|
||||||
|
}
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
### Dependencies
|
||||||
|
love-release is only installable through LuaRocks and highly depends on LuaRocks internal API. love-release is currently build on LuaRocks 2.3.0. LuaRocks API is not meant to be stable, and a future update could break love-release. As love-release is made for LÖVE, it is written for Lua 5.1.
|
||||||
|
|
||||||
|
#### Required
|
||||||
|
- [libzip][libzip] headers for lua-zip.
|
||||||
|
- [lua-zip][lua-zip] has no official stable version, thus while available on LuaRocks it must be installed manually.
|
||||||
|
- Other libraries are automatically installed, but let's give them some credit: [luafilesystem][lfs], [loadconf][loadconf], [middleclass][middleclass], [semver][semver].
|
||||||
|
|
||||||
|
#### Optional
|
||||||
|
- `love` can be used to determine your system LÖVE version.
|
||||||
|
- `fakeroot` and `dpkg-deb` are required to create Debian packages.
|
||||||
|
|
||||||
|
### Install
|
||||||
|
|
||||||
|
```sh
|
||||||
|
# sudo
|
||||||
|
luarocks install --server=http://luarocks.org/dev lua-zip
|
||||||
|
luarocks install --server=http://luarocks.org/dev love-release
|
||||||
|
```
|
||||||
|
|
||||||
|
### Remove Bash version
|
||||||
|
You may have previously installed the Bash version of love-release. You can remove it with the following piece of code. Take the time to assure yourself that the paths are correct and match your installation of love-release.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
rm -rf '/usr/bin/love-release'
|
||||||
|
rm -rf '/usr/share/love-release'
|
||||||
|
rm -rf '/usr/share/man/man1/love-release.1.gz'
|
||||||
|
rm -rf '/usr/share/bash-completion/completions/love-release' '/etc/bash_completion.d/love-release'
|
||||||
|
```
|
||||||
|
|
||||||
|
## Contribute
|
||||||
|
The documentation of love-release internals is written with [LDoc][ldoc]. Generate it by running `ldoc .`.
|
||||||
|
I do not plan to keep developing the Bash script, not even fixing it. If there appears to be any need for it, let me know and I might consider doing so.
|
||||||
|
Every bug report or feature request is gladly welcome !
|
||||||
|
|
||||||
|
[forum_topic]: https://love2d.org/forums/viewtopic.php?t=75387
|
||||||
|
[game_dist]: https://www.love2d.org/wiki/Game_Distribution
|
||||||
|
[ldoc]: https://github.com/stevedonovan/LDoc
|
||||||
|
[lfs]: https://github.com/keplerproject/luafilesystem
|
||||||
|
[libzip]: http://www.nih.at/libzip/
|
||||||
|
[love]: https://www.love2d.org/
|
||||||
|
[lua]: http://www.lua.org/
|
||||||
|
[luarocks]: https://luarocks.org/
|
||||||
|
[lua-zip]: https://github.com/brimworks/lua-zip
|
||||||
|
[loadconf]: https://github.com/Alloyed/loadconf
|
||||||
|
[middleclass]: https://github.com/kikito/middleclass
|
||||||
|
[package]: https://luarocks.org/modules/rucikir/love-release
|
||||||
|
[semver]: https://github.com/kikito/semver.lua
|
8
config.ld
Normal file
8
config.ld
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
file = "src"
|
||||||
|
project = "love-release"
|
||||||
|
description = [[
|
||||||
|
love-release - a Lua script to make LÖVE games releases easier
|
||||||
|
]]
|
||||||
|
readme = "README.md"
|
||||||
|
format = "discount"
|
||||||
|
title = "love-release documentation"
|
42
rockspecs/love-release-scm-1.rockspec
Normal file
42
rockspecs/love-release-scm-1.rockspec
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
package = "love-release"
|
||||||
|
version = "scm-1"
|
||||||
|
source = {
|
||||||
|
url = "git://github.com/MisterDA/love-release.git",
|
||||||
|
branch = "lua",
|
||||||
|
}
|
||||||
|
description = {
|
||||||
|
summary = "Make LÖVE games releases easier",
|
||||||
|
detailed = [[
|
||||||
|
love-release make LÖVE games releases easier.
|
||||||
|
It automates LÖVE Game Distribution.
|
||||||
|
]],
|
||||||
|
license = "MIT",
|
||||||
|
homepage = "https://github.com/MisterDA/love-release",
|
||||||
|
}
|
||||||
|
dependencies = {
|
||||||
|
"loadconf",
|
||||||
|
"lua ~> 5.1",
|
||||||
|
"luafilesystem",
|
||||||
|
"lua-zip",
|
||||||
|
"middleclass",
|
||||||
|
"semver",
|
||||||
|
}
|
||||||
|
build = {
|
||||||
|
type = "builtin",
|
||||||
|
modules = {
|
||||||
|
["love-release.scripts.debian"] = "src/scripts/debian.lua",
|
||||||
|
["love-release.scripts.love"] = "src/scripts/love.lua",
|
||||||
|
["love-release.scripts.macosx"] = "src/scripts/macosx.lua",
|
||||||
|
["love-release.scripts.windows"] = "src/scripts/windows.lua",
|
||||||
|
["love-release.pipes.conf"] = "src/pipes/conf.lua",
|
||||||
|
["love-release.pipes.env"] = "src/pipes/env.lua",
|
||||||
|
["love-release.project"] = "src/project.lua",
|
||||||
|
["love-release.script"] = "src/script.lua",
|
||||||
|
["love-release.utils"] = "src/utils.lua",
|
||||||
|
},
|
||||||
|
install = {
|
||||||
|
bin = {
|
||||||
|
["love-release"] = "src/main.lua"
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
20
src/main.lua
Normal file
20
src/main.lua
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
--- love-release main.
|
||||||
|
-- @script love-release
|
||||||
|
|
||||||
|
local conf = require 'love-release.pipes.conf'
|
||||||
|
local env = require 'love-release.pipes.env'
|
||||||
|
local Project = require 'love-release.project'
|
||||||
|
local p = Project:new()
|
||||||
|
conf(env(p))
|
||||||
|
|
||||||
|
print(p)
|
||||||
|
|
||||||
|
local script
|
||||||
|
script = require 'love-release.scripts.love'
|
||||||
|
script(p)
|
||||||
|
script = require 'love-release.scripts.macosx'
|
||||||
|
script(p)
|
||||||
|
script = require 'love-release.scripts.windows'
|
||||||
|
script(p)
|
||||||
|
script = require 'love-release.scripts.debian'
|
||||||
|
script(p)
|
78
src/pipes/conf.lua
Normal file
78
src/pipes/conf.lua
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
--- Gather informations from the LÖVE conf.lua file.
|
||||||
|
-- @module conf
|
||||||
|
-- @usage conf(project)
|
||||||
|
|
||||||
|
local fs = require 'luarocks.fs'
|
||||||
|
local loadconf = require 'loadconf'
|
||||||
|
local semver = require 'semver'
|
||||||
|
|
||||||
|
local utils = require 'love-release.utils'
|
||||||
|
|
||||||
|
|
||||||
|
local pipe = {}
|
||||||
|
|
||||||
|
function pipe.pipe(project)
|
||||||
|
local err = utils.io.err
|
||||||
|
|
||||||
|
-- checks for a conf.lua file
|
||||||
|
fs.change_dir(project.projectDirectory)
|
||||||
|
if not fs.exists("conf.lua") then
|
||||||
|
err("CONF: No conf.lua provided.\n")
|
||||||
|
return project
|
||||||
|
end
|
||||||
|
local conf = assert(loadconf.parse_file("conf.lua"))
|
||||||
|
fs.pop_dir()
|
||||||
|
|
||||||
|
local function setString(key, value)
|
||||||
|
if type(value) == "string" then
|
||||||
|
project["set"..key](project, value)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function setLoveVersion(v)
|
||||||
|
if type(v) == "string" and v ~= "" then
|
||||||
|
local version = semver(v)
|
||||||
|
if not utils.love.isSupported(version) then
|
||||||
|
local scriptLoveVersion = project.loveVersion
|
||||||
|
err("CONF: Your LÖVE conf version ("..v
|
||||||
|
.. ") is not supported by love-release ("..tostring(scriptLoveVersion)
|
||||||
|
.. ").\n")
|
||||||
|
if version > scriptLoveVersion then
|
||||||
|
err(" You should update love-release.\n")
|
||||||
|
elseif version < scriptLoveVersion then
|
||||||
|
err(" You should update your project.\n")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
project:setLoveVersion(version)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- extract LÖVE standard fields
|
||||||
|
setString("Title", conf.title)
|
||||||
|
setString("Package", conf.package)
|
||||||
|
setLoveVersion(conf.version)
|
||||||
|
|
||||||
|
-- extract love-release fields
|
||||||
|
local releases = conf.releases
|
||||||
|
if type(releases) == "table" then
|
||||||
|
setString("Title", releases.title)
|
||||||
|
setString("Package", releases.package)
|
||||||
|
setLoveVersion(releases.loveVersion)
|
||||||
|
setString("Version", releases.version)
|
||||||
|
setString("Author", releases.author)
|
||||||
|
setString("Email", releases.email)
|
||||||
|
setString("Description", releases.description)
|
||||||
|
setString("Homepage", releases.homepage)
|
||||||
|
setString("Identifier", releases.identifier)
|
||||||
|
setString("ReleaseDirectory", releases.releaseDirectory)
|
||||||
|
end
|
||||||
|
|
||||||
|
return project
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
setmetatable(pipe, {
|
||||||
|
__call = function(_, project) return pipe.pipe(project) end,
|
||||||
|
})
|
||||||
|
|
||||||
|
return pipe
|
115
src/pipes/env.lua
Normal file
115
src/pipes/env.lua
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
--- Gather informations from the environment.
|
||||||
|
-- @module env
|
||||||
|
-- @usage env(project)
|
||||||
|
|
||||||
|
local fs = require 'luarocks.fs'
|
||||||
|
local semver = require 'semver'
|
||||||
|
local utils = require 'love-release.utils'
|
||||||
|
|
||||||
|
local pipe = {}
|
||||||
|
|
||||||
|
|
||||||
|
--- Gets the version of the installed LÖVE.
|
||||||
|
-- @treturn semver LÖVE version.
|
||||||
|
-- @local
|
||||||
|
local function getSystemLoveVersion()
|
||||||
|
local handle = io.popen('love --version')
|
||||||
|
local result = handle:read("*a")
|
||||||
|
handle:close()
|
||||||
|
local version = result:match('%d+%.%d+%.%d+')
|
||||||
|
if version then
|
||||||
|
return semver(version)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Gets the latest LÖVE version from the web.
|
||||||
|
-- @treturn semver LÖVE version.
|
||||||
|
-- @local
|
||||||
|
local function getWebLoveVersion()
|
||||||
|
local releasesPath = utils.cache.."/releases.xml"
|
||||||
|
|
||||||
|
local ok, err = fs.download("https://love2d.org/releases.xml",
|
||||||
|
releasesPath,
|
||||||
|
true)
|
||||||
|
if ok then
|
||||||
|
local releasesXml = io.open(releasesPath, "rb")
|
||||||
|
local version = releasesXml:read("*a"):match("<title>(%d+%.%d+%.%d+)")
|
||||||
|
releasesXml:close()
|
||||||
|
return semver(version)
|
||||||
|
else
|
||||||
|
return nil, err
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Gets the latest LÖVE version from the script, the system and the web.
|
||||||
|
-- @tparam semver script script version.
|
||||||
|
-- @tparam semver system system version.
|
||||||
|
-- @tparam semver web web version.
|
||||||
|
-- @treturn semver the latest version.
|
||||||
|
-- @local
|
||||||
|
local function getLatestLoveVersion(script, system, web)
|
||||||
|
local version = script
|
||||||
|
if system and system >= script then
|
||||||
|
version = system
|
||||||
|
end
|
||||||
|
if web and web > version then
|
||||||
|
version = web
|
||||||
|
end
|
||||||
|
return version
|
||||||
|
end
|
||||||
|
|
||||||
|
function pipe.pipe(project)
|
||||||
|
local err = utils.io.err
|
||||||
|
|
||||||
|
-- checks for a main.lua file
|
||||||
|
fs.change_dir(project.projectDirectory)
|
||||||
|
if not fs.exists("main.lua") then
|
||||||
|
err("ENV: No main.lua provided.\n")
|
||||||
|
os.exit(1)
|
||||||
|
end
|
||||||
|
fs.pop_dir()
|
||||||
|
|
||||||
|
-- title
|
||||||
|
project:setTitle(project.projectDirectory:match("[^/]+$"))
|
||||||
|
|
||||||
|
-- package
|
||||||
|
project:setPackage(project.title:gsub("%W", "-"):lower())
|
||||||
|
|
||||||
|
-- LÖVE version
|
||||||
|
|
||||||
|
local systemLoveVersion = getSystemLoveVersion()
|
||||||
|
local webLoveVersion = getWebLoveVersion()
|
||||||
|
local scriptLoveVersion = utils.love.lastVersion()
|
||||||
|
local isSupported = utils.love.isSupported
|
||||||
|
|
||||||
|
if systemLoveVersion and not isSupported(systemLoveVersion) then
|
||||||
|
err("ENV: Your LÖVE installed version (" .. tostring(systemLoveVersion) ..
|
||||||
|
") is not supported by love-release (" .. tostring(scriptLoveVersion) ..
|
||||||
|
").\n")
|
||||||
|
if systemLoveVersion > scriptLoveVersion then
|
||||||
|
err(" You should update love-release.\n")
|
||||||
|
elseif systemLoveVersion < scriptLoveVersion then
|
||||||
|
err(" You should update LÖVE.\n")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if webLoveVersion and not isSupported(webLoveVersion) then
|
||||||
|
err("ENV: The upstream LÖVE version (" .. tostring(webLoveVersion) ..
|
||||||
|
") is not supported by love-release (" .. tostring(scriptLoveVersion) ..
|
||||||
|
").\n")
|
||||||
|
err(" You should update love-release.\n")
|
||||||
|
end
|
||||||
|
|
||||||
|
project:setLoveVersion(getLatestLoveVersion(scriptLoveVersion,
|
||||||
|
systemLoveVersion,
|
||||||
|
webLoveVersion))
|
||||||
|
|
||||||
|
return project
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
setmetatable(pipe, {
|
||||||
|
__call = function(_, project) return pipe.pipe(project) end,
|
||||||
|
})
|
||||||
|
|
||||||
|
return pipe
|
272
src/project.lua
Normal file
272
src/project.lua
Normal file
@@ -0,0 +1,272 @@
|
|||||||
|
--- Provides tools to manipulate a LÖVE project.
|
||||||
|
-- @classmod project
|
||||||
|
|
||||||
|
local fs = require 'luarocks.fs'
|
||||||
|
local lr_dir = require 'luarocks.dir'
|
||||||
|
local class = require 'middleclass'
|
||||||
|
local utils = require 'love-release.utils'
|
||||||
|
|
||||||
|
local Project = class('Project')
|
||||||
|
|
||||||
|
|
||||||
|
--- Title of this project.
|
||||||
|
Project.title = nil
|
||||||
|
|
||||||
|
--- Package name. It's the title converted to lowercase, with alpha-numerical
|
||||||
|
-- characters and hyphens only.
|
||||||
|
Project.package = nil
|
||||||
|
|
||||||
|
--- LÖVE version the project uses.
|
||||||
|
Project.loveVersion = nil
|
||||||
|
|
||||||
|
--- Version.
|
||||||
|
Project.version = nil
|
||||||
|
|
||||||
|
--- Author full name.
|
||||||
|
Project.author = nil
|
||||||
|
|
||||||
|
--- Email.
|
||||||
|
Project.email = nil
|
||||||
|
|
||||||
|
--- Description.
|
||||||
|
Project.description = nil
|
||||||
|
|
||||||
|
--- Homepage URL.
|
||||||
|
Project.homepage = nil
|
||||||
|
|
||||||
|
--- Uniform Type Identifier in reverse-DNS format.
|
||||||
|
Project.identifier = nil
|
||||||
|
|
||||||
|
--- Project directory, where to find the game sources.
|
||||||
|
Project.projectDirectory = nil
|
||||||
|
|
||||||
|
--- Project release directory, where to store the releases.
|
||||||
|
Project.releaseDirectory = nil
|
||||||
|
|
||||||
|
Project._fileTree = nil
|
||||||
|
Project._fileList = nil
|
||||||
|
|
||||||
|
function Project:initialize()
|
||||||
|
local defaultDirectory = fs.current_dir()
|
||||||
|
self:setProjectDirectory(defaultDirectory)
|
||||||
|
self:setReleaseDirectory(defaultDirectory.."/releases")
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Recursive function used to build the tree.
|
||||||
|
-- @local
|
||||||
|
local _buildFileTree
|
||||||
|
_buildFileTree = function(dir)
|
||||||
|
local subDir
|
||||||
|
for file in assert(fs.dir()) do
|
||||||
|
if not file:find("^%.git") then
|
||||||
|
if fs.is_dir(file) then
|
||||||
|
subDir = {}
|
||||||
|
dir[file] = subDir
|
||||||
|
assert(fs.change_dir(file))
|
||||||
|
_buildFileTree(subDir, file)
|
||||||
|
assert(fs.pop_dir())
|
||||||
|
elseif fs.is_file(file) then
|
||||||
|
dir[#dir+1] = file
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Constructs the file tree.
|
||||||
|
-- @return File tree. The table represents the root directory.
|
||||||
|
-- Sub-directories are represented as sub-tables, indexed by the directory name.
|
||||||
|
-- Files are strings stored in each sub-tables.
|
||||||
|
function Project:fileTree()
|
||||||
|
if not self._fileTree then
|
||||||
|
assert(fs.change_dir(self.projectDirectory))
|
||||||
|
self._fileTree = {}
|
||||||
|
_buildFileTree(self._fileTree)
|
||||||
|
assert(fs.pop_dir())
|
||||||
|
end
|
||||||
|
return self._fileTree
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Recursive function used to build the file list.
|
||||||
|
-- @local
|
||||||
|
local _buildFileList
|
||||||
|
_buildFileList = function(list, tree, dir)
|
||||||
|
for k, v in pairs(tree) do
|
||||||
|
if type(v) == "table" then
|
||||||
|
list[#list+1] = dir..k.."/"
|
||||||
|
_buildFileList(list, tree[k], dir..k.."/")
|
||||||
|
elseif type(v) == "string" then
|
||||||
|
list[#list+1] = dir..v
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Constructs the file list.
|
||||||
|
-- @bool build Rebuild the file tree.
|
||||||
|
-- @treturn table List of this project's files.
|
||||||
|
function Project:fileList(build)
|
||||||
|
if not self._fileList or build then
|
||||||
|
self._fileList = {}
|
||||||
|
_buildFileList(self._fileList, self:fileTree(), "")
|
||||||
|
self:excludeFiles()
|
||||||
|
end
|
||||||
|
return self._fileList
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Excludes files from the LÖVE file.
|
||||||
|
-- @todo This function should be able to parse and use CVS files such as
|
||||||
|
-- gitignore. It should also work on the file tree rather than on the file list.
|
||||||
|
-- For now it only exludes the release directory if it is within the project
|
||||||
|
-- directory and works on the file list.
|
||||||
|
function Project:excludeFiles()
|
||||||
|
local dir = self.releaseDirectory:gsub(
|
||||||
|
"^"..utils.lua.escape_string_regex(self.projectDirectory).."/",
|
||||||
|
"")
|
||||||
|
if dir then
|
||||||
|
local n = #self._fileList
|
||||||
|
for i = 1, n do
|
||||||
|
if self._fileList[i]:find("^"..dir) then
|
||||||
|
self._fileList[i] = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
|
-- File tree traversal
|
||||||
|
local function deep(tree)
|
||||||
|
for k, v in pairs(tree) do
|
||||||
|
if type(v) == "string" then
|
||||||
|
print(v)
|
||||||
|
elseif type(v) == "table" then
|
||||||
|
print(k)
|
||||||
|
deep(v)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
deep(t)
|
||||||
|
--]]
|
||||||
|
|
||||||
|
local function escape(var)
|
||||||
|
if type(var) == "string" then
|
||||||
|
return "'"..var:gsub("'", "\'").."'"
|
||||||
|
else
|
||||||
|
return tostring(var)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Prints debug informations.
|
||||||
|
-- @local
|
||||||
|
function Project:__tostring()
|
||||||
|
return
|
||||||
|
'{\n'..
|
||||||
|
' title = '..escape(self.title)..',\n'..
|
||||||
|
' package = '..escape(self.package)..',\n'..
|
||||||
|
' loveVersion = \''..escape(self.loveVersion)..'\',\n'..
|
||||||
|
' version = '..escape(self.version)..',\n'..
|
||||||
|
' author = '..escape(self.author)..',\n'..
|
||||||
|
' email = '..escape(self.email)..',\n'..
|
||||||
|
' description = '..escape(self.description)..',\n'..
|
||||||
|
' homepage = '..escape(self.homepage)..',\n'..
|
||||||
|
' identifier = '..escape(self.identifier)..',\n'..
|
||||||
|
' projectDirectory = '..escape(self.projectDirectory)..',\n'..
|
||||||
|
' releaseDirectory = '..escape(self.releaseDirectory)..',\n'..
|
||||||
|
'}'
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Sets the title.
|
||||||
|
-- @string title the title.
|
||||||
|
-- @treturn project self.
|
||||||
|
function Project:setTitle(title)
|
||||||
|
self.title = title
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Sets the package name.
|
||||||
|
-- @string package the package name.
|
||||||
|
-- @treturn project self.
|
||||||
|
function Project:setPackage(package)
|
||||||
|
self.package = package
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Sets the LÖVE version used.
|
||||||
|
-- @tparam semver version the LÖVE version.
|
||||||
|
-- @treturn project self.
|
||||||
|
function Project:setLoveVersion(version)
|
||||||
|
self.loveVersion = version
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Sets the project's version.
|
||||||
|
-- @string version the version.
|
||||||
|
-- @treturn project self.
|
||||||
|
function Project:setVersion(version)
|
||||||
|
self.version = version
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Sets the author.
|
||||||
|
-- @string author the author.
|
||||||
|
-- @treturn project self.
|
||||||
|
function Project:setAuthor(author)
|
||||||
|
self.author = author
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Sets the author's email.
|
||||||
|
-- @string email the email.
|
||||||
|
-- @treturn project self.
|
||||||
|
function Project:setEmail(email)
|
||||||
|
self.email = email
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Sets the description.
|
||||||
|
-- @string description the description.
|
||||||
|
-- @treturn project self.
|
||||||
|
function Project:setDescription(description)
|
||||||
|
self.description = description
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Sets the homepage.
|
||||||
|
-- @string homepage the homepage.
|
||||||
|
-- @treturn project self.
|
||||||
|
function Project:setHomepage(homepage)
|
||||||
|
self.homepage = homepage
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Sets the identifier.
|
||||||
|
-- @string identifier the identifier.
|
||||||
|
-- @treturn project self.
|
||||||
|
function Project:setIdentifier(identifier)
|
||||||
|
self.identifier = identifier
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Sets the source directory. The path is normalized and absoluted.
|
||||||
|
-- @string directory the directory.
|
||||||
|
-- @treturn project self.
|
||||||
|
function Project:setProjectDirectory(directory)
|
||||||
|
directory = fs.absolute_name(lr_dir.normalize(directory))
|
||||||
|
assert(fs.change_dir(directory))
|
||||||
|
fs.pop_dir()
|
||||||
|
self.projectDirectory = directory
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Sets the release directory. The path is normalized and absoluted.
|
||||||
|
-- @string directory the directory.
|
||||||
|
-- @treturn project self.
|
||||||
|
function Project:setReleaseDirectory(directory)
|
||||||
|
directory = fs.absolute_name(lr_dir.normalize(directory))
|
||||||
|
assert(fs.make_dir(directory))
|
||||||
|
assert(fs.change_dir(directory))
|
||||||
|
fs.pop_dir()
|
||||||
|
self.releaseDirectory = directory
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
return Project
|
87
src/script.lua
Normal file
87
src/script.lua
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
--- A love-release script.
|
||||||
|
-- @classmod script
|
||||||
|
|
||||||
|
local fs = require 'luarocks.fs'
|
||||||
|
local class = require 'middleclass'
|
||||||
|
local lfs = require "lfs"
|
||||||
|
local zip = require 'brimworks.zip'
|
||||||
|
local utils = require 'love-release.utils'
|
||||||
|
|
||||||
|
local Script = class('Script')
|
||||||
|
|
||||||
|
|
||||||
|
--- Current project.
|
||||||
|
Script.project = nil
|
||||||
|
|
||||||
|
--- Name of the LÖVE file.
|
||||||
|
Script.loveFile = nil
|
||||||
|
|
||||||
|
local function validate(project)
|
||||||
|
local valid, err = true, utils.io.err
|
||||||
|
if type(project.title) ~= "string" or project.title == "" then
|
||||||
|
err("SCRIPT: No title specified.\n")
|
||||||
|
valid = false
|
||||||
|
end
|
||||||
|
if type(project.package) ~= "string" or project.package == "" then
|
||||||
|
err("SCRIPT: No package specified.\n")
|
||||||
|
valid = false
|
||||||
|
end
|
||||||
|
if not type(project.loveVersion) then
|
||||||
|
err("SCRIPT: No LÖVE version specified.\n")
|
||||||
|
valid = false
|
||||||
|
end
|
||||||
|
if not valid then os.exit(1) end
|
||||||
|
return project
|
||||||
|
end
|
||||||
|
|
||||||
|
function Script:initialize(project)
|
||||||
|
self.project = validate(project)
|
||||||
|
self.loveFile = project.title..'.love'
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Creates a LÖVE file in the release directory of the current project.
|
||||||
|
function Script:createLoveFile()
|
||||||
|
local ar = assert(zip.open(self.project.releaseDirectory.."/"..self.loveFile,
|
||||||
|
zip.OR(zip.CREATE, zip.CHECKCONS)))
|
||||||
|
|
||||||
|
assert(fs.change_dir(self.project.projectDirectory))
|
||||||
|
|
||||||
|
local attributes, stat
|
||||||
|
for _, file in ipairs(self.project:fileList()) do
|
||||||
|
attributes = assert(lfs.attributes(file))
|
||||||
|
stat = ar:stat(file)
|
||||||
|
|
||||||
|
-- file is not present in the filesystem nor the archive
|
||||||
|
if not attributes and not stat then
|
||||||
|
utils.io.err("BUILD: "..file.." is not present in the file system.\n")
|
||||||
|
-- file is not present in the archive
|
||||||
|
elseif attributes and not stat then
|
||||||
|
utils.io.out("Add "..file.."\n")
|
||||||
|
if attributes.mode == "directory" then
|
||||||
|
ar:add_dir(file)
|
||||||
|
else
|
||||||
|
ar:add(file, "file", file)
|
||||||
|
end
|
||||||
|
-- file in the filesystem is more recent than in the archive
|
||||||
|
elseif attributes and stat and attributes.modification > stat.mtime + 5 then
|
||||||
|
if attributes.mode == "file" then
|
||||||
|
utils.io.out("Update "..file.."\n")
|
||||||
|
ar:replace(assert(ar:name_locate(file)), "file", file)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
for i = 1, #ar do
|
||||||
|
local file = ar:stat(i).name
|
||||||
|
-- file is present in the archive, but not in the filesystem
|
||||||
|
if not lfs.attributes(file) then
|
||||||
|
utils.io.out("Delete "..file.."\n")
|
||||||
|
ar:delete(i)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
ar:close()
|
||||||
|
assert(fs.pop_dir())
|
||||||
|
end
|
||||||
|
|
||||||
|
return Script
|
138
src/scripts/debian.lua
Normal file
138
src/scripts/debian.lua
Normal file
@@ -0,0 +1,138 @@
|
|||||||
|
--- Debian package release.
|
||||||
|
-- @module scripts.debian
|
||||||
|
-- @usage debian(project)
|
||||||
|
|
||||||
|
local fs = require 'luarocks.fs'
|
||||||
|
local dir = require 'luarocks.dir'
|
||||||
|
local lfs = require 'lfs'
|
||||||
|
local Script = require 'love-release.script'
|
||||||
|
local utils = require 'love-release.utils'
|
||||||
|
|
||||||
|
local s = {}
|
||||||
|
|
||||||
|
|
||||||
|
local function validate(project)
|
||||||
|
local valid, err = true, utils.io.err
|
||||||
|
if type(project.author) ~= "string" or project.author == "" then
|
||||||
|
err("DEBIAN: No author specified.\n")
|
||||||
|
valid = false
|
||||||
|
end
|
||||||
|
if type(project.description) ~= "string" or project.description == "" then
|
||||||
|
err("DEBIAN: No description specified.\n")
|
||||||
|
valid = false
|
||||||
|
end
|
||||||
|
if type(project.email) ~= "string" or project.email == "" then
|
||||||
|
err("DEBIAN: No email specified.\n")
|
||||||
|
valid = false
|
||||||
|
end
|
||||||
|
if type(project.homepage) ~= "string" or project.homepage == "" then
|
||||||
|
err("DEBIAN: No homepage specified.\n")
|
||||||
|
valid = false
|
||||||
|
end
|
||||||
|
if type(project.version) ~= "string" or project.version == "" then
|
||||||
|
err("DEBIAN: No version specified.\n")
|
||||||
|
valid = false
|
||||||
|
end
|
||||||
|
if not valid then os.exit(1) end
|
||||||
|
return project
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Is it such a good design to load the Debian package into memory with
|
||||||
|
-- temporary files ?
|
||||||
|
function s.script(project)
|
||||||
|
local ok1, err1 = fs.is_tool_available("fakeroot", "fakeroot", "-v")
|
||||||
|
local ok2, err2 = fs.is_tool_available("dpkg-deb", "dpkg-deb")
|
||||||
|
if not ok1 or not ok2 then
|
||||||
|
if not ok1 then utils.io.err(err1) end
|
||||||
|
if not ok2 then utils.io.err(err2) end
|
||||||
|
os.exit(1)
|
||||||
|
end
|
||||||
|
|
||||||
|
local script = Script:new(validate(project))
|
||||||
|
script:createLoveFile()
|
||||||
|
|
||||||
|
local tempDir = assert(fs.make_temp_dir("debian"))
|
||||||
|
local loveFileDeb = "/usr/share/games/"..project.package.."/"..script.loveFile
|
||||||
|
local loveFileRel = project.releaseDirectory.."/"..script.loveFile
|
||||||
|
local md5sums = {}
|
||||||
|
|
||||||
|
local function writeFile(path, content, md5)
|
||||||
|
local fullPath = tempDir..path
|
||||||
|
assert(fs.make_dir(dir.dir_name(fullPath)))
|
||||||
|
local file = assert(io.open(fullPath, "wb"))
|
||||||
|
file:write(content)
|
||||||
|
file:close()
|
||||||
|
|
||||||
|
if md5 then
|
||||||
|
md5sums[#md5sums+1] = { path = path, md5 = assert(fs.get_md5(fullPath)) }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function copyFile(orig, dest, md5)
|
||||||
|
local fullPath = tempDir..dest
|
||||||
|
assert(fs.make_dir(dir.dir_name(fullPath)))
|
||||||
|
assert(fs.copy(orig, fullPath))
|
||||||
|
|
||||||
|
if md5 then
|
||||||
|
md5sums[#md5sums+1] = { path = dest, md5 = assert(fs.get_md5(fullPath)) }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- /DEBIAN/control
|
||||||
|
writeFile("/DEBIAN/control",
|
||||||
|
"Package: "..project.package.."\n"..
|
||||||
|
"Version: "..project.version.."\n"..
|
||||||
|
"Architecture: all\n"..
|
||||||
|
"Maintainer: "..project.author.." <"..project.email..">\n"..
|
||||||
|
"Installed-Size: "..
|
||||||
|
math.floor(assert(lfs.attributes(loveFileRel, "size")) / 1024).."\n"..
|
||||||
|
"Depends: love (>= "..tostring(project.loveVersion)..")\n"..
|
||||||
|
"Priority: extra\n"..
|
||||||
|
"Homepage: "..project.homepage.."\n"..
|
||||||
|
"Description: "..project.description.."\n"
|
||||||
|
)
|
||||||
|
|
||||||
|
-- /usr/share/applications/${PACKAGE}.desktop
|
||||||
|
writeFile("/usr/share/applications/"..project.package..".desktop",
|
||||||
|
"[Desktop Entry]\n"..
|
||||||
|
"Name="..project.title.."\n"..
|
||||||
|
"Comment="..project.description.."\n"..
|
||||||
|
"Exec="..project.package.."\n"..
|
||||||
|
"Type=Application\n"..
|
||||||
|
"Categories=Game;\n",
|
||||||
|
true
|
||||||
|
)
|
||||||
|
|
||||||
|
-- /usr/bin/${PACKAGE}
|
||||||
|
writeFile("/usr/bin/"..project.package,
|
||||||
|
"#!/bin/sh\n"..
|
||||||
|
"love "..loveFileDeb.."\n",
|
||||||
|
true
|
||||||
|
)
|
||||||
|
|
||||||
|
-- /usr/share/games/${PACKAGE}/${LOVE_FILE}
|
||||||
|
copyFile(project.releaseDirectory.."/"..script.loveFile, loveFileDeb, true)
|
||||||
|
|
||||||
|
-- /DEBIAN/md5sums
|
||||||
|
local sum = ""
|
||||||
|
for _, v in ipairs(md5sums) do
|
||||||
|
sum = sum..v.md5.." "..v.path.."\n"
|
||||||
|
end
|
||||||
|
writeFile("/DEBIAN/md5sums", sum)
|
||||||
|
|
||||||
|
-- create the package
|
||||||
|
local deb = project.releaseDirectory.."/"..project.package.."-"..
|
||||||
|
project.version.."_all.deb"
|
||||||
|
fs.delete(deb)
|
||||||
|
assert(fs.execute("fakeroot dpkg-deb -b ", tempDir, deb),
|
||||||
|
"DEBIAN: error while building the package.")
|
||||||
|
|
||||||
|
fs.delete(tempDir)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
setmetatable(s, {
|
||||||
|
__call = function(_, project) return s.script(project) end,
|
||||||
|
})
|
||||||
|
|
||||||
|
return s
|
20
src/scripts/love.lua
Normal file
20
src/scripts/love.lua
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
--- LÖVE file release.
|
||||||
|
-- @module scripts.love
|
||||||
|
-- @usage love(project)
|
||||||
|
|
||||||
|
local Script = require "love-release.script"
|
||||||
|
|
||||||
|
local s = {}
|
||||||
|
|
||||||
|
|
||||||
|
function s.script(project)
|
||||||
|
local script = Script:new(project)
|
||||||
|
script:createLoveFile()
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
setmetatable(s, {
|
||||||
|
__call = function(_, project) return s.script(project) end,
|
||||||
|
})
|
||||||
|
|
||||||
|
return s
|
91
src/scripts/macosx.lua
Normal file
91
src/scripts/macosx.lua
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
--- MacOS X app release.
|
||||||
|
-- @module scripts.macosx
|
||||||
|
-- @usage macosx(project)
|
||||||
|
|
||||||
|
local fs = require "luarocks.fs"
|
||||||
|
local semver = require "semver"
|
||||||
|
local zip = require "brimworks.zip"
|
||||||
|
local Script = require "love-release.script"
|
||||||
|
local utils = require "love-release.utils"
|
||||||
|
|
||||||
|
local s = {}
|
||||||
|
|
||||||
|
|
||||||
|
local function validate(project)
|
||||||
|
local valid, err = true, utils.io.err
|
||||||
|
if type(project.identifier) ~= "string" or project.identifier == "" then
|
||||||
|
err("DEBIAN: No author specified.\n")
|
||||||
|
valid = false
|
||||||
|
end
|
||||||
|
if not valid then os.exit(1) end
|
||||||
|
return project
|
||||||
|
end
|
||||||
|
|
||||||
|
function s.script(project)
|
||||||
|
local script = Script:new(validate(project))
|
||||||
|
script:createLoveFile()
|
||||||
|
fs.change_dir(project.releaseDirectory)
|
||||||
|
|
||||||
|
local prefix = "love-"..tostring(project.loveVersion).."-macosx-"
|
||||||
|
local bin
|
||||||
|
if project.loveVersion >= semver'0.9.0' then
|
||||||
|
bin = prefix.."x64.zip"
|
||||||
|
else
|
||||||
|
bin = prefix.."ub.zip"
|
||||||
|
end
|
||||||
|
local url = "https://bitbucket.org/rude/love/downloads/"..bin
|
||||||
|
local cache = utils.cache.."/"..bin
|
||||||
|
|
||||||
|
-- Can't cache the archive because luarocks functions use a HEAD request to
|
||||||
|
-- Amazon AWS which will answer a 403.
|
||||||
|
-- assert(fs.download(url, cache, true))
|
||||||
|
if not fs.exists(cache) then
|
||||||
|
assert(fs.download(url, cache))
|
||||||
|
end
|
||||||
|
|
||||||
|
fs.delete(bin)
|
||||||
|
assert(fs.copy(cache, bin))
|
||||||
|
|
||||||
|
-- local ar = assert(zip.open(bin, zip.OR(zip.CHECKCONS)))
|
||||||
|
local ar = zip.open(bin)
|
||||||
|
|
||||||
|
local infoPlistIndex = assert(ar:name_locate("love.app/Contents/Info.plist"))
|
||||||
|
local infoPlistSize = assert(ar:stat(infoPlistIndex).size)
|
||||||
|
local infoPlistHandle = assert(ar:open(infoPlistIndex))
|
||||||
|
local infoPlist = assert(infoPlistHandle:read(infoPlistSize))
|
||||||
|
infoPlistHandle:close()
|
||||||
|
infoPlist = infoPlist
|
||||||
|
:gsub("\n\t<key>UTExportedTypeDeclarations</key>.*</array>",
|
||||||
|
"")
|
||||||
|
:gsub("(CFBundleIdentifier.-<string>)(.-)(</string>)",
|
||||||
|
"%1"..project.identifier.."%3")
|
||||||
|
:gsub("(CFBundleName.-<string>)(.-)(</string>)",
|
||||||
|
"%1"..project.title..".love%3")
|
||||||
|
|
||||||
|
ar:add("love.app/Contents/Resources/"..script.loveFile,
|
||||||
|
"file", script.loveFile)
|
||||||
|
|
||||||
|
local app = project.title..".app"
|
||||||
|
for i = 1, #ar do
|
||||||
|
ar:rename(i, ar:stat(i).name:gsub("^love%.app", app))
|
||||||
|
end
|
||||||
|
|
||||||
|
ar:close()
|
||||||
|
|
||||||
|
-- for unknown reason, replacing the Info.plist content earlier would cause
|
||||||
|
-- random crashes
|
||||||
|
ar = zip.open(bin)
|
||||||
|
assert(ar:replace(infoPlistIndex, "string", infoPlist))
|
||||||
|
ar:close()
|
||||||
|
|
||||||
|
os.rename(bin, project.title.."-macosx.zip")
|
||||||
|
|
||||||
|
fs.pop_dir()
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
setmetatable(s, {
|
||||||
|
__call = function(_, project) return s.script(project) end,
|
||||||
|
})
|
||||||
|
|
||||||
|
return s
|
87
src/scripts/windows.lua
Normal file
87
src/scripts/windows.lua
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
--- Windows exe release.
|
||||||
|
-- @module scripts.windows
|
||||||
|
-- @usage windows(project)
|
||||||
|
|
||||||
|
local fs = require "luarocks.fs"
|
||||||
|
local semver = require "semver"
|
||||||
|
local zip = require "brimworks.zip"
|
||||||
|
local Script = require "love-release.script"
|
||||||
|
local utils = require "love-release.utils"
|
||||||
|
|
||||||
|
local s = {}
|
||||||
|
|
||||||
|
|
||||||
|
local function release(script, project, arch)
|
||||||
|
local prefix = "love-"..tostring(project.loveVersion).."-win"
|
||||||
|
local dir, bin
|
||||||
|
if project.loveVersion >= semver'0.9.0' then
|
||||||
|
bin = prefix..arch..".zip"
|
||||||
|
dir = prefix..arch.."/"
|
||||||
|
else
|
||||||
|
if arch == 32 then
|
||||||
|
bin = prefix.."-x86.zip"
|
||||||
|
dir = prefix.."-x86/"
|
||||||
|
elseif arch == 64 then
|
||||||
|
bin = prefix.."-x64.zip"
|
||||||
|
dir = prefix.."-x64/"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local url = "https://bitbucket.org/rude/love/downloads/"..bin
|
||||||
|
local cache = utils.cache.."/"..bin
|
||||||
|
|
||||||
|
-- Can't cache the archive because luarocks functions use a HEAD request to
|
||||||
|
-- Amazon AWS which will answer a 403.
|
||||||
|
-- assert(fs.download(url, cache, true))
|
||||||
|
if not fs.exists(cache) then
|
||||||
|
assert(fs.download(url, cache))
|
||||||
|
end
|
||||||
|
|
||||||
|
fs.delete(bin)
|
||||||
|
assert(fs.copy(cache, bin))
|
||||||
|
|
||||||
|
local gameHandle = assert(io.open(script.loveFile, "rb"))
|
||||||
|
local game = gameHandle:read("*a")
|
||||||
|
gameHandle:close()
|
||||||
|
|
||||||
|
-- local ar = assert(zip.open(bin, zip.OR(zip.CHECKCONS)))
|
||||||
|
local ar = zip.open(bin)
|
||||||
|
|
||||||
|
local exeHandle = assert(ar:open(dir.."love.exe"))
|
||||||
|
local exe = assert(exeHandle:read(assert(ar:stat(dir.."love.exe")).size))
|
||||||
|
exeHandle:close()
|
||||||
|
|
||||||
|
ar:add(dir..project.package..".exe", "string", exe..game)
|
||||||
|
ar:delete(dir.."love.exe")
|
||||||
|
|
||||||
|
local stat
|
||||||
|
for i = 1, #ar do
|
||||||
|
stat = ar:stat(i)
|
||||||
|
if stat then
|
||||||
|
ar:rename(i, stat.name:gsub(
|
||||||
|
"^"..utils.lua.escape_string_regex(dir),
|
||||||
|
utils.lua.escape_string_regex(project.title).."-win"..arch.."/"))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
ar:close()
|
||||||
|
|
||||||
|
os.rename(bin, project.title.."-win"..arch..".zip")
|
||||||
|
end
|
||||||
|
|
||||||
|
function s.script(project)
|
||||||
|
local script = Script:new(project)
|
||||||
|
script:createLoveFile()
|
||||||
|
fs.change_dir(project.releaseDirectory)
|
||||||
|
release(script, project, 32)
|
||||||
|
if project.loveVersion >= semver'0.8.0' then
|
||||||
|
release(script, project, 64)
|
||||||
|
end
|
||||||
|
fs.pop_dir()
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
setmetatable(s, {
|
||||||
|
__call = function(_, project) return s.script(project) end,
|
||||||
|
})
|
||||||
|
|
||||||
|
return s
|
123
src/utils.lua
Normal file
123
src/utils.lua
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
--- Provides utility functions and constants.
|
||||||
|
-- @module utils
|
||||||
|
|
||||||
|
local cfg = require 'luarocks.cfg'
|
||||||
|
local fs = require 'luarocks.fs'
|
||||||
|
local semver = require 'semver'
|
||||||
|
|
||||||
|
local utils = {}
|
||||||
|
|
||||||
|
|
||||||
|
--[[ CACHE ]]--
|
||||||
|
|
||||||
|
--- Cache directory.
|
||||||
|
utils.cache = nil
|
||||||
|
|
||||||
|
do
|
||||||
|
local cache
|
||||||
|
if cfg.platforms.windows then
|
||||||
|
cache = os.getenv("APPDATA")
|
||||||
|
else
|
||||||
|
cache = os.getenv("HOME").."/.cache"
|
||||||
|
end
|
||||||
|
cache = fs.absolute_name(cache.."/love-release")
|
||||||
|
assert(fs.make_dir(cache))
|
||||||
|
utils.cache = cache
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--[[ LÖVE VERSION ]]--
|
||||||
|
|
||||||
|
utils.love = {}
|
||||||
|
|
||||||
|
--- All supported LÖVE versions.
|
||||||
|
-- @local
|
||||||
|
utils.love.versionTable = {
|
||||||
|
semver'0.10.0',
|
||||||
|
semver'0.9.2', semver'0.9.1', semver'0.9.0',
|
||||||
|
semver'0.8.0',
|
||||||
|
semver'0.7.2', semver'0.7.1', semver'0.7.0',
|
||||||
|
semver'0.6.2', semver'0.6.1', semver'0.6.0',
|
||||||
|
--[[
|
||||||
|
semver'0.5.0',
|
||||||
|
semver'0.4.0',
|
||||||
|
semver'0.3.2', semver'0.3.1', semver'0.3.0',
|
||||||
|
semver'0.2.1', semver'0.2.0',
|
||||||
|
semver'0.1.1',
|
||||||
|
--]]
|
||||||
|
}
|
||||||
|
|
||||||
|
--- Last script LÖVE version.
|
||||||
|
function utils.love.lastVersion()
|
||||||
|
return utils.love.versionTable[1]
|
||||||
|
end
|
||||||
|
|
||||||
|
--- First supported LÖVE version.
|
||||||
|
function utils.love.minVersion()
|
||||||
|
return utils.love.versionTable[#utils.love.versionTable]
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Checks if a LÖVE version exists and is supported.
|
||||||
|
-- @tparam semver version LÖVE version.
|
||||||
|
-- @treturn bool true is the version is supported.
|
||||||
|
function utils.love.isSupported(version)
|
||||||
|
if version >= utils.love.minVersion()
|
||||||
|
and version <= utils.love.lastVersion() then
|
||||||
|
for _, v in ipairs(utils.love.versionTable) do
|
||||||
|
if version == v then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[ LUA ]]--
|
||||||
|
|
||||||
|
utils.lua = {}
|
||||||
|
|
||||||
|
--- Compiles a file to LuaJIT bytecode.
|
||||||
|
-- @string file file path.
|
||||||
|
-- @treturn string bytecode.
|
||||||
|
function utils.lua.bytecode(file)
|
||||||
|
if package.loaded.jit then
|
||||||
|
return string.dump(assert(loadfile(file)), true)
|
||||||
|
else
|
||||||
|
local handle = io.popen('luajit -b '..file..' -')
|
||||||
|
local result = handle:read("*a")
|
||||||
|
handle:close()
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Escapes a string to use as a regex.
|
||||||
|
-- @string string to escape.
|
||||||
|
function utils.lua.escape_string_regex(string)
|
||||||
|
-- ^$()%.[]*+-?
|
||||||
|
return string:gsub('%%', '%%%%'):gsub('^%^', '%%^'):gsub('%$$', '%%$')
|
||||||
|
:gsub('%(', '%%('):gsub('%)', '%%)'):gsub('%.', '%%.')
|
||||||
|
:gsub('%[', '%%['):gsub('%]', '%%]'):gsub('%*', '%%*')
|
||||||
|
:gsub('%+', '%%+'):gsub('%-', '%%-'):gsub('%?', '%%?')
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--[[ IO ]]--
|
||||||
|
|
||||||
|
local stdout = io.output(io.stdout)
|
||||||
|
local stderr = io.output(io.stderr)
|
||||||
|
utils.io = {}
|
||||||
|
|
||||||
|
--- Prints a message to stdout.
|
||||||
|
-- @string string the message.
|
||||||
|
function utils.io.out(string)
|
||||||
|
stdout:write(string)
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Prints a message to stderr.
|
||||||
|
-- @string string the message.
|
||||||
|
function utils.io.err(string)
|
||||||
|
stderr:write(string)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
return utils
|
Reference in New Issue
Block a user