--- LuaDist console application -- Peter Kapec, Peter Drahos LuaDist Project, 2008 local dist = require "dist" local pe = require "dist.persist" local function help() print [[LuaDist 0.9 - Simple Lua Distribution and Deployment System Usage: luadist (depldir) [command] [package] (version) (variables) where [...] are required and (...) are optional: depldir - Optional path to the deployment directory LuaDist will operate on. command - Specifies the operation to be executed: help - Display detailed command usage. install - Installs package. remove - Removes package. pack - Packs package. search - Searches for package, empty package argument lists all available packages. list - Lists installed packages. info - Show details about installed package. manifest - Generates manifest for the repository directory specified by [dir]. make - Make package from local directory. package - Package name (case sensitive) or URL of dist file. version - Desired version constraints (optional). variables - CMake variables to be passed into the build process (optional). Example: installing luasocket > luadist install luasocket installing nanoki 1.10 to its own dir directory > luadist /nanoki install nanoki 1.10 For additional help invoke >luadist help command ]] end -- Command-line globals local commands commands = { ["help"] = { help = [[Usage: luadist help (command) This will show detailed info on command usage. ]], run = function (_, command) if not command then help() return end if not commands[command] then print("LuaDist Error: Unknown command: " .. command) return 1 end print(commands[command].help) return 0 end }, ["install"] = { help = [[Usage: luadist (depldir) install [name|URL|path] (version) (variables) The install command can install the a package by its name with optional verstion string containing constraints that have to be satisfied. When version string is not specified, then the newest found package version is installed. If URL or path to a dist package or extracted package directory is specified instead of a name, it will be directly installed and version is ignored. The optional depldir path is used to specify deployment directory, by default packages install into LuaDist. Optional variables list can contain CMake defines using CMake's -D format and must be quoted. ]], run = function (depldir, package, version, variables) local ok, err = dist.installPackage(package, version, depldir, nil, variables) if not ok then print (err) return 1 end print("Installation of "..package.." succesfull.") if err then print(err) end return 0 end }, ["remove"] = { help = [[Usage: luadist (depldir) remove [name] The remove command will remove installed package by its name from the deployment directory depldir. When depldir is not specified, then the package will be removed from LuaDist. WARNING: LuaDist does not do any package dependency breakage tests on remove! ]], run = function (depldir, package) if not package then print("LuaDist Error: Specify package.") return 1 end local ok, err = dist.deletePackage(package, depldir) if not ok then print (err) return 1 end print("Removal of "..package.." succesfull.") return 0 end }, ["pack"] = { help = [[Usage: luadist (depldir) pack [name] (dest) The pack command will pack installed package identified by its name from the directory depldir. When depldir is not specified the package will be packed from LuaDist. The resulting dist file placed into the dest directory or when not specified current directory will be used. Dist files follow the folowing naming sheme when packed "package-version-architecture-type.dist" format (e.g. lua-5.1.4-Windows-x86.zip) ]], run = function (depldir, package, dest) if not package then print("LuaDist Error: Specify package!") return 1 end if not dist.getPackage(package, depldir) then print ("Package " .. package .. " not found.") return 1 end local ok, err = dist.packPackage(package, depldir, dest) if not ok then print ("Error packing package " .. package .. ".\n" .. err) return 1 end print("Packing package "..package.." done.") return 0 end }, ["search"] = { help = [[Usage: luadist search (name) (version) The search command will search standart package repositories for the package name and version. When name is not specified, then all packages will be printed. Search results are filtered and display only packages that can be installed for the platform LuaDist is running on. Matching of package names is partial so "luadist search log" will match e.g. lualogging, luasyslog etc. ]], run = function (_, package, version) local repos, err = dist.filterRepositories(nil, ".*"..(package or "")..".*", version) if not repos then print (err) return 1 end print"\nSearch results:\n===============\n" for repo, packages in pairs(repos) do print("Repository: ", repo) for package, versions in pairs(packages) do local sort = {} for version in pairs(versions) do table.insert(sort,version) end table.sort(sort, function(a,b) return dep.compareVersions(a,b) end) print("\t" .. package .. " - " ..table.concat(sort,", ")) end end return 0 end }, ["list"] = { help = [[Usage: luadist (depldir) list The list command will display a list of all packages instaled in the depldir directory. When depldir is not specified, then all packages installed in LuaDist will be displayed. ]], run = function (depldir) local packages,err = dist.getPackages(depldir) if not packages then print(err) return 1 end -- Sort list of installed packages table.sort(packages, function(a,b) return a.name < b.name end) if next(packages) then print"\nInstalled packages:\n==================\n" for _, package in pairs(packages) do print("\t" .. package.name .. " - " .. package.version) end else print("\nNo packages installed in : "..depldir.."\n") end return 0 end }, ["manifest"] = { help = [[Usage: luadist (dir) manifest The manifest command will create a dist.manifest file for the directory dir or current directory. ]], run = function (dir) local packages, err = dist.makeManifest(dir) if not packages then print(err) return 1 end local manif = io.open(dir.."/dist.manifest","w") if not manif then print("Could not create manifest.") return 1 end manif:write(pe.saveText(packages)) manif:close() print("Manifest successfuly created.") return 0 end }, ["make"] = { help = [[Usage: luadist (depldir) make (path) (variables) The make command will make and install a package into depldir from local path or current directory by default. This command is usefull for package developers and the following conditions must be fulfilled: The package directory must contain valid dist.info. Source packages must contain CMakeLists.txt in order to be built. Optional variables list can contain CMake defines using CMake's -D format and must be quoted. Example: >pwd /home/luadist/devel/luasocket-2.0.2 >luadist make ]], run = function (repo, package, version, variables) local ok, err = dist.makePackage(package, repo, variables) if not ok then print(err) return 1 end print("Make successful.") if err then print(err) end return 0 end }, ["info"] = { help = [[Usage: luadist (depldir) info [name] Info command will print information about the package identified by name from deployment directory depldir. When depldir is not specified LuaDist directory will be used. ]], run = function (depldir, package) if not package then print("LuaDist Error: Specify package!") return 1 end local info, err = dist.getPackage(package, depldir) if not info then print("Package " .. package .. " not found.") return 1 end print(info.name .. "-" .. info.version .. "-" .. info.arch .. "-" .. info.type .." - " .. (info.short or "")) print("\tDescription: " .. (info.full or "not-available")) print("\tAuthor: " .. (info.author or "unknown" )) print("\tMaintainer: " .. (info.maintainer or "unknown" )) print("\tHomepage: " .. (info.homepage or "none" )) print("\tLicense: " .. (info.license or "unknown" )) print("\tDependencies:") local deps = info.dependencies or {} for dep, constr in pairs(deps) do if type(constr)=="string" then print("\t\t" .. dep .. " " .. constr) end end for dep, constr in pairs(deps.external or {}) do if type(constr)=="string" then print("\t\t" .. dep .. " " .. constr .. " (External)") end end return 0 end } } if (...) then local n, repo, command, package, version, variables -- Process arguments if commands[arg[1]] then repo = dist.getRoot() command = arg[1] package = arg[2] if arg[3] and arg[3]:match("%-") then n=3 else version = arg[3] n=4 end elseif commands[arg[2]] then repo = arg[1] command = arg[2] package = arg[3] if arg[4] and arg[4]:match("%-D.-=.*") then n=4 else version = arg[4] n=5 end else print("Invalid command!\n") help() return 1 end -- Check for CMake variables. if table.getn(arg) >= n then for i = n,table.getn(arg) do local var, value = arg[i]:match("%-D(.-)=(.*)") if var then variables = variables or {} variables[var]=value end end end -- Run command if repo then repo = repo:gsub("\\","/") end if package then package = package:gsub("\\","/") end if version then version = version:gsub("\\","/") end local ok = commands[command].run( repo, package, version, variables ) return 0 else help() return 0 end