diff options
| author | ruki <[email protected]> | 2017-08-14 11:27:19 +0800 |
|---|---|---|
| committer | ruki <[email protected]> | 2017-08-14 11:29:30 +0800 |
| commit | dba45d143d8aff047da82cbe1a881056e6e4bc00 (patch) | |
| tree | 7b80d5de264c17b538a7c9d0fbb234ded39ac683 /xmake/core/package/package.lua | |
| parent | 34706ba053dda9dd86902cacf42a6c1878c85234 (diff) | |
merge repo and require codes
Diffstat (limited to 'xmake/core/package/package.lua')
| -rw-r--r-- | xmake/core/package/package.lua | 419 |
1 files changed, 419 insertions, 0 deletions
diff --git a/xmake/core/package/package.lua b/xmake/core/package/package.lua new file mode 100644 index 000000000..e5ca87b84 --- /dev/null +++ b/xmake/core/package/package.lua @@ -0,0 +1,419 @@ +--!The Make-like Build Utility based on Lua +-- +-- Licensed to the Apache Software Foundation (ASF) under one +-- or more contributor license agreements. See the NOTICE file +-- distributed with this work for additional information +-- regarding copyright ownership. The ASF licenses this file +-- to you under the Apache License, Version 2.0 (the +-- "License"); you may not use this file except in compliance +-- with the License. You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific package governing permissions and +-- limitations under the License. +-- +-- Copyright (C) 2015 - 2017, TBOOX Open Source Group. +-- +-- @author ruki +-- @file package.lua +-- + +-- define module +local package = package or {} +local _instance = _instance or {} + +-- load modules +local os = require("base/os") +local io = require("base/io") +local path = require("base/path") +local utils = require("base/utils") +local table = require("base/table") +local filter = require("base/filter") +local global = require("base/global") +local interpreter = require("base/interpreter") +local sandbox = require("sandbox/sandbox") +local config = require("project/config") +local project = require("project/project") +local platform = require("platform/platform") + +-- new an instance +function _instance.new(name, info, rootdir) + + -- new an instance + local instance = table.inherit(_instance) + + -- init instance + instance._NAME = name + instance._INFO = info + instance._ROOTDIR = rootdir + instance._FILTER = filter.new() + + -- register filter handler + instance._FILTER:register("package", function (variable) + + -- init maps + local maps = + { + version = instance:version_str() + } + + -- map it + return maps[variable] + end) + + -- ok + return instance +end + +-- get the package configure +function _instance:get(name) + + -- the info + local info = self._INFO + + -- get if from info first + local value = info[name] + if value ~= nil then + return value + end +end + +-- get the package name +function _instance:name() + return self._NAME +end + +-- get the package filter +function _instance:filter() + return self._FILTER +end + +-- get urls +function _instance:urls() + return self._URLS or table.wrap(self:get("urls")) +end + +-- get urls +function _instance:urls_set(urls) + self._URLS = urls +end + +-- get sha256 +function _instance:sha256() + + -- get it from cache first + if self._SHA256 then + return self._SHA256 + end + + -- find sha256 + local version = self:version() + local sha256s = table.wrap(self:get("sha256s")) + local versions = table.wrap(self:get("versions")) + if version then + for idx, ver in ipairs(versions) do + if ver == version then + self._SHA256 = sha256s[idx] + break + end + end + end + + -- get it + return self._SHA256 +end + +-- is global package? +function _instance:global() + return self._ISGLOBAL +end + +-- is optional package? +function _instance:optional() + + -- optional? + return self._REQUIREINFO.mode == "optional" +end + +-- get the cached directory of this package +function _instance:cachedir() + return path.join(package.cachedir(), self:name() .. "-" .. (self:version_str() or "group")) +end + +-- get the installed directory of this package +function _instance:installdir() + return path.join(package.installdir(self:global()), self:name() .. "-" .. (self:version_str() or "group")) +end + +-- get the version +function _instance:version() + + -- get it + return self._VERSION or {} +end + +-- get the version string +function _instance:version_str() + + -- get it + return self:version().raw or self:version().version +end + +-- the verson from tags, branches or versions? +function _instance:version_from(...) + + -- from source? + for _, source in ipairs({...}) do + return self:version().source == source + end +end + +-- set the version +function _instance:version_set(version, source) + + -- init package version + if type(version) == "string" then + version = {version = version, source = source} + else + version.source = source + end + + -- save version + self._VERSION = version +end + +-- get the require info +function _instance:requireinfo() + return self._REQUIREINFO +end + +-- set the require info +function _instance:requireinfo_set(requireinfo) + self._REQUIREINFO = requireinfo +end + +-- get xxx_script +function _instance:script(name, generic) + + -- get script + local script = self:get(name) + if type(script) == "function" then + return script + elseif type(script) == "table" then + + -- match script for special plat and arch + local plat = (config.get("plat") or "") + local pattern = plat .. '|' .. (config.get("arch") or "") + for _pattern, _script in pairs(script) do + if not _pattern:startswith("__") and pattern:find('^' .. _pattern .. '$') then + return _script + end + end + + -- match script for special plat + for _pattern, _script in pairs(script) do + if not _pattern:startswith("__") and plat:find('^' .. _pattern .. '$') then + return _script + end + end + + -- get generic script + return script["__generic__"] or generic + end + + -- only generic script + return generic +end + +-- the interpreter +function package._interpreter() + + -- the interpreter has been initialized? return it directly + if package._INTERPRETER then + return package._INTERPRETER + end + + -- init interpreter + local interp = interpreter.new() + assert(interp) + + -- define apis + interp:api_define(package.apis()) + + -- save interpreter + package._INTERPRETER = interp + + -- ok? + return interp +end + +-- get package apis +function package.apis() + + return + { + values = + { + -- package.set_xxx + "package.set_urls" + , "package.set_sha256s" + , "package.set_versions" + , "package.set_homepage" + , "package.set_description" + -- package.add_xxx + , "package.add_requires" + } + , script = + { + -- package.on_xxx + "package.on_build" + , "package.on_install" + , "package.on_test" + + -- package.before_xxx + , "package.before_build" + , "package.before_install" + , "package.before_test" + + -- package.before_xxx + , "package.after_build" + , "package.after_install" + , "package.after_test" + } + } +end + +-- get install directory +function package.installdir(is_global) + + -- get directory + if is_global then + return path.join(global.directory(), "packages") + else + return path.join(config.directory(), "packages") + end +end + +-- the cache directory +function package.cachedir() + return path.join(global.directory(), "cache", "packages") +end + +-- load the package from the package url +function package.load_from_url(packagename, packageurl) + + -- make a temporary package file + local packagefile = os.tmpfile() .. ".lua" + + -- make package description + local packagedata = string.format([[ + package("%s") + set_urls("%s") + ]], packagename, packageurl) + + -- write a temporary package description to file + local ok, errors = io.writefile(packagefile, packagedata) + if not ok then + return nil, errors + end + + -- load package instance + local instance, errors = package.load_from_repository(packagename, false, nil, packagefile) + + -- remove the package file + os.rm(packagefile) + + -- ok? + return instance, errors +end + +-- load the package from the project file +function package.load_from_project(packagename) + + -- get it directly from cache first + package._PACKAGES = package._PACKAGES or {} + if package._PACKAGES[packagename] then + return package._PACKAGES[packagename] + end + + -- load packages (with cache) + local packages, errors = project.packages() + if not packages then + return nil, errors + end + + -- get interpreter + local interp = errors or package._interpreter() + + -- not found? + if not packages[packagename] then + return + end + + -- new an instance + local instance, errors = _instance.new(packagename, packages[packagename], interp:rootdir()) + if not instance then + return nil, errors + end + + -- mark as loval package + instance._ISGLOBAL = false + + -- save instance to the cache + package._PACKAGES[packagename] = instance + + -- ok + return instance +end + +-- load the package from the package directory or package description file +function package.load_from_repository(packagename, is_global, packagedir, packagefile) + + -- get it directly from cache first + package._PACKAGES = package._PACKAGES or {} + if package._PACKAGES[packagename] then + return package._PACKAGES[packagename] + end + + -- find the package script path + local scriptpath = packagefile + if not packagefile and packagedir then + scriptpath = path.join(packagedir, "xmake.lua") + end + if not scriptpath or not os.isfile(scriptpath) then + return nil, string.format("the package %s not found!", packagename) + end + + -- load package and disable filter, we will process filter after a while + local results, errors = package._interpreter():load(scriptpath, "package", true, false) + if not results and os.isfile(scriptpath) then + return nil, errors + end + + -- check the package name + if not results[packagename] then + return nil, string.format("the package %s not found!", name) + end + + -- new an instance + local instance, errors = _instance.new(packagename, results[packagename], package._interpreter():rootdir()) + if not instance then + return nil, errors + end + + -- mark as global package? + instance._ISGLOBAL = is_global + + -- save instance to the cache + package._PACKAGES[packagename] = instance + + -- ok + return instance +end + +-- return module +return package |
