Add command-line interface

This commit is contained in:
Antonin Décimo
2016-01-21 13:09:28 +01:00
parent 873934e526
commit d639fcbf6d
7 changed files with 229 additions and 25 deletions

View File

@@ -9,10 +9,49 @@ 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 creates only one LÖVE file per 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.
### Usage
```
Usage: love-release [-D] [-M] [-a <author>] [-b] [-d <desc>]
[-e <email>] [-l <love>] [-p <package>] [-t <title>] [-u <url>]
[--uti <uti>] [-v <v>] [--version] [-h] [<release>] [<source>]
[-W [32|64]]
Makes LÖVE games releases easier !
Arguments:
release Project release directory.
source Project source directory.
Options:
-D Debian package.
-M MacOS X application.
-W [32|64] Windows executable.
-a <author>, --author <author>
Author full name.
-b Compile new or updated files to LuaJIT bytecode.
-d <desc>, --desc <desc>
Project description.
-e <email>, --email <email>
Author email.
-l <love>, --love <love>
LÖVE version to use.
-p <package>, --package <package>
Package and command name.
-t <title>, --title <title>
Project title.
-u <url>, --url <url> Project homepage url.
--uti <uti> Project Uniform Type Identifier.
-v <v> Project version.
--version Show love-release version and exit.
-h, --help Show this help message and exit.
For more info, see https://github.com/MisterDA/love-release
```
### 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.
@@ -46,6 +85,7 @@ love-release is only installable through LuaRocks and highly depends on LuaRocks
#### Optional
- `love` can be used to determine your system LÖVE version.
- `fakeroot` and `dpkg-deb` are required to create Debian packages.
- [LuaJIT][luajit] can be used to compile your sources, either with `luarocks-luajit` or if `luajit` is installed.
### Install
@@ -77,6 +117,7 @@ Every bug report or feature request is gladly welcome !
[libzip]: http://www.nih.at/libzip/
[love]: https://www.love2d.org/
[lua]: http://www.lua.org/
[luajit]: http://luajit.org/
[luarocks]: https://luarocks.org/
[lua-zip]: https://github.com/brimworks/lua-zip
[loadconf]: https://github.com/Alloyed/loadconf

View File

@@ -14,6 +14,7 @@ It automates LÖVE Game Distribution.
homepage = "https://github.com/MisterDA/love-release",
}
dependencies = {
"argparse",
"loadconf",
"lua ~> 5.1",
"luafilesystem",
@@ -28,6 +29,7 @@ build = {
["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.args"] = "src/pipes/args.lua",
["love-release.pipes.conf"] = "src/pipes/conf.lua",
["love-release.pipes.env"] = "src/pipes/env.lua",
["love-release.project"] = "src/project.lua",

View File

@@ -1,20 +1,13 @@
--- love-release main.
-- @script love-release
local Args = require 'love-release.pipes.args'
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))
local args = Args:new()
args(conf(env(args(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)
return 0

126
src/pipes/args.lua Normal file
View File

@@ -0,0 +1,126 @@
--- Gather informations from the CLI
-- @module args
-- @usage args(project)
local argparse = require 'argparse'
local class = require 'middleclass'
local utils = require 'love-release.utils'
local Args = class('Args')
Args.pre = true
Args.args = nil
function Args:initialize()
self.pre = Args.pre
local parser = argparse()
:name "love-release"
:description "Makes LÖVE games releases easier !"
:epilog "For more info, see https://github.com/MisterDA/love-release"
parser:argument("release", "Project release directory.")
:args "?"
parser:argument("source", "Project source directory.")
:args "?"
parser:flag("-D", "Debian package.")
:target "debian"
parser:flag("-M", "MacOS X application.")
:target "macosx"
parser:option("-W", "Windows executable.")
:target "windows"
:args "0-1"
:count "0-2"
:argname "32|64"
parser:option("-a --author", "Author full name.")
parser:flag("-b", "Compile new or updated files to LuaJIT bytecode.")
:target("compile")
parser:option("-d --desc", "Project description.")
parser:option("-e --email", "Author email.")
parser:option("-l --love", "LÖVE version to use.")
:target("loveVersion")
parser:option("-p --package", "Package and command name.")
parser:option("-t --title", "Project title.")
parser:option("-u --url", "Project homepage url.")
parser:option("--uti", "Project Uniform Type Identifier.")
parser:option("-v", "Project version.")
:target("version")
parser:flag("--version", "Show love-release version and exit.")
:target("love_release")
self.args = parser:parse()
end
function Args:__call(project)
local out = utils.io.out
local args = self.args
if self.pre then
if args.source then project:setProjectDirectory(args.source) end
if args.release then project:setReleaseDirectory(args.release) end
if args.love_release then
local show = require 'luarocks.show'
local _, version = show.pick_installed_rock("love-release")
out("love-release "..version.."\n")
os.exit(0)
end
self.pre = false
return project
end
if args.author then project:setAuthor(args.author) end
if args.compile then project:setCompile(true) end
if args.desc then project:setDescription(args.desc) end
if args.email then project:setEmail(args.email) end
if args.loveVersion then
assert(utils.love.isSupported(args.loveVersion),
"ARGS: "..args.loveVersion.." is not supported.\n")
project:setLoveVersion(args.loveVersion)
end
if args.package then project:setPackage(args.package) end
if args.title then project:setTitle(args.title) end
if args.url then project:setHomepage(args.url) end
if args.uti then project:setIdentifier(args.uti) end
if args.version then project:setVersion(args.version) end
if project.projectDirectory == project.releaseDirectory then
project:setReleaseDirectory(project.releaseDirectory.."/releases")
end
print(project)
local script
script = require 'love-release.scripts.love'
script(project)
if args.macosx then
script = require 'love-release.scripts.macosx'
script(project)
end
if #args.windows > 0 then
local win = args.windows
local win32 = win[1][1] == "32" or (win[2] and win[2][1] == "32")
local win64 = win[1][1] == "64" or (win[2] and win[2][1] == "64")
if not win32 and not win64 then
win32, win64 = true, true
end
script = require 'love-release.scripts.windows'
if win32 then script(project, 32) end
if win64 then script(project, 64) end
end
if args.debian then
script = require 'love-release.scripts.debian'
script(project)
end
return project
end
return Args

View File

@@ -43,13 +43,16 @@ Project.projectDirectory = nil
--- Project release directory, where to store the releases.
Project.releaseDirectory = nil
--- True is the files should be precompiled to LuaJIT bytecode.
Project.compile = false
Project._fileTree = nil
Project._fileList = nil
function Project:initialize()
local defaultDirectory = fs.current_dir()
self:setProjectDirectory(defaultDirectory)
self:setReleaseDirectory(defaultDirectory.."/releases")
self:setReleaseDirectory(defaultDirectory)
end
--- Recursive function used to build the tree.
@@ -115,17 +118,29 @@ 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.
-- For now it works on the file list and only exludes the release directory if
-- it is within the project directory.
function Project:excludeFiles()
local dir = self.releaseDirectory:gsub(
local dir, rm_dir = self.releaseDirectory:gsub(
"^"..utils.lua.escape_string_regex(self.projectDirectory).."/",
"")
if dir then
if rm_dir > 0 then
rm_dir = true
dir = "^"..dir
else
rm_dir = false
end
if rm_dir then
local rm = false
local file
local n = #self._fileList
for i = 1, n do
if self._fileList[i]:find("^"..dir) then
file = self._fileList[i]
if rm_dir then if file:find(dir) then rm = true end end
if rm then
self._fileList[i] = nil
rm = false
end
end
end
@@ -168,6 +183,7 @@ function Project:__tostring()
' description = '..escape(self.description)..',\n'..
' homepage = '..escape(self.homepage)..',\n'..
' identifier = '..escape(self.identifier)..',\n'..
' compile = '..escape(self.compile)..',\n'..
' projectDirectory = '..escape(self.projectDirectory)..',\n'..
' releaseDirectory = '..escape(self.releaseDirectory)..',\n'..
'}'
@@ -268,5 +284,20 @@ function Project:setReleaseDirectory(directory)
return self
end
--- Sets if Lua files should be precompiled to LuaJIT bytecode. By default they
-- are not compiled.
-- @bool value wether the files should be compiled or not.
-- @treturn project self
function Project:setCompile(value)
if value then
if package.loaded.jit then
self.compile = true
else
assert(fs.is_tool_available("luajit", "LuaJIT", "-v"))
self.compile = true
end
end
end
return Project

View File

@@ -59,17 +59,26 @@ function Script:createLoveFile()
utils.io.out("Add "..file.."\n")
if attributes.mode == "directory" then
ar:add_dir(file)
else
if self.project.compile then
ar:add(file, "string", utils.lua.bytecode(file))
else
ar:add(file, "file", file)
end
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")
if self.project.compile then
ar:replace(assert(ar:name_locate(file)), "string",
utils.lua.bytecode(file))
else
ar:replace(assert(ar:name_locate(file)), "file", file)
end
end
end
end
for i = 1, #ar do
local file = ar:stat(i).name

View File

@@ -68,12 +68,14 @@ local function release(script, project, arch)
os.rename(bin, project.title.."-win"..arch..".zip")
end
function s.script(project)
function s.script(project, arch)
local script = Script:new(project)
script:createLoveFile()
fs.change_dir(project.releaseDirectory)
if arch == 32 then
release(script, project, 32)
if project.loveVersion >= semver'0.8.0' then
end
if arch == 64 and project.loveVersion >= semver'0.8.0' then
release(script, project, 64)
end
fs.pop_dir()
@@ -81,7 +83,7 @@ end
setmetatable(s, {
__call = function(_, project) return s.script(project) end,
__call = function(_, project, arch) return s.script(project, arch) end,
})
return s