diff options
-rw-r--r-- | .github/workflows/build.yml | 51 | ||||
-rw-r--r-- | .github/workflows/release.yml | 57 | ||||
-rwxr-xr-x | build.sh | 24 | ||||
-rw-r--r-- | src/lpm.c | 85 | ||||
-rw-r--r-- | src/lpm.lua | 10 |
5 files changed, 133 insertions, 94 deletions
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index fc4c7e9..c04e12b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,7 +1,9 @@ name: CI on: - push: { branches: [master] } + push: { branches: ['!master'] } + pull_request: { branches: ['*'] } workflow_dispatch: + workflow_call: jobs: build: @@ -140,50 +142,3 @@ jobs: path: ${{ env.BIN }} name: ${{ env.BIN }} - create-release: - runs-on: ubuntu-latest - needs: [build, build-macos] - env: { GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" } - - steps: - - name: Checkout code - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: Set Environment Variables - run: | - echo VERSION=`git describe --tags --abbrev=0 --match "v*" | tail -c +2` >> $GITHUB_ENV - - - name: Download Artifacts - uses: actions/download-artifact@v4 - with: - pattern: lpm.* - path: artifacts - merge-multiple: true - - - name: Create Release(s) - run: | - perl -pe 'last if $_ =~ m/^\s*#/ && $_ !~ m/#\s*$ENV{VERSION}/' < CHANGELOG.md | tail -n +2 > NOTES.md - gh release delete -y continuous || true; - gh release create -t 'Continuous Release' -F NOTES.md continuous ./artifacts/* - if [[ `git tag --points-at HEAD v* | head -c 1` == "v" ]]; then - gh release delete -y v$VERSION || true; - gh release create -t v$VERSION -F NOTES.md v$VERSION ./artifacts/* - gh release delete -y latest || true; - gh release create -t latest -F NOTES.md latest ./artifacts/* - git branch -f latest HEAD - git tag -f latest - git push -f origin refs/heads/latest - git push -f origin refs/tags/latest - fi - git tag -f continuous - git push -f origin refs/tags/continuous - - - name: Discord Notification - env: { DISCORD_WEBHOOK: "${{ secrets.DISCORD_WEBHOOK }}" } - run: | - if [[ -n "$DISCORD_WEBHOOK" ]] && [[ `git tag --points-at HEAD v* | head -c 1` == "v" ]]; then - perl -e 'use JSON qw(encode_json from_json); $/ = undef; print encode_json({ content => "## Lite XL Plugin Manager $ENV{VERSION} has been released!\nhttps://github.com/lite-xl/lite-xl-plugin-manager/releases/tag/v$ENV{VERSION}\n@release:lpm\n### Changes in $ENV{VERSION}:\n" . <> })' < NOTES.md | - curl -H 'Content-Type:application/json' $DISCORD_WEBHOOK -X POST -d "$(</dev/stdin)" - fi diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..b34579e --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,57 @@ +name: Release +on: + push: { branches: [master] } + workflow_dispatch: + +jobs: + build-everything: + uses: ./.github/workflows/build.yml + secrets: inherit + + create-release: + runs-on: ubuntu-latest + needs: build-everything + env: { GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" } + + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Set Environment Variables + run: | + echo VERSION=`git describe --tags --abbrev=0 --match "v*" | tail -c +2` >> $GITHUB_ENV + + - name: Download Artifacts + uses: actions/download-artifact@v4 + with: + pattern: lpm.* + path: artifacts + merge-multiple: true + + - name: Create Release(s) + run: | + perl -pe 'last if $_ =~ m/^\s*#/ && $_ !~ m/#\s*$ENV{VERSION}/' < CHANGELOG.md | tail -n +2 > NOTES.md + gh release delete -y continuous || true; + gh release create -t 'Continuous Release' -F NOTES.md continuous ./artifacts/* + if [[ `git tag --points-at HEAD v* | head -c 1` == "v" ]]; then + gh release delete -y v$VERSION || true; + gh release create -t v$VERSION -F NOTES.md v$VERSION ./artifacts/* + gh release delete -y latest || true; + gh release create -t latest -F NOTES.md latest ./artifacts/* + git branch -f latest HEAD + git tag -f latest + git push -f origin refs/heads/latest + git push -f origin refs/tags/latest + fi + git tag -f continuous + git push -f origin refs/tags/continuous + + - name: Discord Notification + env: { DISCORD_WEBHOOK: "${{ secrets.DISCORD_WEBHOOK }}" } + run: | + if [[ -n "$DISCORD_WEBHOOK" ]] && [[ `git tag --points-at HEAD v* | head -c 1` == "v" ]]; then + perl -e 'use JSON qw(encode_json from_json); $/ = undef; print encode_json({ content => "## Lite XL Plugin Manager $ENV{VERSION} has been released!\nhttps://github.com/lite-xl/lite-xl-plugin-manager/releases/tag/v$ENV{VERSION}\n@release:lpm\n### Changes in $ENV{VERSION}:\n" . <> })' < NOTES.md | + curl -H 'Content-Type:application/json' $DISCORD_WEBHOOK -X POST -d "$(</dev/stdin)" + fi @@ -7,15 +7,21 @@ : ${BIN=lpm} : ${JOBS=4} -# The build options are available: -# clean Cleans the build directory. -# -g Compile with debug support. -# -l<library> Compiles against the shared system version of the specified library. -# -DLPM_NO_GIT Compiles without libgit2 support. -# -DLPM_NO_NETWORK Compiles without network support. -# -DLPM_NO_THREADS Compiles without threading support. -# -DLPM_VERSION Sets the specific version. -# -DLPM_STATIC Bundles lpm.lua into the binary executable. +# The non-exhaustive build options are available: +# clean Cleans the build directory. +# -g Compile with debug support. +# -l<library> Compiles against the shared system version of the specified library. +# -DLPM_NO_GIT Compiles without libgit2 support. +# -DLPM_NO_NETWORK Compiles without network support. +# -DLPM_NO_THREADS Compiles without threading support. +# -DLPM_NO_REMOTE_EXECUTABLE Compiles without the ability to download remote executables. +# -DLPM_STATIC Compiles lpm.lua into the binary executable. +# -DLPM_ARCH_TUPLE Specifies the arch tuple for this build. +# -DLPM_DEFAULT_REPOSITORY Specifies the default repository to download on init. +# -DLPM_DEFAULT_RELEASE Specifies the default release for lpm for `self-upgrade`. +# -DLPM_VERSION Specifies the lpm version. +# -DLPM_ARCH_PROCESSOR Manually specifies the processor archiecture. +# -DLPM_ARCH_PLATFORM Manually specifies the operating system. SRCS="src/*.c" COMPILE_FLAGS="$CFLAGS -I`pwd`/lib/prefix/include" # We specifically rename this and LDFLAGS, because exotic build environments export these to subprocesses. @@ -1,7 +1,10 @@ #ifdef _WIN32 - #include <direct.h> + // prevent windows.h from including winsock.h, which will allow us to include winsock2.h + #define WIN32_LEAN_AND_MEAN #include <windows.h> - #include <fileapi.h> + #include <direct.h> + #include <wincrypt.h> + #include <process.h> #else #ifndef LPM_NO_THRAEDS #include <pthread.h> @@ -80,7 +83,7 @@ typedef struct { typedef struct { #if _WIN32 - HANDLE mutex; + CRITICAL_SECTION mutex; #else pthread_mutex_t mutex; #endif @@ -90,7 +93,7 @@ static lpm_mutex_t* new_mutex() { lpm_mutex_t* mutex = malloc(sizeof(lpm_mutex_t)); #ifndef LPM_NO_THREADS #if _WIN32 - mutex->mutex = CreateMutex(NULL, FALSE, NULL); + InitializeCriticalSection(&mutex->mutex); #else pthread_mutex_init(&mutex->mutex, NULL); #endif @@ -101,7 +104,7 @@ static lpm_mutex_t* new_mutex() { static void free_mutex(lpm_mutex_t* mutex) { #ifndef LPM_NO_THREADS #if _WIN32 - CloseHandle(mutex->mutex); + DeleteCriticalSection(&mutex->mutex); #else pthread_mutex_destroy(&mutex->mutex); #endif @@ -112,7 +115,7 @@ static void free_mutex(lpm_mutex_t* mutex) { static void lock_mutex(lpm_mutex_t* mutex) { #ifndef LPM_NO_THREADS #if _WIN32 - WaitForSingleObject(mutex->mutex, INFINITE); + EnterCriticalSection(&mutex->mutex); #else pthread_mutex_lock(&mutex->mutex); #endif @@ -122,7 +125,7 @@ static void lock_mutex(lpm_mutex_t* mutex) { static void unlock_mutex(lpm_mutex_t* mutex) { #ifndef LPM_NO_THREADS #if _WIN32 - ReleaseMutex(mutex->mutex); + LeaveCriticalSection(&mutex->mutex); #else pthread_mutex_unlock(&mutex->mutex); #endif @@ -131,7 +134,7 @@ static void unlock_mutex(lpm_mutex_t* mutex) { #if _WIN32 -static DWORD windows_thread_callback(void* data) { +static WINAPI unsigned int windows_thread_callback(void* data) { lpm_thread_t* thread = data; thread->data = thread->func(thread->data); return 0; @@ -144,7 +147,7 @@ static lpm_thread_t* create_thread(void* (*func)(void*), void* data) { #if _WIN32 thread->func = func; thread->data = data; - thread->thread = CreateThread(NULL, 0, windows_thread_callback, thread, 0, NULL); + thread->thread = (HANDLE) _beginthreadex(NULL, 0, &windows_thread_callback, thread, 0, NULL); #else pthread_create(&thread->thread, NULL, func, data); #endif @@ -161,6 +164,8 @@ static void* join_thread(lpm_thread_t* thread) { #ifndef LPM_NO_THREADS #if _WIN32 WaitForSingleObject(thread->thread, INFINITE); + CloseHandle(thread->thread); + retval = thread->data; #else pthread_join(thread->thread, &retval); #endif @@ -399,7 +404,7 @@ static int lpm_hash(lua_State* L) { } fclose(file); } else { - sha256_update(&hash_ctx, data, len); + sha256_update(&hash_ctx, (unsigned char *) data, len); } sha256_final(&hash_ctx, buffer); lua_pushhexstring(L, buffer, digest_length); @@ -1210,7 +1215,7 @@ static int lpm_extract(lua_State* L) { } break; } int err; - if (err = mtar_next(&tar)) { + if ((err = mtar_next(&tar))) { mtar_close(&tar); return luaL_error(L, "Error while reading tar archive: %s", mtar_strerror(err)); } @@ -1451,7 +1456,7 @@ static int lpm_extract(lua_State* L) { static int lpm_socket_write(get_context_t* context, int len) { - return context->is_ssl ? mbedtls_ssl_write(&context->ssl, context->buffer, len) : write(context->s, context->buffer, len); + return context->is_ssl ? mbedtls_ssl_write(&context->ssl, (unsigned char *) context->buffer, len) : write(context->s, context->buffer, len); } static int lpm_socket_read(get_context_t* context, int len) { @@ -1459,7 +1464,7 @@ static int lpm_extract(lua_State* L) { len = sizeof(context->buffer) - context->buffer_length; if (len == 0) return len; - len = context->is_ssl ? mbedtls_ssl_read(&context->ssl, &context->buffer[context->buffer_length], len) : read(context->s, &context->buffer[context->buffer_length], len); + len = context->is_ssl ? mbedtls_ssl_read(&context->ssl, (unsigned char *) &context->buffer[context->buffer_length], len) : read(context->s, &context->buffer[context->buffer_length], len); if (len > 0) context->buffer_length += len; return len; @@ -1637,6 +1642,7 @@ static int lpm_extract(lua_State* L) { } } } + default: break; } finish: if (context->file) { @@ -1882,38 +1888,38 @@ static const luaL_Reg system_lib[] = { { NULL, NULL } }; -#ifndef ARCH_PROCESSOR +#ifndef LPM_ARCH_PROCESSOR #if defined(__x86_64__) || defined(_M_AMD64) || defined(__MINGW64__) - #define ARCH_PROCESSOR "x86_64" + #define LPM_ARCH_PROCESSOR "x86_64" #elif defined(__i386__) || defined(_M_IX86) || defined(__MINGW32__) - #define ARCH_PROCESSOR "x86" + #define LPM_ARCH_PROCESSOR "x86" #elif defined(__aarch64__) || defined(_M_ARM64) || defined (_M_ARM64EC) - #define ARCH_PROCESSOR "aarch64" + #define LPM_ARCH_PROCESSOR "aarch64" #elif defined(__arm__) || defined(_M_ARM) - #define ARCH_PROCESSOR "arm" + #define LPM_ARCH_PROCESSOR "arm" #elif defined(__riscv_xlen) && __riscv_xlen == 32 - #define ARCH_PROCESSOR "riscv32" + #define LPM_ARCH_PROCESSOR "riscv32" #elif defined(__riscv_xlen) && __riscv_xlen == 64 - #define ARCH_PROCESSOR "riscv64" + #define LPM_ARCH_PROCESSOR "riscv64" #else - #error "Please define -DARCH_PROCESSOR." + #error "Please define -DLPM_ARCH_PROCESSOR." #endif #endif -#ifndef ARCH_PLATFORM +#ifndef LPM_ARCH_PLATFORM #if _WIN32 - #define ARCH_PLATFORM "windows" + #define LPM_ARCH_PLATFORM "windows" #elif __ANDROID__ - #define ARCH_PLATFORM "android" + #define LPM_ARCH_PLATFORM "android" #elif __linux__ - #define ARCH_PLATFORM "linux" + #define LPM_ARCH_PLATFORM "linux" #elif __APPLE__ - #define ARCH_PLATFORM "darwin" + #define LPM_ARCH_PLATFORM "darwin" #else - #error "Please define -DARCH_PLATFORM." + #error "Please define -DLPM_ARCH_PLATFORM." #endif #endif -#ifndef LITE_ARCH_TUPLE - #define LITE_ARCH_TUPLE ARCH_PROCESSOR "-" ARCH_PLATFORM +#ifndef LPM_ARCH_TUPLE + #define LPM_ARCH_TUPLE LPM_ARCH_PROCESSOR "-" LPM_ARCH_PLATFORM #endif @@ -1926,9 +1932,9 @@ static const luaL_Reg system_lib[] = { // If this is defined as empty string, we disable self-upgrading, as well as switching the executable symlink. #ifndef LPM_DEFAULT_RELEASE #if _WIN32 - #define LPM_DEFAULT_RELEASE "https://github.com/lite-xl/lite-xl-plugin-manager/releases/download/%r/lpm." LITE_ARCH_TUPLE ".exe" + #define LPM_DEFAULT_RELEASE "https://github.com/lite-xl/lite-xl-plugin-manager/releases/download/%r/lpm." LPM_ARCH_TUPLE ".exe" #else - #define LPM_DEFAULT_RELEASE "https://github.com/lite-xl/lite-xl-plugin-manager/releases/download/%r/lpm." LITE_ARCH_TUPLE + #define LPM_DEFAULT_RELEASE "https://github.com/lite-xl/lite-xl-plugin-manager/releases/download/%r/lpm." LPM_ARCH_TUPLE #endif #endif @@ -1937,6 +1943,7 @@ static const luaL_Reg system_lib[] = { extern unsigned int lpm_luac_len; #endif + int main(int argc, char* argv[]) { lua_State* L = luaL_newstate(); luaL_openlibs(L); @@ -1950,7 +1957,7 @@ int main(int argc, char* argv[]) { lua_setglobal(L, "ARGV"); lua_pushliteral(L, LPM_VERSION); lua_setglobal(L, "VERSION"); - lua_pushliteral(L, ARCH_PLATFORM); + lua_pushliteral(L, LPM_ARCH_PLATFORM); lua_setglobal(L, "PLATFORM"); #ifdef LPM_NO_NETWORK lua_pushboolean(L, 1); @@ -1964,6 +1971,18 @@ int main(int argc, char* argv[]) { lua_pushboolean(L, 0); #endif lua_setglobal(L, "NO_GIT"); + #ifdef LPM_NO_LXL + lua_pushboolean(L, 1); + #else + lua_pushboolean(L, 0); + #endif + lua_setglobal(L, "NO_LXL"); + #ifdef LPM_NO_REMOTE_EXECUTABLE + lua_pushboolean(L, 1); + #else + lua_pushboolean(L, 0); + #endif + lua_setglobal(L, "NO_REMOTE_EXEUCTABLE"); #if _WIN32 DWORD handles[] = { STD_OUTPUT_HANDLE, STD_ERROR_HANDLE }; int setVirtualProcessing = 0; @@ -2012,7 +2031,7 @@ int main(int argc, char* argv[]) { #endif lua_setglobal(L, "EXEFILE"); - lua_pushliteral(L, LITE_ARCH_TUPLE); + lua_pushliteral(L, LPM_ARCH_TUPLE); lua_setglobal(L, "DEFAULT_ARCH"); lua_pushliteral(L, LPM_DEFAULT_REPOSITORY); lua_setglobal(L, "DEFAULT_REPO_URL"); diff --git a/src/lpm.lua b/src/lpm.lua index d27f9ed..fe60af3 100644 --- a/src/lpm.lua +++ b/src/lpm.lua @@ -1425,7 +1425,9 @@ end function LiteXL:uninstall() if not system.stat(self.local_path) then error("lite-xl " .. self.version .. " not installed") end - common.rmrf(self.local_path) + if prompt("This will delete " .. self.local_path .. ". Are you sure you want to continue?") then + common.rmrf(self.local_path) + end end @@ -1625,7 +1627,7 @@ function Bottle:all_addons() repo_path = (hash[id] and hash[id][1].local_path or nil), dependencies = (hash[id] and hash[id][1].dependencies or nil) })) - if not hash[id] then hash[id] = t[#t] end + if not hash[id] then hash[id] = { t[#t] } end end end end @@ -2641,7 +2643,7 @@ not commonly used publically. ARCH = ARGS["arch"] or { DEFAULT_ARCH } ASSUME_YES = ARGS["assume-yes"] or FORCE MOD_VERSION = ARGS["mod-version"] or os.getenv("LPM_MODVERSION") - assert(not MOD_VERSION or MOD_VERSION == "any" or MOD_VERSION:find("^%d+$"), "--mod-version must be either 'any' or a number.") + assert(not MOD_VERSION or MOD_VERSION == "any" or MOD_VERSION:find("^%d+%.?%d*%.?%d*$"), "--mod-version must be either 'any' or a version number.") HOME = (os.getenv("USERPROFILE") or os.getenv("HOME")):gsub(PATHSEP .. "$", "") USERDIR = common.normalize_path(ARGS["userdir"]) or os.getenv("LITE_USERDIR") or (os.getenv("XDG_CONFIG_HOME") and os.getenv("XDG_CONFIG_HOME") .. PATHSEP .. "lite-xl") or (HOME and (HOME .. PATHSEP .. '.config' .. PATHSEP .. 'lite-xl')) @@ -2712,7 +2714,7 @@ not commonly used publically. if ARGS[2] == "purge" then return lpm.purge() end local ssl_certs = ARGS["ssl-certs"] or os.getenv("SSL_CERT_DIR") or os.getenv("SSL_CERT_FILE") if not NO_NETWORK then - if ssl_certs then + if ssl_certs and ssl_certs ~= "system" then if ssl_certs == "noverify" then system.certs("noverify") else |