diff options
-rw-r--r-- | .github/workflows/build.yml | 30 | ||||
-rw-r--r-- | README.md | 32 | ||||
-rwxr-xr-x | build.sh | 30 | ||||
-rw-r--r-- | lpm.c | 79 | ||||
-rw-r--r-- | lpm.lua | 8 |
5 files changed, 153 insertions, 26 deletions
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..2bfa14c --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,30 @@ +name: CI +on: { push: { branches: [master] } } +env: { VERSION: "0.1.0" } +jobs: + build: + runs-on: ubuntu-latest + defaults: { run: { shell: bash } } + steps: + - name: Checkout Code + uses: actions/checkout@v3 + with: + fetch-depth: 0 + - name: Clone Submodules + run: git submodule update --init --depth=1 + - name: Build Linux + run: | + ./build.sh -DLPM_VERSION='"'$VERSION-x86_64-linux-`git rev-parse --short HEAD`'"' && tar -czvf lpm-$VERSION-x86_64-linux.tar.gz lpm + - name: Package Debian/Ubuntu + env: { REV: "1", ARCH: "amd64", DESCRIPTION: "A plugin manager for the lite-xl text editor.", MAINTAINER: "Adam Harrison <adamdharrison@gmail.com>" } + run: | + export NAME=lite-xl_$VERSION-$REV""_$ARCH + mkdir -p $NAME/usr/bin $NAME/DEBIAN && cp lpm $NAME/usr/bin + printf "Package: lpm\nVersion: $VERSION\nArchitecture: $ARCH\nMaintainer: $MAINTAINER\nDescription: $DESCRIPTION\n" > $NAME/DEBIAN/control + dpkg-deb --build --root-owner-group $NAME + - name: Build Windows + run: | + sudo apt-get install mingw-w64 && ./build.sh clean && CC=x86_64-w64-mingw32-gcc AR=x86_64-w64-mingw32-gcc-ar WINDRES=x86_64-w64-mingw32-windres GIT2_CONFIGURE="-DCMAKE_FIND_ROOT_PATH_MODE_PROGRAM=NEVER -DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=ONLY -DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=ONLY -DBUILD_CLAR=OFF -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_SYSTEM_NAME=Windows -DDLLTOOL=x86_64-w64-mingw32-dlltool" SSL_CONFIGURE=mingw ./build.sh -DLPM_VERSION='"'$VERSION-x86_64-linux-`git rev-parse --short HEAD`'"' && zip -r lpm-$VERSION-x86_64-win32.zip lpm.exe + - name: Create Release + env: { GITHUB_TOKEN: "${{ github.token }}" } + run: gh release delete -y continuous || true; gh release create -t 'Continuous Release' continuous *.zip *.tar.gz *.deb @@ -6,6 +6,24 @@ Can be used by a package manager plugin that works from inside the editor and ca Releases forthcoming, should be available on Windows, Mac, Linux and FreeBSD. +## Quickstart + +If you have a C compiler, and `git`, and want to compile from scratch, you can do: + +``` +git clone git@github.com:adamharrison/lite-xl-plugin-manager.git --shallow-submodules \ + --recurse-submodules && cd lite-xl-plugin-manager && ./build.sh && ./lpm +```` + +If you want to build it quickly, and have the right modules installed, you can do: + +``` +./build.sh -lz -lssl -llibgit2 +``` + +CI is enabled on this repository, so you can grab Windows and Linux builds from the +`continuous` [release page](https://github.com/adamharrison/lite-xl-plugin-manager/releases/tag/continuous). + ## Usage ```sh @@ -17,3 +35,17 @@ lpm add https://github.com/lite-xl/lite-xl-plugins.git lpm rm https://github.com/lite-xl/lite-xl-plugins.git ``` + +## Building + +### Linux + +``` +./build.sh -DLPM_VERSION='"'$VERSION-x86_64-linux-`git rev-parse --short HEAD`'"' +``` + +### Linux to Windows + +``` +CC=x86_64-w64-mingw32-gcc AR=x86_64-w64-mingw32-gcc-ar WINDRES=x86_64-w64-mingw32-windres GIT2_CONFIGURE="-DCMAKE_FIND_ROOT_PATH_MODE_PROGRAM=NEVER -DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=ONLY -DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=ONLY -DBUILD_CLAR=OFF -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_SYSTEM_NAME=Windows -DDLLTOOL=x86_64-w64-mingw32-dlltool" SSL_CONFIGURE=mingw ./build.sh -DLPM_VERSION='"'$VERSION-x86_64-linux-`git rev-parse --short HEAD`'"' +``` @@ -8,26 +8,30 @@ SRCS="*.c" LDFLAGS="$LDFLAGS -lm -pthread -static-libgcc" -[[ "$@" == "clean" ]] && rm -rf lib/libgit2/build lib/zlib/build lib/openssl/build $BIN && exit 0 +[[ "$@" == "clean" ]] && rm -rf lib/libgit2/build lib/zlib/build lib/openssl/build lib/prefix $BIN *.exe && exit 0 +[[ $OSTYPE == 'msys'* || $CC == *'mingw'* ]] && SSL_CONFIGURE="mingw64" # Build supporting libraries, libgit2, libz, libssl (with libcrypto), libpcre -if [[ "$@" != *"-libgit2"* ]]; 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 && cmake .. -DBUILD_SHARED_LIBS=OFF -DUSE_SSH=OFF && $MAKE -j $JOBS && cd ../../ - LDFLAGS="$LDFLAGS -Llib/libgit2/build -l:libgit2.a" && CFLAGS="$CFLAGS -Ilib/libgit2/build/include/git2 -Ilib/libgit2/build/include -Ilib/libgit2/include" -fi if [[ "$@" != *"-lz"* ]]; then - [ ! -e "lib/zlib/build" ] && cd lib/zlib && mkdir build && ../configure && $MAKE -j $JOBS && cd ../../ - LDFLAGS="$LDFLAGS -Llib/libz/build -l:libz.a" && CFLAGS="$CFLAGS -Ilib/libz" + [ ! -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 -if [[ "$@" != *"-lssl"* ]]; then - [ ! -e "lib/openssl/build" ] && cd lib/openssl && mkdir build && ../Configure && $MAKE -j $JOBS && cd ../../ - LDFLAGS="$LDFLAGS -Llib/libz/build -l:libssl.a -l:libcrypto.a" && CFLAGS="$CFLAGS -Ilib/libz" +if [[ "$@" != *"-lssl"* && "$@" != *"-lcrypto"* ]]; then + [ ! -e "lib/openssl/build" ] && cd lib/openssl && mkdir build && cd build && ../Configure --prefix=`pwd`/../../prefix $SSL_CONFIGURE && $MAKE -j $JOBS && $MAKE install && cd ../../../ && ln -sf lib/prefix/lib64/libcrypto.a lib/prefix/lib/libcyrpto.a + 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 [[ "$@" != *"-llua"* ]] && CFLAGS="$CFLAGS -Ilib/lua -DMAKE_LIB=1" && SRCS="$SRCS lib/lua/onelua.c" # Build the pre-packaged lua file into the executbale. -echo "const char* luafile = " > lpm.lua.c && cat lpm.lua | sed 's/\\/\\\\/g' | sed 's/"/\\"/g' | sed 's/^/"/' | sed 's/$/\\n"/' >> lpm.lua.c && echo ";" >> lpm.lua.c +xxd -i lpm.lua > lpm.lua.c + +[[ $OSTYPE != 'msys'* && $CC != *'mingw'* && $CC != "emcc" ]] && LDFLAGS=" $LDFLAGS -ldl -pthread -lz" +[[ $OSTYPE == 'msys'* || $CC == *'mingw'* ]] && LDFLAGS="$LDFLAGS -lws2_32 -lz -lwinhttp -lole32 -lcrypt32 -lrpcrt4" [[ "$@" != *" -g "* || "$@" != *" -O"* ]] && CFLAGS="$CFLAGS -O3" && LDFLAGS="$LDFLAGS -s" -$CC $CFLAGS $SRCS $@ -o lpm $LDFLAGS -ldl -l:libpcre.a +$CC $CFLAGS $SRCS $@ -o lpm $LDFLAGS @@ -61,6 +61,56 @@ static int lpm_hash(lua_State* L) { } /** BEGIN STOLEN LITE CODE **/ + +#if _WIN32 +#define UTFCONV_ERROR_INVALID_CONVERSION "Input contains invalid byte sequences." +static LPWSTR utfconv_utf8towc(const char *str) { + LPWSTR output; + int len; + + // len includes \0 + len = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0); + if (len == 0) + return NULL; + + output = (LPWSTR) malloc(sizeof(WCHAR) * len); + if (output == NULL) + return NULL; + + len = MultiByteToWideChar(CP_UTF8, 0, str, -1, output, len); + if (len == 0) { + free(output); + return NULL; + } + + return output; +} + +static char *utfconv_wctoutf8(LPCWSTR str) { + char *output; + int len; + + // len includes \0 + len = WideCharToMultiByte(CP_UTF8, 0, str, -1, NULL, 0, NULL, NULL); + if (len == 0) + return NULL; + + output = (char *) malloc(sizeof(char) * len); + if (output == NULL) + return NULL; + + len = WideCharToMultiByte(CP_UTF8, 0, str, -1, output, len, NULL, NULL); + if (len == 0) { + free(output); + return NULL; + } + + return output; +} +#endif + + + static int lpm_ls(lua_State *L) { const char *path = luaL_checkstring(L, 1); @@ -86,7 +136,7 @@ static int lpm_ls(lua_State *L) { free(wpath); if (find_handle == INVALID_HANDLE_VALUE) { lua_pushnil(L); - push_win32_error(L, GetLastError()); + lua_pushinteger(L, GetLastError()); return 2; } @@ -107,7 +157,7 @@ static int lpm_ls(lua_State *L) { if (GetLastError() != ERROR_NO_MORE_FILES) { lua_pushnil(L); - push_win32_error(L, GetLastError()); + lua_pushinteger(L, GetLastError()); FindClose(find_handle); return 2; } @@ -149,7 +199,7 @@ static int lpm_rmdir(lua_State *L) { lua_pushboolean(L, 1); } else { lua_pushboolean(L, 0); - push_win32_error(L, GetLastError()); + lua_pushinteger(L, GetLastError()); return 2; } #else @@ -354,18 +404,23 @@ int lpm_status(lua_State* L) { 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. + { "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. }; -extern const char* luafile; +#ifndef LPM_VERSION + #define LPM_VERSION "unknown" +#endif + +extern const char lpm_lua[]; +extern unsigned int lpm_lua_len; int main(int argc, char* argv[]) { git_libgit2_init(); lua_State* L = luaL_newstate(); @@ -376,6 +431,8 @@ int main(int argc, char* argv[]) { lua_pushstring(L, argv[i]); lua_rawseti(L, -2, i+1); } + lua_pushliteral(L, LPM_VERSION); + lua_setglobal(L, "VERSION"); lua_setglobal(L, "ARGV"); #if _WIN32 lua_pushliteral(L, "\\"); @@ -383,7 +440,7 @@ int main(int argc, char* argv[]) { lua_pushliteral(L, "/"); #endif lua_setglobal(L, "PATHSEP"); - if (luaL_loadstring(L, luafile)) { + 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; @@ -880,7 +880,11 @@ end local status = 0 xpcall(function() - local ARGS = parse_arguments(ARGV, { json = "flag", userdir = "string", cachedir = "string", verbose = "flag", quiet = "flag", version = "string", modversion = "string" }) + local ARGS = parse_arguments(ARGV, { json = "flag", userdir = "string", cachedir = "string", version = "flag", verbose = "flag", quiet = "flag", version = "string", modversion = "string" }) + if ARGS["version"] then + io.stdout:write(VERSION .. "\n") + os.exit(0) + end VERBOSE = ARGS["verbose"] or false JSON = ARGS["json"] or os.getenv("LPM_JSON") QUIET = ARGS["quiet"] or os.getenv("LPM_QUIET") @@ -946,7 +950,7 @@ xpcall(function() else io.stderr:write([[ Usage: lpm COMMAND [--json] [--userdir=directory] [--cachedir=directory] - [--verbose] [--version=2.1] [--modversion=3] [--quiet] + [--verbose] [--liteversion=2.1] [--modversion=3] [--quiet] [--version] LPM is a package manager for `lite-xl`, written in C (and packed-in lua). |