aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitmodules3
-rwxr-xr-xbuild.sh10
m---------lib/curl0
-rw-r--r--lpm.c86
-rw-r--r--lpm.lua47
5 files changed, 103 insertions, 43 deletions
diff --git a/.gitmodules b/.gitmodules
index 9f578cd..0ee8ee3 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -11,3 +11,6 @@
[submodule "lib/zlib"]
path = lib/zlib
url = https://github.com/madler/zlib.git
+[submodule "lib/curl"]
+ path = lib/curl
+ url = https://github.com/curl/curl.git
diff --git a/build.sh b/build.sh
index 5301236..f1b05d7 100755
--- a/build.sh
+++ b/build.sh
@@ -8,11 +8,12 @@
SRCS="*.c"
LDFLAGS="$LDFLAGS -lm -pthread -static-libgcc"
-[[ "$@" == "clean" ]] && rm -rf lib/libgit2/build lib/zlib/build lib/openssl/build lib/prefix $BIN *.exe && exit 0
+[[ "$@" == "clean" ]] && rm -rf lib/libgit2/build lib/zlib/build lib/openssl/build lib/curl/build lib/prefix $BIN *.exe && exit 0
[[ $OSTYPE == 'msys'* || $CC == *'mingw'* ]] && SSL_CONFIGURE="mingw64"
# Build supporting libraries, libgit2, libz, libssl (with libcrypto), libpcre
if [[ "$@" != *"-lz"* ]]; then
+ [ ! -e "lib/zlib" ] && echo "Make sure you've cloned submodules. (git submodule update --init --depth=1)" && exit -1
[ ! -e "lib/zlib/build" ] && cd lib/zlib && mkdir build && cd build && ../configure --prefix=`pwd`/../../prefix && $MAKE -j $JOBS && $MAKE install && cd ../../../
LDFLAGS="$LDFLAGS -Llib/libz/build -l:libz.a" && CFLAGS="$CFLAGS -Ilib/prefix/include" && LDFLAGS="$LDFLAGS -Llib/prefix/lib -Llib/prefix/lib64"
fi
@@ -21,16 +22,19 @@ if [[ "$@" != *"-lssl"* && "$@" != *"-lcrypto"* ]]; then
LDFLAGS="$LDFLAGS -Llib/libz/build" && CFLAGS="$CFLAGS -Ilib/prefix/include" && LDFLAGS="$LDFLAGS -Llib/prefix/lib -Llib/prefix/lib64 -l:libssl.a -l:libcrypto.a"
fi
if [[ "$@" != *"-lgit2"* ]]; then
- [ ! -e "lib/libgit2/include" ] && echo "Make sure you've cloned submodules. (git submodule update --init --depth=1)" && exit -1
[ ! -e "lib/libgit2/build" ] && cd lib/libgit2 && mkdir build && cd build && cmake .. $GIT2_CONFIGURE -DCMAKE_PREFIX_PATH=`pwd`/../../prefix -DCMAKE_INSTALL_PREFIX=`pwd`/../../prefix -DOPENSSL_ROOT_DIR=`pwd`/../../prefix -DBUILD_SHARED_LIBS=OFF -DBUILD_TESTS=OFF -DBUILD_CLI=OFF -DREGEX_BACKEND=builtin -DUSE_SSH=OFF && $MAKE -j $JOBS && $MAKE install && cd ../../../
LDFLAGS="-Llib/libgit2/build -l:libgit2.a $LDFLAGS" && CFLAGS="$CFLAGS -Ilib/prefix/include" && LDFLAGS="$LDFLAGS -Llib/prefix/lib -Llib/prefix/lib64"
fi
+if [[ "$@" != *"-lcurl"* ]]; then
+ [ ! -e "lib/curl/build" ] && cd lib/curl && mkdir build && cd build && cmake .. $CURL_CONFIGURE -DCMAKE_INSTALL_PREFIX=`pwd`/../../prefix -DENABLE_UNICODE=OFF -DBUILD_CURL_EXE=OFF -DCURL_USE_LIBSSH2=OFF -DOPENSSL_ROOT_DIR=`pwd`/../../prefix -DBUILD_SHARED_LIBS=OFF && $MAKE -j $JOBS && $MAKE install && cd ../../../
+ LDFLAGS="-Llib/curl/build -l:libcurl.a $LDFLAGS" && CFLAGS="$CFLAGS -Ilib/prefix/include -DCURL_STATICLIB" && LDFLAGS="$LDFLAGS -Llib/prefix/lib"
+fi
[[ "$@" != *"-llua"* ]] && CFLAGS="$CFLAGS -Ilib/lua -DMAKE_LIB=1" && SRCS="$SRCS lib/lua/onelua.c"
# Build the pre-packaged lua file into the executbale.
xxd -i lpm.lua > lpm.lua.c
-[[ $OSTYPE != 'msys'* && $CC != *'mingw'* && $CC != "emcc" ]] && LDFLAGS=" $LDFLAGS -ldl -pthread -lz"
+[[ $OSTYPE != 'msys'* && $CC != *'mingw'* && $CC != "emcc" ]] && LDFLAGS=" $LDFLAGS -ldl -pthread -l:libidn2.a -l:libunistring.a"
[[ $OSTYPE == 'msys'* || $CC == *'mingw'* ]] && LDFLAGS="$LDFLAGS -lws2_32 -lz -lwinhttp -lole32 -lcrypt32 -lrpcrt4"
[[ "$@" != *" -g "* || "$@" != *" -O"* ]] && CFLAGS="$CFLAGS -O3" && LDFLAGS="$LDFLAGS -s"
diff --git a/lib/curl b/lib/curl
new file mode 160000
+Subproject 2ca0530a4d4bd1e1ccb9c876e954d8dc9a87da4
diff --git a/lpm.c b/lpm.c
index 8538923..11e1373 100644
--- a/lpm.c
+++ b/lpm.c
@@ -11,6 +11,8 @@
#include <sys/stat.h>
#include <git2.h>
+#include <openssl/sha.h>
+#include <curl/curl.h>
#ifdef _WIN32
#include <direct.h>
@@ -18,26 +20,18 @@
#include <fileapi.h>
#endif
-/* 64bit fnv-1a hash */
-typedef unsigned long long hash_t;
static char hexDigits[] = "0123456789abcdef";
-#define FNV_64_PRIME ((hash_t)0x100000001b3ULL)
static int lpm_hash(lua_State* L) {
- hash_t hval = 0;
size_t len;
const char* data = luaL_checklstring(L, 1, &len);
- const unsigned char *bp = (unsigned char*)data;
- const unsigned char *be = data + len;
- while (bp < be) {
- hval *= FNV_64_PRIME;
- hval ^= (unsigned long long)*bp++;
- }
- char buffer[16];
+ unsigned char buffer[SHA256_DIGEST_LENGTH];
+ char hexBuffer[SHA256_DIGEST_LENGTH * 2];
+ SHA256(data, len, buffer);
for (size_t i = 0; i < len; ++i) {
- buffer[i*2+0] = hexDigits[data[i] >> 4];
- buffer[i*2+1] = hexDigits[data[i] & 0xF];
+ hexBuffer[i*2+0] = hexDigits[buffer[i] >> 4];
+ hexBuffer[i*2+1] = hexDigits[buffer[i] & 0xF];
}
- lua_pushlstring(L, buffer, 16);
+ lua_pushlstring(L, buffer, SHA256_DIGEST_LENGTH * 2);
return 1;
}
@@ -310,7 +304,7 @@ static git_commit* git_retrieve_commit(git_repository* repository, const char* c
}
-int lpm_reset(lua_State* L) {
+static int lpm_reset(lua_State* L) {
git_repository* repository = luaL_checkgitrepo(L, 1);
const char* commit_name = luaL_checkstring(L, 2);
const char* type = luaL_checkstring(L, 3);
@@ -333,7 +327,7 @@ int lpm_reset(lua_State* L) {
}
-int lpm_init(lua_State* L) {
+static int lpm_init(lua_State* L) {
const char* path = luaL_checkstring(L, 1);
const char* url = luaL_checkstring(L, 2);
git_repository* repository;
@@ -350,7 +344,7 @@ int lpm_init(lua_State* L) {
}
-int lpm_fetch(lua_State* L) {
+static int lpm_fetch(lua_State* L) {
git_repository* repository = luaL_checkgitrepo(L, 1);
git_remote* remote;
if (git_remote_lookup(&remote, repository, "origin")) {
@@ -369,7 +363,7 @@ int lpm_fetch(lua_State* L) {
}
-int lpm_set_certs(lua_State* L) {
+static int lpm_set_certs(lua_State* L) {
const char* type = luaL_checkstring(L, 1);
const char* path = luaL_checkstring(L, 2);
if (strcmp(type, "dir") == 0)
@@ -379,8 +373,8 @@ int lpm_set_certs(lua_State* L) {
return 0;
}
-
-int lpm_status(lua_State* L) {
+static CURL *curl;
+static int lpm_status(lua_State* L) {
const char* path = luaL_checkstring(L, 1);
git_repository* repository;
if (git_repository_open(&repository, path))
@@ -395,19 +389,45 @@ int lpm_status(lua_State* L) {
}
+static size_t lpm_curl_write_callback(char *ptr, size_t size, size_t nmemb, void *BL) {
+ luaL_Buffer* B = BL;
+ luaL_addlstring(B, ptr, size*nmemb);
+ return size*nmemb;
+}
+
+
+static int lpm_get(lua_State* L) {
+ const char* url = luaL_checkstring(L, 1);
+ curl_easy_reset(curl);
+ curl_easy_setopt(curl, CURLOPT_URL, url);
+ CURLcode res = curl_easy_perform(curl);
+ if (res != CURLE_OK)
+ return luaL_error(L, "curl error: %d", res);
+ luaL_Buffer B;
+ luaL_buffinit(L, &B);
+ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, lpm_curl_write_callback);
+ curl_easy_setopt(curl, CURLOPT_WRITEDATA, &B);
+ luaL_pushresult(&B);
+ lua_newtable(L);
+ return 2;
+}
+
+
static const luaL_Reg system_lib[] = {
- { "ls", lpm_ls }, // Returns an array of files.
- { "stat", lpm_stat }, // Returns info about a single file.
- { "mkdir", lpm_mkdir }, // Makes a directory.
- { "rmdir", lpm_rmdir }, // Removes a directory.
- { "hash", lpm_hash }, // Returns a hexhash.
- { "init", lpm_init }, // Initializes a git repository with the specified remote.
- { "fetch", lpm_fetch }, // Updates a git repository with the specified remote.
- { "reset", lpm_reset }, // Updates a git repository to the specified commit/hash/branch.
- { "status", lpm_status }, // Returns the git repository in question's current branch, if any, and commit hash.
+ { "ls", lpm_ls }, // Returns an array of files.
+ { "stat", lpm_stat }, // Returns info about a single file.
+ { "mkdir", lpm_mkdir }, // Makes a directory.
+ { "rmdir", lpm_rmdir }, // Removes a directory.
+ { "hash", lpm_hash }, // Returns a hex sha256 hash.
+ { "init", lpm_init }, // Initializes a git repository with the specified remote.
+ { "fetch", lpm_fetch }, // Updates a git repository with the specified remote.
+ { "reset", lpm_reset }, // Updates a git repository to the specified commit/hash/branch.
+ { "status", lpm_status }, // Returns the git repository in question's current branch, if any, and commit hash.
+ { "get", lpm_get }, // HTTP(s) GET request.
{ "set_certs", lpm_set_certs } // Returns the git repository in question's current branch, if any, and commit hash.
};
+
#ifndef LPM_VERSION
#define LPM_VERSION "unknown"
#endif
@@ -415,6 +435,9 @@ static const luaL_Reg system_lib[] = {
extern const char lpm_lua[];
extern unsigned int lpm_lua_len;
int main(int argc, char* argv[]) {
+ curl = curl_easy_init();
+ if (!curl)
+ return -1;
git_libgit2_init();
lua_State* L = luaL_newstate();
luaL_openlibs(L);
@@ -436,8 +459,8 @@ int main(int argc, char* argv[]) {
#endif
lua_setglobal(L, "PATHSEP");
lua_setglobal(L, "PLATFORM");
- if (luaL_loadbuffer(L, lpm_lua, lpm_lua_len, "lpm.lua")) {
- // if (luaL_loadfile(L, "lpm.lua")) {
+ // if (luaL_loadbuffer(L, lpm_lua, lpm_lua_len, "lpm.lua")) {
+ if (luaL_loadfile(L, "lpm.lua")) {
fprintf(stderr, "internal error when starting the application: %s\n", lua_tostring(L, -1));
return -1;
}
@@ -445,5 +468,6 @@ int main(int argc, char* argv[]) {
int status = lua_tointeger(L, -1);
lua_close(L);
git_libgit2_shutdown();
+ curl_easy_cleanup(curl);
return status;
}
diff --git a/lpm.lua b/lpm.lua
index 878006b..04ec189 100644
--- a/lpm.lua
+++ b/lpm.lua
@@ -619,7 +619,7 @@ function Repository:parse_manifest(already_pulling)
table.insert(remotes, repo)
table.insert(self.plugins, Plugin.new(self, metadata))
else
- log_warning("plugin " .. plugin.name .. " specifies remote as source, but ")
+ log_warning("plugin " .. metadata.name .. " specifies remote as source, but isn't a commit")
end
else
table.insert(self.plugins, Plugin.new(self, metadata))
@@ -649,10 +649,14 @@ function Repository:generate_manifest()
local plugins, plugin_map = {}, {}
if system.stat(path .. PATHSEP .. "README.md") then -- If there's a README, parse it for a table like in our primary repository.
for line in io.lines(path .. PATHSEP .. "README.md") do
- local _, _, name, path, description = line:find("^%s*%|%s*%[`(%w+)%??.-`%]%((.-)%).-%|%s*(.-)%s*%|%s*$")
+ local _, _, name, path, description = line:find("^%s*%|%s*%[`([%w_]+)%??.-`%]%((.-)%).-%|%s*(.-)%s*%|%s*$")
if name then
plugin_map[name] = { name = name, description = description }
- plugin_map[path:find("^http") and "remote" or "path"] = path
+ if path:find("^http") then
+ plugin_map[name].remote = path
+ else
+ plugin_map[name].path = path:gsub("%?.*$", "")
+ end
end
end
end
@@ -667,10 +671,18 @@ function Repository:generate_manifest()
local _, _, required_plugin = line:find("require [\"']plugins.([%w_]+)")
if required_plugin then if required_plugin ~= plugin.name then plugin.dependencies[required_plugin] = ">=1.0" end end
end
- if plugin_map[plugin.name] then plugin = common.merge(plugin, plugin_map[plugin.name]) end
+ if plugin_map[plugin.name] then
+ plugin = common.merge(plugin, plugin_map[plugin.name])
+ plugin_map[plugin.name].plugin = plugin
+ end
table.insert(plugins, plugin)
end
end
+ for k, v in pairs(plugin_map) do
+ if not v.plugin then
+ table.insert(plugins, common.merge({ dependencies = {}, mod_version = 3, version = "1.0", tags = {} }, v))
+ end
+ end
io.open(path .. PATHSEP .. "manifest.json", "wb"):write(json.encode({ plugins = plugins })):flush()
end
@@ -871,6 +883,18 @@ local function lpm_plugin_list()
end
end
+local function lpm_plugin_upgrade()
+ for i,repo in ipairs(repositories) do
+ if not repo.plugins then error("can't find plugins for repo " .. repo.remote .. ":" .. (repo.commit or repo.branch or "master")) end
+ for j,plugin in ipairs(repo.plugins) do
+ if plugin:is_installed() then
+ local compatibles = get_plugin(plugin.name, ">" .. plugin.version)
+ table.sort(compatibles, function(a, b) return compare_version(b.version, a.version) end)
+ compatibles[1]:install()
+ end
+ end
+ end
+end
local function lpm_purge()
log_action("Removed " .. CACHEDIR .. ".")
@@ -932,10 +956,12 @@ local function run_command(ARGS)
elseif ARGS[2] == "repo" and ARGS[3] == "list" then return lpm_repo_list()
elseif ARGS[2] == "plugin" and ARGS[3] == "install" then lpm_plugin_install(table.unpack(common.slice(ARGS, 4)))
elseif ARGS[2] == "plugin" and ARGS[3] == "uninstall" then lpm_plugin_uninstall(table.unpack(common.slice(ARGS, 4)))
- elseif ARGS[2] == "plugin" and ARGS[3] == "list" then return lpm_plugin_list()
+ elseif ARGS[2] == "plugin" and ARGS[3] == "list" then return lpm_plugin_list(table.unpack(common.slice(ARGS, 4)))
+ elseif ARGS[2] == "plugin" and ARGS[3] == "upgrade" then return lpm_plugin_upgrade(table.unpack(common.slice(ARGS, 4)))
+ elseif ARGS[2] == "upgrade" then return lpm_plugin_upgrade(table.unpack(common.slice(ARGS, 3)))
elseif ARGS[2] == "install" then lpm_plugin_install(table.unpack(common.slice(ARGS, 3)))
elseif ARGS[2] == "uninstall" then lpm_plugin_uninstall(table.unpack(common.slice(ARGS, 3)))
- elseif ARGS[2] == "list" then return lpm_plugin_list()
+ elseif ARGS[2] == "list" then return lpm_plugin_list(table.unpack(common.slice(ARGS, 3)))
elseif ARGS[2] == "purge" then lpm_purge()
else error("unknown command: " .. ARGS[2]) end
if JSON then
@@ -979,10 +1005,13 @@ It has the following commands:
lpm [repo] update [<repository remote>] Update all/the specified repositories.
[...<repository remote>]
lpm [plugin] install <plugin name>[:<version>] Install the specific plugins in question.
- [...<plugin name>:<version>]
+ [...<plugin name>:<version>] If the plugin is installed, upgrades it.
lpm [plugin] uninstall <plugin name> Uninstall the specific plugin.
[...<plugin name>]
- lpm [plugin] list List all known plugins.
+ lpm [plugin] list <repository remote> List all/associated plugins.
+ [...<repository remote>]
+ lpm [plugin] upgrade Upgrades all installed plugins to new version
+ if applicable.
lpm purge Completely purge all state for LPM.
lpm - Read these commands from stdin in an
interactive print-eval loop.
@@ -1027,7 +1056,7 @@ Flags have the following effects:
if not stat then error("can't find " .. ARGS["ssl_certs"]) end
system.set_certs(stat.type, ARGS["ssl_certs"])
elseif not os.getenv("SSL_CERT_DIR") and not os.getenv("SSL_CERT_FILE") then
- local paths = {
+ local paths = { -- https://serverfault.com/questions/62496/ssl-certificate-location-on-unix-linux#comment1155804_62500
"/etc/ssl/certs/ca-certificates.crt", -- Debian/Ubuntu/Gentoo etc.
"/etc/pki/tls/certs/ca-bundle.crt", -- Fedora/RHEL 6
"/etc/ssl/ca-bundle.pem", -- OpenSUSE