this code is cursed

This commit is contained in:
delta 2022-12-01 15:25:08 +01:00
commit ccbcb236f1
17 changed files with 1283 additions and 0 deletions

649
Cargo.lock generated Normal file
View file

@ -0,0 +1,649 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "autocfg"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
[[package]]
name = "base64"
version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"
[[package]]
name = "bitflags"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bstr"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223"
dependencies = [
"memchr",
]
[[package]]
name = "bulb"
version = "0.1.0"
dependencies = [
"git2",
"lazy_static",
"lenient_semver",
"minreq",
"mlua",
"ron",
"semver",
"serde",
"serde_json",
"url",
]
[[package]]
name = "bumpalo"
version = "3.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba"
[[package]]
name = "cc"
version = "1.0.77"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e9f73505338f7d905b19d18738976aae232eb46b8efc15554ffc56deb5d9ebe4"
dependencies = [
"jobserver",
]
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "erased-serde"
version = "0.3.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "54558e0ba96fbe24280072642eceb9d7d442e32c7ec0ea9e7ecd7b4ea2cf4e11"
dependencies = [
"serde",
]
[[package]]
name = "form_urlencoded"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8"
dependencies = [
"percent-encoding",
]
[[package]]
name = "git2"
version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2994bee4a3a6a51eb90c218523be382fd7ea09b16380b9312e9dbe955ff7c7d1"
dependencies = [
"bitflags",
"libc",
"libgit2-sys",
"log",
"openssl-probe",
"openssl-sys",
"url",
]
[[package]]
name = "idna"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6"
dependencies = [
"unicode-bidi",
"unicode-normalization",
]
[[package]]
name = "itoa"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc"
[[package]]
name = "jobserver"
version = "0.1.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "068b1ee6743e4d11fb9c6a1e6064b3693a1b600e7f5f5988047d98b3dc9fb90b"
dependencies = [
"libc",
]
[[package]]
name = "js-sys"
version = "0.3.60"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47"
dependencies = [
"wasm-bindgen",
]
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "lenient_semver"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "de8de3f4f3754c280ce1c8c42ed8dd26a9c8385c2e5ad4ec5a77e774cea9c1ec"
dependencies = [
"lenient_semver_parser",
"lenient_version",
"semver",
]
[[package]]
name = "lenient_semver_parser"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f650c1d024ddc26b4bb79c3076b30030f2cf2b18292af698c81f7337a64d7d6"
dependencies = [
"lenient_semver_version_builder",
"semver",
]
[[package]]
name = "lenient_semver_version_builder"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9049f8ff49f75b946f95557148e70230499c8a642bf2d6528246afc7d0282d17"
dependencies = [
"semver",
]
[[package]]
name = "lenient_version"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bad7b41cc0ad9b8a9f8d8fcb7c2ab6703a6da4b369cbb7e3a63ee0840769b4eb"
dependencies = [
"lenient_semver_parser",
"lenient_semver_version_builder",
"serde",
]
[[package]]
name = "libc"
version = "0.2.137"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc7fcc620a3bff7cdd7a365be3376c97191aeaccc2a603e600951e452615bf89"
[[package]]
name = "libgit2-sys"
version = "0.14.0+1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "47a00859c70c8a4f7218e6d1cc32875c4b55f6799445b842b0d8ed5e4c3d959b"
dependencies = [
"cc",
"libc",
"libssh2-sys",
"libz-sys",
"openssl-sys",
"pkg-config",
]
[[package]]
name = "libssh2-sys"
version = "0.2.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b094a36eb4b8b8c8a7b4b8ae43b2944502be3e59cd87687595cf6b0a71b3f4ca"
dependencies = [
"cc",
"libc",
"libz-sys",
"openssl-sys",
"pkg-config",
"vcpkg",
]
[[package]]
name = "libz-sys"
version = "1.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9702761c3935f8cc2f101793272e202c72b99da8f4224a19ddcf1279a6450bbf"
dependencies = [
"cc",
"libc",
"pkg-config",
"vcpkg",
]
[[package]]
name = "log"
version = "0.4.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
dependencies = [
"cfg-if",
]
[[package]]
name = "lua-src"
version = "544.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "708ba3c844d5e9d38def4a09dd871c17c370f519b3c4b7261fbabe4a613a814c"
dependencies = [
"cc",
]
[[package]]
name = "luajit-src"
version = "210.4.3+resty8384278"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19ee5d5afddf1ec76ffa55ca7c3001f2f8a703834beba53c56a38ea6641cef44"
dependencies = [
"cc",
]
[[package]]
name = "memchr"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
[[package]]
name = "minreq"
version = "2.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c785bc6027fd359756e538541c8624012ba3776d3d3fe123885643092ed4132"
dependencies = [
"lazy_static",
"log",
"rustls",
"webpki",
"webpki-roots",
]
[[package]]
name = "mlua"
version = "0.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4351dbcc863fb6249c81b3bd0c8001214e9d4d44d22cabda17026353a77fe612"
dependencies = [
"bstr",
"cc",
"erased-serde",
"lua-src",
"luajit-src",
"mlua_derive",
"num-traits",
"once_cell",
"pkg-config",
"rustc-hash",
"serde",
]
[[package]]
name = "mlua_derive"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9214e60d3cf1643013b107330fcd374ccec1e4ba1eef76e7e5da5e8202e71c0"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "num-traits"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd"
dependencies = [
"autocfg",
]
[[package]]
name = "once_cell"
version = "1.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860"
[[package]]
name = "openssl-probe"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
[[package]]
name = "openssl-sys"
version = "0.9.77"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b03b84c3b2d099b81f0953422b4d4ad58761589d0229b5506356afca05a3670a"
dependencies = [
"autocfg",
"cc",
"libc",
"pkg-config",
"vcpkg",
]
[[package]]
name = "percent-encoding"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e"
[[package]]
name = "pkg-config"
version = "0.3.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160"
[[package]]
name = "proc-macro2"
version = "1.0.47"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179"
dependencies = [
"proc-macro2",
]
[[package]]
name = "ring"
version = "0.16.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc"
dependencies = [
"cc",
"libc",
"once_cell",
"spin",
"untrusted",
"web-sys",
"winapi",
]
[[package]]
name = "ron"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "300a51053b1cb55c80b7a9fde4120726ddf25ca241a1cbb926626f62fb136bff"
dependencies = [
"base64",
"bitflags",
"serde",
]
[[package]]
name = "rustc-hash"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
[[package]]
name = "rustls"
version = "0.20.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "539a2bfe908f471bfa933876bd1eb6a19cf2176d375f82ef7f99530a40e48c2c"
dependencies = [
"log",
"ring",
"sct",
"webpki",
]
[[package]]
name = "ryu"
version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09"
[[package]]
name = "sct"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4"
dependencies = [
"ring",
"untrusted",
]
[[package]]
name = "semver"
version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e25dfac463d778e353db5be2449d1cce89bd6fd23c9f1ea21310ce6e5a1b29c4"
dependencies = [
"serde",
]
[[package]]
name = "serde"
version = "1.0.147"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d193d69bae983fc11a79df82342761dfbf28a99fc8d203dca4c3c1b590948965"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.147"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4f1d362ca8fc9c3e3a7484440752472d68a6caa98f1ab81d99b5dfe517cec852"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "serde_json"
version = "1.0.89"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "020ff22c755c2ed3f8cf162dbb41a7268d934702f3ed3631656ea597e08fc3db"
dependencies = [
"itoa",
"ryu",
"serde",
]
[[package]]
name = "spin"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
[[package]]
name = "syn"
version = "1.0.103"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a864042229133ada95abf3b54fdc62ef5ccabe9515b64717bcb9a1919e59445d"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "tinyvec"
version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50"
dependencies = [
"tinyvec_macros",
]
[[package]]
name = "tinyvec_macros"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
[[package]]
name = "unicode-bidi"
version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992"
[[package]]
name = "unicode-ident"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3"
[[package]]
name = "unicode-normalization"
version = "0.1.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921"
dependencies = [
"tinyvec",
]
[[package]]
name = "untrusted"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
[[package]]
name = "url"
version = "2.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643"
dependencies = [
"form_urlencoded",
"idna",
"percent-encoding",
"serde",
]
[[package]]
name = "vcpkg"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
[[package]]
name = "wasm-bindgen"
version = "0.2.83"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268"
dependencies = [
"cfg-if",
"wasm-bindgen-macro",
]
[[package]]
name = "wasm-bindgen-backend"
version = "0.2.83"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142"
dependencies = [
"bumpalo",
"log",
"once_cell",
"proc-macro2",
"quote",
"syn",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.83"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
]
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.83"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c"
dependencies = [
"proc-macro2",
"quote",
"syn",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.83"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f"
[[package]]
name = "web-sys"
version = "0.3.60"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bcda906d8be16e728fd5adc5b729afad4e444e106ab28cd1c7256e54fa61510f"
dependencies = [
"js-sys",
"wasm-bindgen",
]
[[package]]
name = "webpki"
version = "0.22.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd"
dependencies = [
"ring",
"untrusted",
]
[[package]]
name = "webpki-roots"
version = "0.22.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "368bfe657969fb01238bb756d351dcade285e0f6fcbd36dcb23359a5169975be"
dependencies = [
"webpki",
]
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"

23
Cargo.toml Normal file
View file

@ -0,0 +1,23 @@
[package]
name = "bulb"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
git2 = "0.15.0"
minreq = { version = "2.6.0", features = [ "https" ] }
mlua = { version = "0.8.3", features = [ "vendored", "module", "lua54", "serialize" ] }
serde = { version = "1.0.147", features = ["derive"] }
ron = "0.8.0"
lazy_static = "1.4.0"
semver = { version = "1.0.14", features = [ "serde" ] }
lenient_semver = { version = "0.4.2", features = [ "version_serde" ] }
url = { version = "2.3.1", features = [ "serde" ] }
serde_json = "1.0.89"
# lenient_semver_range = { git = "https://github.com/knutwalker/lenient-semver-range" }
[lib]
name = "bulb"
crate-type = ["cdylib"]

2
README.md Normal file
View file

@ -0,0 +1,2 @@
<h1 align="center">💡 lite-bulb</h1>
<p align="center">minimalist, vim-plug inspired plugin manager for lite-xl</p>

36
init.lua Normal file
View file

@ -0,0 +1,36 @@
--mod-version:3
local config = require "core.config"
local common = require "core.common"
local core = require "core"
package.cpath = package.cpath .. ";" .. USERDIR .. "/plugins/bulb/?.so"
-- Globals
-- BULB_PLUGIN_DIR = USERDIR .. "/bulb-plugins"
-- BULB_CACHE_DIR = BULB_PLUGIN_DIR .. "/.cache"
local bulb = require "libbulb"
config.plugins.bulb = common.merge({
repos = {
{
url = "https://github.com/lite-xl/lite-xl-plugins",
plugins = {
"plugin1",
"plugin2"
}
}
},
clean_repos = false,
install_optionals = false
}, config.plugins.bulb)
local quit_default = core.quit
function core.quit()
-- bulb.state.clean()
quit_default()
end
core.log(bulb.init(config.plugins.bulb))

1
libbulb.so Symbolic link
View file

@ -0,0 +1 @@
target/debug/libbulb.so

17
manifest.json Normal file
View file

@ -0,0 +1,17 @@
{
"plugins": [
{
"name": "plugin1",
"description": "sus",
"version": "1.2.3"
},
{
"name": "plugin2",
"description": "sus",
"version": "1.2.3",
"conflicts": {
"plugin1": {}
}
}
]
}

79
src/actions/install.rs Normal file
View file

@ -0,0 +1,79 @@
use mlua::prelude::*;
use url::Url;
use git2::Repository;
use std::{
sync::{
Mutex,
Arc
}
};
use crate::{
manifest::{
Manifest,
Plugin
},
globals::{
BULB_CACHE_PATH,
MOD_VERSION
},
errors::ErrorWrapper,
State,
Config
};
pub fn install(plugin_name: String, repo_url: Url, /*state_mutex: Arc<Mutex<&State>>,*/ config_mutex: Arc<Mutex<&&mut Config>>) -> LuaResult<()> {
let bulb_cache_path = BULB_CACHE_PATH.lock().unwrap();
let mod_version = *MOD_VERSION.lock().unwrap();
let repo_manifest = Manifest::parse("/home/delta/.config/lite-xl/plugins/bulb/manifest.json", repo_url)?;
//let state = STATE.lock().unwrap();
let config = config_mutex.lock().unwrap();
// If true, the repository isn't cached yet
// if !state.repos.contains(&repo_url) {
// Repository::clone(repo_url.as_str(), bulb_cache_path).map_err(ErrorWrapper)?;
// state.repos.push(repo_url.clone());
// }
// let repo_folder_name = repo_url.path_segments().unwrap().last().unwrap();
// let mut repo_path = bulb_cache_path.clone();
// repo_path.push(repo_folder_name);
// repo_manifest = Manifest::parse(repo_path, repo_url)?;
// repo_manifest = Manifest::parse("/home/delta/.config/lite-xl/plugins/bulb/manifest.json", repo_url)?;
println!("{:#?}", &repo_manifest);
for plugin in repo_manifest.plugins {
println!(".name {}", plugin.name);
println!("_name {}", plugin_name);
if plugin.name == plugin_name {
match plugin.mod_version {
Some(version) => {
if version != mod_version {
return Err(LuaError::external(format!("[bulb] Failed to install plugin \"{}\": mod_version mismatch", plugin_name)));
}
},
_ => {}
}
match plugin.conflicts {
Some(conflicts) => {
for possible_conflict in conflicts.keys() {
for config_plugin in config.plugins.iter() {
println!("{}", &possible_conflict);
println!("{}", config_plugin);
if &possible_conflict == config_plugin {
return Err(LuaError::external(format!("[bulb] Failed to install plugin \"{}\": plugin conflict detected with {}", plugin_name, possible_conflict)));
}
}
}
},
_ => {}
}
}
}
Ok(())
}

2
src/actions/mod.rs Normal file
View file

@ -0,0 +1,2 @@
pub mod install;
pub mod update;

1
src/actions/uninstall.rs Normal file
View file

@ -0,0 +1 @@

0
src/actions/update.rs Normal file
View file

112
src/config.rs Normal file
View file

@ -0,0 +1,112 @@
use serde::Deserialize;
use url::Url;
// use git2::Repository;
use std::{
// fs::read_dir,
// path::PathBuf,
collections::HashSet,
sync::{
Mutex,
Arc
}
};
use crate::{
globals::{
BULB_CACHE_PATH
},
state::State,
actions,
errors::ErrorWrapper
};
use mlua::{
prelude::{
LuaResult,
LuaError,
LuaTable
},
Lua,
LuaSerdeExt
};
#[allow(dead_code)]
#[derive(Deserialize, Debug, Clone, Hash, Eq, PartialEq)]
pub struct Repo {
url: Url,
plugins: Vec<String>
}
#[derive(Deserialize, Debug)]
// #[serde(transparent)]
pub struct Config<'c> {
pub repos: Vec<Repo>,
pub clean_repos: bool,
pub install_optionals: bool,
#[serde(skip)]
pub plugins: Vec<&'c String>
}
pub struct ConfigLua<'lua> {
pub table: LuaTable<'lua>,
pub lua: &'lua Lua
}
impl<'lua> TryFrom<ConfigLua<'lua>> for Config<'_> {
type Error = LuaError;
fn try_from(config_lua: ConfigLua) -> LuaResult<Self> {
let config: Config = Lua::from_value(config_lua.lua, mlua::Value::Table(config_lua.table))?;
Ok(config)
}
}
impl<'c> Config<'c> {
pub fn parse(&'c mut self, state: State) -> LuaResult<()> {
let bulb_cache_path = BULB_CACHE_PATH.get_mut().unwrap();
// let state = STATE.lock().unwrap();
let state_repos_hash: HashSet<_> = state.repos.iter().collect();
let state_plugins_hash: HashSet<_> = state.plugins.iter().collect();
let config_repos_hash: HashSet<String> = self.repos.iter().map(|repo| repo.url.to_string()).collect();
let config_plugins_hash: HashSet<_>;
// let mut repo_clone = self.repos.clone();
let config_plugins_vec: Vec<&'c String> = self.repos.iter()
.map(|repo| &repo.plugins)
.flatten()
.collect();
self.plugins = config_plugins_vec.clone();
config_plugins_hash = config_plugins_vec.iter().collect();
let config_mutex = Arc::new(Mutex::new(&self));
/*actions::install::install("plugin1".to_owned(),
Url::parse("https://github.com/lite-xl/lite-xl-plugins").map_err(ErrorWrapper)?,
config_mutex)?;*/
// Remove duplicate repos from state
// for repo_config in self.repos {
// state_diff.repos.remove(state_diff.repos.iter().position(|repo| repo == repo_config.url.as_str()).unwrap());
// for plugin_config in repo_config.plugins {
// }
// }
Ok(())
}
pub fn new() -> Self {
Self {
repos: Vec::new(),
clean_repos: false,
install_optionals: false,
plugins: Vec::new()
}
}
}

49
src/errors.rs Normal file
View file

@ -0,0 +1,49 @@
use mlua::prelude::LuaError;
use ron::error::SpannedError;
pub struct JsonError(pub serde_json::Error);
pub struct RonError(pub SpannedError);
// pub struct MutexError<T>(pub PoisonError<T>);
pub struct ErrorWrapper<E>(pub E);
impl From<serde_json::Error> for JsonError {
fn from(err: serde_json::Error) -> Self {
Self(err)
}
}
impl From<JsonError> for LuaError {
fn from(err: JsonError) -> Self {
LuaError::external(err.0)
}
}
impl From<SpannedError> for RonError {
fn from(err: ron::error::SpannedError) -> Self {
Self(err)
}
}
impl From<RonError> for LuaError {
fn from(err: RonError) -> Self {
LuaError::external(err.0)
}
}
impl<E> From<E> for ErrorWrapper<E>
where
E: std::error::Error + Send + Sync
{
fn from(err: E) -> Self {
Self(err)
}
}
impl<E> From<ErrorWrapper<E>> for LuaError
where
E: std::error::Error + Send + Sync + 'static
{
fn from(err: ErrorWrapper<E>) -> Self {
LuaError::external(err.0)
}
}

23
src/globals.rs Normal file
View file

@ -0,0 +1,23 @@
use lazy_static::lazy_static;
use std::{
sync::{
Mutex,
Once
},
path::PathBuf
};
use crate::{
state::State,
config::Config
};
lazy_static! {
pub static ref BULB_PATH: Mutex<PathBuf> = Mutex::new(PathBuf::new());
pub static ref BULB_CACHE_PATH: Mutex<PathBuf> = Mutex::new(PathBuf::new());
pub static ref BULB_STATE_PATH: Mutex<PathBuf> = Mutex::new(PathBuf::new());
pub static ref MOD_VERSION: Mutex<&'static str> = Mutex::new("");
// pub static ref STATE: Mutex<State> = Mutex::new(State::new());
// pub static ref CONFIG: Mutex<Config<'static>> = Mutex::new(Config::new());
}

105
src/lib.rs Normal file
View file

@ -0,0 +1,105 @@
mod actions;
mod config;
mod state;
mod manifest;
mod globals;
mod errors;
use mlua::prelude::*;
use std::{
fs::{
self,
File
},
// path::{
// Path,
// PathBuf
// }
};
use crate::{
config::{
ConfigLua,
Config
},
state::State,
globals::*
};
fn init(lua: &Lua, config_table: LuaTable) -> LuaResult<()> {
let bulb_state_path = BULB_STATE_PATH.get_mut().unwrap();
let config_lua = ConfigLua {
table: config_table,
lua
};
// let manifest = Manifest::parse(
// "/home/delta/.config/lite-xl/plugins/bulb/manifest.json",
// Url::parse("https://github.com/lite-xl/lite-xl-plugins").map_err(ErrorWrapper)?
// )?;
let state = State::parse(bulb_state_path.to_owned())?;
let mut config = Config::try_from(config_lua)?;
config.parse(state);
Ok(())
// Ok(format!("{:#?}", config))
}
#[mlua::lua_module]
fn libbulb(lua: &Lua) -> LuaResult<LuaTable> {
println!("1");
let lua_globals = lua.globals();
let user_dir: String = lua_globals.get("USERDIR")?;
let mut bulb_path = BULB_PATH.lock().unwrap();
let mut bulb_cache_path = BULB_CACHE_PATH.lock().unwrap();
let mut bulb_state_path = BULB_STATE_PATH.lock().unwrap();
let mut mod_version = MOD_VERSION.lock().unwrap();
// Jank:tm:
// Taken from https://stackoverflow.com/a/30527289
fn string_to_static_str(s: String) -> &'static str {
Box::leak(s.into_boxed_str())
}
bulb_path.push(user_dir);
bulb_path.push("bulb");
bulb_cache_path.push(bulb_path.clone());
bulb_cache_path.push(".cache");
bulb_state_path.push(bulb_path.clone());
bulb_state_path.push(".state.ron");
*mod_version = string_to_static_str(lua_globals.get("MOD_VERSION")?);
println!("2");
//*state = State::parse(bulb_state_path.to_owned())?;
println!("3");
if !bulb_path.exists() {
fs::create_dir(bulb_path.to_owned())?;
}
if !bulb_state_path.exists() {
File::create(bulb_state_path.to_owned())?;
fs::write(bulb_state_path.to_owned(), "(plugins:[],repos:[])")?;
}
if !bulb_cache_path.exists() {
fs::create_dir(bulb_cache_path.to_owned())?;
}
let bulb = lua.create_table()?;
bulb.set("init", lua.create_function(init)?)?;
// bulb.set("state", lua.create_userdata(*state)?)?;
println!("4");
Ok(bulb)
}

89
src/manifest.rs Normal file
View file

@ -0,0 +1,89 @@
#![allow(dead_code)]
use semver::VersionReq;
use crate::errors::JsonError;
use url::Url;
use serde::Deserialize;
use std::{
collections::HashMap,
path::{
PathBuf,
Path
},
fs
};
use mlua::prelude::{
LuaResult,
LuaError
};
#[derive(Deserialize, Debug)]
pub struct Manifest {
#[serde(skip, default = "default_url")]
pub url: Url,
pub plugins: Vec<Plugin>,
pub repos: Option<Vec<String>>
}
#[derive(Deserialize, Debug)]
pub struct PluginReference {
pub optional: Option<bool>,
pub version: Option<VersionReq>
}
#[derive(Deserialize, Debug)]
struct File {
pub url: Url,
pub checksum: String,
pub arch: String,
pub path: PathBuf
}
#[derive(Deserialize, Debug)]
pub struct Plugin {
pub name: String,
pub description: String,
pub version: VersionReq,
pub mod_version: Option<String>,
pub provides: Option<Vec<String>>,
pub dependencies: Option<HashMap<String, PluginReference>>,
pub conflicts: Option<HashMap<String, PluginReference>>,
pub path: Option<PathBuf>,
pub remote: Option<String>,
pub url: Option<Url>,
pub checksum: Option<String>,
}
fn default_url() -> Url {
Url::parse("https://example.com").unwrap()
}
impl Manifest {
pub fn parse<P>(path: P, url: Url) -> LuaResult<Manifest>
where
P: AsRef<Path>
{
let data = fs::read(path)?;
let mut manifest: Manifest = serde_json::from_slice(data.as_slice()).map_err(JsonError)?;
(&mut manifest).url = url;
// Make sure that a plugin doesn't contain both 'url'/'checksum' and 'remote'
for p in manifest.plugins.iter() {
if p.url.is_some() && p.checksum.is_none() {
return Err(LuaError::external(format!("Could not parse manifest from {}!\nField 'url' depends on field 'checksum'", manifest.url)));
} else if p.url.is_none() && p.checksum.is_some() {
return Err(LuaError::external(format!("Could not parse manifest from {}!\nField 'checksum' depends on field 'url'", manifest.url)));
};
if p.remote.is_some() && p.url.is_some() {
return Err(LuaError::external(format!("Could not parse manifest from {}!\nConflicting fields 'remote' and 'url'", manifest.url)));
}
}
Ok(manifest)
}
}

65
src/state.rs Normal file
View file

@ -0,0 +1,65 @@
use mlua::prelude::*;
use url::Url;
use ron::de::from_bytes;
use crate::{
globals::BULB_STATE_PATH,
errors::RonError
};
use serde::{
Serialize,
Deserialize
};
use std::{
fs,
path::Path
};
#[derive(Serialize, Deserialize, Clone)]
pub struct State {
pub plugins: Vec<String>,
pub repos: Vec<Url>
}
impl State {
pub fn parse<P>(path: P) -> LuaResult<Self>
where
P: AsRef<Path>
{
let data = fs::read(path)?;
// let mut manifest: Manifest = serde_json::from_slice(data.as_slice()).map_err(JsonError)?;
let state = from_bytes(data.as_slice()).map_err(RonError)?;
Ok(state)
}
pub fn new() -> Self {
Self {
plugins: Vec::new(),
repos: Vec::new()
}
}
pub fn clean(&self) {
fs::write(
BULB_STATE_PATH.lock().unwrap().to_owned(),
ron::to_string(self).unwrap()
).expect("Couldn't write state");
}
// pub fn clean_lua(_: &Lua, this: &Self, (): ()) -> LuaResult<()> {
// this.clean();
// Ok(())
// }
}
// impl LuaUserData for State {
// fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) {
// methods.add_method("clean", State::clean_lua)
// }
// }
impl Drop for State {
fn drop(&mut self) {
self.clean();
}
}

View file

@ -0,0 +1,30 @@
+-------+ +--------+
| State | | Config | Phase 1
+-------+ +--------+
| ||
V \/
+-------+ +-------+
| Repo1 | | Repo1 |
| Repo2 | | Repo2 |
| Repo3 | | Repo3 |
| Repo4 | | Repo5 |
+-------+ +-------+
||
|| Phase 1.5
\/
+-------+ +--------+
| State | | Config | Phase 2
+-------+ +--------+
| ||
V \/
+-------+ +-------+
| Repo1 | | Repo1 |
| Repo2 | | Repo2 |
| Repo3 | | Repo3 |
| Repo5 | | Repo5 |
+-------+ +-------+
Internally in phase 1.5, Config compares itself to State, removes keys that are in State and then installs plugins that are not in State
Config also modifies State by removing the keys that aren't in Config
Note: Config never modifies itself or State manually, instead delegating that work to the install() and uninstall() functions