mirror of
https://github.com/lune-org/lune.git
synced 2024-12-12 13:00:37 +00:00
Initial commit
This commit is contained in:
commit
8078425b2d
23 changed files with 1450 additions and 0 deletions
23
.github/workflows/build.yaml
vendored
Normal file
23
.github/workflows/build.yaml
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
name: Build
|
||||
|
||||
on:
|
||||
push:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Install Rust
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: stable
|
||||
override: true
|
||||
profile: minimal
|
||||
|
||||
- name: Build
|
||||
run: cargo build --locked --verbose
|
26
.github/workflows/lint.yaml
vendored
Normal file
26
.github/workflows/lint.yaml
vendored
Normal file
|
@ -0,0 +1,26 @@
|
|||
name: Lint
|
||||
|
||||
on:
|
||||
push:
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
name: Lint
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Install Rust
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: stable
|
||||
override: true
|
||||
components: rustfmt, clippy
|
||||
|
||||
- name: Rustfmt
|
||||
run: cargo fmt -- --check
|
||||
|
||||
- name: Clippy
|
||||
run: cargo clippy
|
117
.github/workflows/release.yaml
vendored
Normal file
117
.github/workflows/release.yaml
vendored
Normal file
|
@ -0,0 +1,117 @@
|
|||
name: Release
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
init:
|
||||
name: Init
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
manifest_name: ${{ steps.get_name.outputs.value }}
|
||||
manifest_version: ${{ steps.get_version.outputs.value }}
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Get name from manifest
|
||||
uses: SebRollen/toml-action@0ad94c4a52c402aaa76e14e8a43551163b6cedf9
|
||||
id: get_name
|
||||
with:
|
||||
file: Cargo.toml
|
||||
field: package.name
|
||||
|
||||
- name: Get version from manifest
|
||||
uses: SebRollen/toml-action@0ad94c4a52c402aaa76e14e8a43551163b6cedf9
|
||||
id: get_version
|
||||
with:
|
||||
file: Cargo.toml
|
||||
field: package.version
|
||||
|
||||
create-release:
|
||||
needs: ["init"]
|
||||
name: Create release
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Create release
|
||||
id: create_release
|
||||
uses: actions/create-release@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
tag_name: v${{ needs.init.outputs.manifest_version }}
|
||||
release_name: ${{ needs.init.outputs.manifest_version }}
|
||||
draft: true
|
||||
|
||||
release:
|
||||
needs: ["init", "create-release"]
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- name: Windows x86_64
|
||||
runner-os: windows-latest
|
||||
artifact-name: ${{ needs.init.outputs.manifest_name }}-${{ needs.init.outputs.manifest_version }}-windows-x86_64
|
||||
cargo-target: x86_64-pc-windows-msvc
|
||||
- name: Linux x86_64
|
||||
runner-os: ubuntu-latest
|
||||
artifact-name: ${{ needs.init.outputs.manifest_name }}-${{ needs.init.outputs.manifest_version }}-linux-x86_64
|
||||
cargo-target: x86_64-unknown-linux-gnu
|
||||
- name: macOS x86_64
|
||||
runner-os: macos-latest
|
||||
artifact-name: ${{ needs.init.outputs.manifest_name }}-${{ needs.init.outputs.manifest_version }}-macos-x86_64
|
||||
cargo-target: x86_64-apple-darwin
|
||||
|
||||
name: Build - ${{ matrix.name }}
|
||||
runs-on: ${{ matrix.runner-os }}
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Install Rust
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: stable
|
||||
target: ${{ matrix.cargo-target }}
|
||||
override: true
|
||||
profile: minimal
|
||||
|
||||
- name: Build binary
|
||||
run: cargo build --locked --release --all-features --target ${{ matrix.cargo-target }}
|
||||
env:
|
||||
CARGO_TARGET_DIR: output
|
||||
OPENSSL_STATIC: 1
|
||||
|
||||
- name: Create binary archive
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir -p staging
|
||||
if [ "${{ matrix.runner-os }}" = "windows-latest" ]; then
|
||||
cp "output/${{ matrix.cargo-target }}/release/${{ needs.init.outputs.manifest_name }}.exe" staging/
|
||||
cd staging
|
||||
7z a ../release.zip *
|
||||
else
|
||||
cp "output/${{ matrix.cargo-target }}/release/${{ needs.init.outputs.manifest_name }}" staging/
|
||||
cd staging
|
||||
zip ../release.zip *
|
||||
fi
|
||||
|
||||
- name: Upload binary artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: ${{ matrix.artifact-name }}
|
||||
path: release.zip
|
||||
|
||||
- name: Upload binary to release
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ needs.create-release.outputs.upload_url }}
|
||||
asset_path: release.zip
|
||||
asset_name: ${{ matrix.artifact-name }}.zip
|
||||
asset_content_type: application/octet-stream
|
23
.github/workflows/test.yaml
vendored
Normal file
23
.github/workflows/test.yaml
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
name: Test
|
||||
|
||||
on:
|
||||
push:
|
||||
|
||||
jobs:
|
||||
test:
|
||||
name: Test
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Install Rust
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: stable
|
||||
override: true
|
||||
profile: minimal
|
||||
|
||||
- name: Test
|
||||
run: cargo test
|
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
/target
|
||||
|
||||
.DS_Store
|
||||
*/.DS_Store
|
7
.luaurc
Normal file
7
.luaurc
Normal file
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"languageMode": "strict",
|
||||
"lint": { "*": true },
|
||||
"lintErrors": false,
|
||||
"typeErrors": true,
|
||||
"globals": []
|
||||
}
|
17
.vscode/settings.json
vendored
Normal file
17
.vscode/settings.json
vendored
Normal file
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
"luau-lsp.types.roblox": false,
|
||||
"luau-lsp.types.definitionFiles": ["luneTypes.d.luau"],
|
||||
"luau-lsp.sourcemap.enabled": false,
|
||||
"editor.formatOnSave": true,
|
||||
"stylua.searchParentDirectories": true,
|
||||
"prettier.tabWidth": 2,
|
||||
"[luau][lua]": {
|
||||
"editor.defaultFormatter": "JohnnyMorganz.stylua"
|
||||
},
|
||||
"[json][jsonc][markdown][yaml]": {
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||
},
|
||||
"[rust]": {
|
||||
"editor.defaultFormatter": "rust-lang.rust-analyzer"
|
||||
}
|
||||
}
|
661
Cargo.lock
generated
Normal file
661
Cargo.lock
generated
Normal file
|
@ -0,0 +1,661 @@
|
|||
# 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 = "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 = "bytes"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dfb24e866b15a1af2a1b663f10c6b6b8f397a84aadb828f12e5b289ec23a3a3c"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.78"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a20104e2335ce8a659d6dd92a51a767a0c062599c73b343fd152cb401e828c3d"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4ec7a4128863c188deefe750ac1d1dfe66c236909f845af04beed823638dc1b2"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"clap_derive",
|
||||
"clap_lex",
|
||||
"is-terminal",
|
||||
"once_cell",
|
||||
"strsim",
|
||||
"termcolor",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_derive"
|
||||
version = "4.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "684a277d672e91966334af371f1a7b5833f9aa00b07c84e92fbce95e00208ce8"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"proc-macro-error",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_lex"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "783fe232adfca04f90f56201b26d79682d4cd2625e0bc7290b95123afe558ade"
|
||||
dependencies = [
|
||||
"os_str_bytes",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "erased-serde"
|
||||
version = "0.3.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e4ca605381c017ec7a5fef5e548f1cfaa419ed0f6df6367339300db74c92aa7d"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "errno"
|
||||
version = "0.2.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1"
|
||||
dependencies = [
|
||||
"errno-dragonfly",
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "errno-dragonfly"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-core"
|
||||
version = "0.3.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "04909a7a7e4633ae6c4a9ab280aeb86da1236243a77b694a49eacd659a4bd3ac"
|
||||
|
||||
[[package]]
|
||||
name = "futures-macro"
|
||||
version = "0.3.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bdfb8ce053d86b91919aad980c220b1fb8401a9394410e1c289ed7e66b61835d"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-task"
|
||||
version = "0.3.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2ffb393ac5d9a6eaa9d3fdf37ae2776656b706e200c8e16b1bdb227f5198e6ea"
|
||||
|
||||
[[package]]
|
||||
name = "futures-util"
|
||||
version = "0.3.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "197676987abd2f9cadff84926f410af1c183608d36641465df73ae8211dc65d6"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-macro",
|
||||
"futures-task",
|
||||
"pin-project-lite",
|
||||
"pin-utils",
|
||||
"slab",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9"
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "io-lifetimes"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e7d6c6f8c91b4b9ed43484ad1a938e393caf35960fce7f82a040497207bd8e9e"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "is-terminal"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "28dfb6c8100ccc63462345b67d1bbc3679177c75ee4bf59bf29c8b1d110b8189"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"io-lifetimes",
|
||||
"rustix",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.139"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79"
|
||||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4"
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"scopeguard",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "luau0-src"
|
||||
version = "0.5.1+luau558"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5e0869ba31f9b152c28bb604ecee6deaa2103a97365bb219781ac137bd487626"
|
||||
dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lune"
|
||||
version = "0.0.1"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"mlua",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
|
||||
|
||||
[[package]]
|
||||
name = "mio"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5d732bc30207a6423068df043e3d02e0735b155ad7ce1a6f76fe2baa5b158de"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"log",
|
||||
"wasi",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mlua"
|
||||
version = "0.8.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2ee2ad7a9aa69056b148d9d590344bc155d3ce0d2200e3b2838f7034f6ba33c1"
|
||||
dependencies = [
|
||||
"bstr",
|
||||
"cc",
|
||||
"erased-serde",
|
||||
"futures-core",
|
||||
"futures-task",
|
||||
"futures-util",
|
||||
"luau0-src",
|
||||
"num-traits",
|
||||
"once_cell",
|
||||
"pkg-config",
|
||||
"rustc-hash",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_cpus"
|
||||
version = "1.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.17.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66"
|
||||
|
||||
[[package]]
|
||||
name = "os_str_bytes"
|
||||
version = "6.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee"
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f"
|
||||
dependencies = [
|
||||
"lock_api",
|
||||
"parking_lot_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot_core"
|
||||
version = "0.9.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba1ef8814b5c993410bb3adfad7a5ed269563e4a2f90c41f5d85be7fb47133bf"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"redox_syscall",
|
||||
"smallvec",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-lite"
|
||||
version = "0.2.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116"
|
||||
|
||||
[[package]]
|
||||
name = "pin-utils"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
||||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
|
||||
dependencies = [
|
||||
"proc-macro-error-attr",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error-attr"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.50"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6ef7d57beacfaf2d8aee5937dab7b7f28de3cb8b1828479bb5de2a7106f2bae2"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.2.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc-hash"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.36.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d4fdebc4b395b7fbb9ab11e462e20ed9051e7b16e42d24042c776eca0ac81b03"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"errno",
|
||||
"io-lifetimes",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7b4b9743ed687d4b4bcedf9ff5eaa7398495ae14e61cba0a295704edbc7decde"
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.152"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.152"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "af487d118eecd09402d70a5d72551860e788df87b464af30e5ea6a38c75c541e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.91"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "877c235533714907a8c2464236f5c4b2a17262ef1bd71f38f35ea592c8da6883"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook-registry"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "slab"
|
||||
version = "0.4.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0"
|
||||
|
||||
[[package]]
|
||||
name = "socket2"
|
||||
version = "0.4.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "02e2d2db9033d13a1567121ddd7a095ee144db4e1ca1b1bda3419bc0da294ebd"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.107"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "termcolor"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6"
|
||||
dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "1.24.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "597a12a59981d9e3c38d216785b0c37399f6e415e8d0712047620f189371b0bb"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"bytes",
|
||||
"libc",
|
||||
"memchr",
|
||||
"mio",
|
||||
"num_cpus",
|
||||
"parking_lot",
|
||||
"pin-project-lite",
|
||||
"signal-hook-registry",
|
||||
"socket2",
|
||||
"tokio-macros",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-macros"
|
||||
version = "1.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d266c00fde287f55d3f1c3e96c500c362a2b8c695076ec180f27918820bc6df8"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||
|
||||
[[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-util"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.42.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm",
|
||||
"windows_aarch64_msvc",
|
||||
"windows_i686_gnu",
|
||||
"windows_i686_msvc",
|
||||
"windows_x86_64_gnu",
|
||||
"windows_x86_64_gnullvm",
|
||||
"windows_x86_64_msvc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.42.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8c9864e83243fdec7fc9c5444389dcbbfd258f745e7853198f365e3c4968a608"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.42.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4c8b1b673ffc16c47a9ff48570a9d85e25d265735c503681332589af6253c6c7"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.42.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "de3887528ad530ba7bdbb1faa8275ec7a1155a45ffa57c37993960277145d640"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.42.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bf4d1122317eddd6ff351aa852118a2418ad4214e6613a50e0191f7004372605"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.42.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c1040f221285e17ebccbc2591ffdc2d44ee1f9186324dd3e84e99ac68d699c45"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.42.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "628bfdf232daa22b0d64fdb62b09fcc36bb01f05a3939e20ab73aaf9470d0463"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.42.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd"
|
11
Cargo.toml
Normal file
11
Cargo.toml
Normal file
|
@ -0,0 +1,11 @@
|
|||
[package]
|
||||
name = "lune"
|
||||
version = "0.0.1"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
clap = { version = "4.1.1", features = ["derive"] }
|
||||
mlua = { version = "0.8.7", features = ["luau", "async", "serialize"] }
|
||||
tokio = { version = "1.24.2", features = ["full"] }
|
||||
serde = { version = "1.0.152", features = ["derive"] }
|
||||
serde_json = { version = "1.0.91" }
|
4
aftman.toml
Normal file
4
aftman.toml
Normal file
|
@ -0,0 +1,4 @@
|
|||
[tools]
|
||||
luau-lsp = "JohnnyMorganz/luau-lsp@1.15.0"
|
||||
selene = "Kampfkarren/selene@0.24.0"
|
||||
stylua = "JohnnyMorganz/StyLua@0.16.0"
|
55
lune.yml
Normal file
55
lune.yml
Normal file
|
@ -0,0 +1,55 @@
|
|||
---
|
||||
globals:
|
||||
# FS (filesystem)
|
||||
fs.readFile:
|
||||
args:
|
||||
- type: string
|
||||
fs.readDir:
|
||||
args:
|
||||
- type: string
|
||||
fs.writeFile:
|
||||
args:
|
||||
- type: string
|
||||
- type: string
|
||||
fs.writeDir:
|
||||
args:
|
||||
- type: string
|
||||
fs.removeFile:
|
||||
args:
|
||||
- type: string
|
||||
fs.removeDir:
|
||||
args:
|
||||
- type: string
|
||||
fs.isFile:
|
||||
args:
|
||||
- type: string
|
||||
fs.isDir:
|
||||
args:
|
||||
- type: string
|
||||
# JSON
|
||||
json.encode:
|
||||
args:
|
||||
- type: any
|
||||
- required: false
|
||||
type: boolean
|
||||
json.decode:
|
||||
args:
|
||||
- type: string
|
||||
# Process
|
||||
process.getEnvVars:
|
||||
process.getEnvVar:
|
||||
args:
|
||||
- type: string
|
||||
process.setEnvVar:
|
||||
args:
|
||||
- type: string
|
||||
- type: string
|
||||
process.exit:
|
||||
args:
|
||||
- required: false
|
||||
type: number
|
||||
process.spawn:
|
||||
args:
|
||||
- type: string
|
||||
- required: false
|
||||
type: table
|
28
luneTypes.d.luau
Normal file
28
luneTypes.d.luau
Normal file
|
@ -0,0 +1,28 @@
|
|||
declare fs: {
|
||||
readFile: (path: string) -> string,
|
||||
readDir: (path: string) -> { string },
|
||||
writeFile: (path: string, contents: string) -> (),
|
||||
writeDir: (path: string) -> (),
|
||||
removeFile: (path: string) -> (),
|
||||
removeDir: (path: string) -> (),
|
||||
isFile: (path: string) -> boolean,
|
||||
isDir: (path: string) -> boolean,
|
||||
}
|
||||
|
||||
declare json: {
|
||||
encode: (value: any, pretty: boolean?) -> string,
|
||||
decode: (encoded: string) -> any,
|
||||
}
|
||||
|
||||
declare process: {
|
||||
getEnvVars: () -> { string },
|
||||
getEnvVar: (key: string) -> string?,
|
||||
setEnvVar: (key: string, value: string) -> (),
|
||||
exit: (code: number?) -> (),
|
||||
spawn: (program: string, params: { string }?) -> {
|
||||
ok: boolean,
|
||||
code: number,
|
||||
stdout: string,
|
||||
stderr: string,
|
||||
},
|
||||
}
|
71
scripts/hello_lune.luau
Normal file
71
scripts/hello_lune.luau
Normal file
|
@ -0,0 +1,71 @@
|
|||
print("Hello, lune! 🌙")
|
||||
|
||||
-- Use a function from another module
|
||||
|
||||
local module = require("scripts/module")
|
||||
module.hello()
|
||||
|
||||
-- Read and print out directories & files in
|
||||
-- the current directory, with fancy icons
|
||||
|
||||
print("\nReading current dir...")
|
||||
local entries = fs.readDir(".")
|
||||
|
||||
-- NOTE: We have to do this outside of the sort function
|
||||
-- to avoid yielding across the metamethod boundary, any
|
||||
-- calls to fs functions may yield for any reason
|
||||
local dirs = {}
|
||||
for _, entry in entries do
|
||||
dirs[entry] = fs.isDir(entry)
|
||||
end
|
||||
|
||||
-- Sort directories first, then alphabetically
|
||||
table.sort(entries, function(entry0, entry1)
|
||||
if dirs[entry0] ~= dirs[entry1] then
|
||||
return dirs[entry0]
|
||||
end
|
||||
return entry0 < entry1
|
||||
end)
|
||||
|
||||
assert(table.find(entries, "Cargo.toml") ~= nil, "Missing Cargo.toml")
|
||||
assert(table.find(entries, "Cargo.lock") ~= nil, "Missing Cargo.lock")
|
||||
|
||||
for _, entry in entries do
|
||||
if fs.isDir(entry) then
|
||||
print("📁 " .. entry)
|
||||
else
|
||||
print("📄 " .. entry)
|
||||
end
|
||||
end
|
||||
|
||||
-- Read and print out environment variables
|
||||
|
||||
print("\nReading current environment...")
|
||||
local vars = process.getEnvVars()
|
||||
table.sort(vars)
|
||||
|
||||
assert(table.find(vars, "PATH") ~= nil, "Missing PATH")
|
||||
assert(table.find(vars, "PWD") ~= nil, "Missing PWD")
|
||||
|
||||
for _, key in vars do
|
||||
local value = process.getEnvVar(key)
|
||||
local box = if value and value ~= "" then "✅" else "❌"
|
||||
print(string.format("[%s] %s", box, key))
|
||||
end
|
||||
|
||||
-- Call out to another program
|
||||
|
||||
print("\nSending 4 pings to google...")
|
||||
local result = process.spawn("ping", {
|
||||
"google.com",
|
||||
"-c 4",
|
||||
})
|
||||
|
||||
if result.ok then
|
||||
print(result.stdout)
|
||||
else
|
||||
print(result.stderr)
|
||||
process.exit(result.code)
|
||||
end
|
||||
|
||||
print("\nGoodbye, lune! 🌙")
|
7
scripts/module.luau
Normal file
7
scripts/module.luau
Normal file
|
@ -0,0 +1,7 @@
|
|||
local module = {}
|
||||
|
||||
function module.hello()
|
||||
print("\nHello from a module! 🧩")
|
||||
end
|
||||
|
||||
return module
|
6
selene.toml
Normal file
6
selene.toml
Normal file
|
@ -0,0 +1,6 @@
|
|||
std = "luau+lune"
|
||||
|
||||
exclude = ["luneTypes.d.luau"]
|
||||
|
||||
[lints]
|
||||
high_cyclomatic_complexity = "warn"
|
84
src/cli.rs
Normal file
84
src/cli.rs
Normal file
|
@ -0,0 +1,84 @@
|
|||
use std::{fs::read_to_string, path::PathBuf};
|
||||
|
||||
use clap::Parser;
|
||||
use mlua::{Lua, Result};
|
||||
|
||||
use crate::lune::{fs::LuneFs, json::LuneJson, process::LuneProcess};
|
||||
|
||||
/// Lune CLI
|
||||
#[derive(Parser, Debug)]
|
||||
#[command(author, version, about, long_about = None)]
|
||||
pub struct Cli {
|
||||
/// Path to the file to run
|
||||
path: String,
|
||||
}
|
||||
|
||||
impl Cli {
|
||||
#[allow(dead_code)]
|
||||
pub fn from_path<S: AsRef<str>>(path: S) -> Self {
|
||||
Self {
|
||||
path: path.as_ref().to_owned(),
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_file_path(&self) -> Result<PathBuf> {
|
||||
let parsed_file_path = match &self.path {
|
||||
path if path.ends_with(".luau") || path.ends_with(".lua") => Some(PathBuf::from(path)),
|
||||
path => {
|
||||
let temp_path = PathBuf::from(path);
|
||||
if temp_path.extension().is_none() {
|
||||
let as_luau_path = temp_path.with_extension("luau");
|
||||
let as_lua_path = temp_path.with_extension("lua");
|
||||
if as_luau_path.exists() {
|
||||
Some(as_luau_path)
|
||||
} else if as_lua_path.exists() {
|
||||
Some(as_lua_path)
|
||||
} else {
|
||||
let as_luau_in_scripts_folder = PathBuf::from("scripts").join(as_luau_path);
|
||||
let as_lua_in_scripts_folder = PathBuf::from("scripts").join(as_lua_path);
|
||||
if as_luau_in_scripts_folder.exists() {
|
||||
Some(as_luau_in_scripts_folder)
|
||||
} else if as_lua_in_scripts_folder.exists() {
|
||||
Some(as_lua_in_scripts_folder)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
};
|
||||
if let Some(file_path) = parsed_file_path {
|
||||
if file_path.exists() {
|
||||
Ok(file_path)
|
||||
} else {
|
||||
Err(mlua::Error::RuntimeError(format!(
|
||||
"File does not exist at path: '{}'",
|
||||
self.path
|
||||
)))
|
||||
}
|
||||
} else {
|
||||
Err(mlua::Error::RuntimeError(format!(
|
||||
"Invalid file path: '{}'",
|
||||
self.path
|
||||
)))
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn run(self) -> Result<()> {
|
||||
// Parse and read the wanted file
|
||||
let file_path = self.parse_file_path()?;
|
||||
let file_contents = read_to_string(file_path)?;
|
||||
// Create a new lua state and add in all lune globals
|
||||
let lua = Lua::new();
|
||||
let globals = lua.globals();
|
||||
globals.set("fs", LuneFs::new())?;
|
||||
globals.set("process", LuneProcess::new())?;
|
||||
globals.set("json", LuneJson::new())?;
|
||||
lua.sandbox(true)?;
|
||||
// Run the file
|
||||
lua.load(&file_contents).exec_async().await?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
109
src/lune/fs.rs
Normal file
109
src/lune/fs.rs
Normal file
|
@ -0,0 +1,109 @@
|
|||
use std::path::{PathBuf, MAIN_SEPARATOR};
|
||||
|
||||
use mlua::{Lua, Result, UserData, UserDataMethods};
|
||||
use tokio::fs;
|
||||
|
||||
pub struct LuneFs();
|
||||
|
||||
impl LuneFs {
|
||||
pub fn new() -> Self {
|
||||
Self()
|
||||
}
|
||||
}
|
||||
|
||||
impl UserData for LuneFs {
|
||||
fn add_methods<'lua, M: UserDataMethods<'lua, Self>>(methods: &mut M) {
|
||||
methods.add_async_function("readFile", fs_read_file);
|
||||
methods.add_async_function("readDir", fs_read_dir);
|
||||
methods.add_async_function("writeFile", fs_write_file);
|
||||
methods.add_async_function("writeDir", fs_write_dir);
|
||||
methods.add_async_function("removeFile", fs_remove_file);
|
||||
methods.add_async_function("removeDir", fs_remove_dir);
|
||||
methods.add_async_function("isFile", fs_is_file);
|
||||
methods.add_async_function("isDir", fs_is_dir);
|
||||
}
|
||||
}
|
||||
|
||||
async fn fs_read_file(_: &Lua, path: String) -> Result<String> {
|
||||
Ok(fs::read_to_string(&path)
|
||||
.await
|
||||
.map_err(mlua::Error::external)?)
|
||||
}
|
||||
|
||||
async fn fs_read_dir(_: &Lua, path: String) -> Result<Vec<String>> {
|
||||
let mut dir_strings = Vec::new();
|
||||
let mut dir = fs::read_dir(&path).await.map_err(mlua::Error::external)?;
|
||||
while let Some(dir_entry) = dir.next_entry().await.map_err(mlua::Error::external)? {
|
||||
if let Some(dir_path_str) = dir_entry.path().to_str() {
|
||||
dir_strings.push(dir_path_str.to_owned());
|
||||
} else {
|
||||
return Err(mlua::Error::RuntimeError(format!(
|
||||
"File path could not be converted into a string: '{}'",
|
||||
dir_entry.path().display()
|
||||
)));
|
||||
}
|
||||
}
|
||||
let mut dir_string_prefix = path;
|
||||
if !dir_string_prefix.ends_with(MAIN_SEPARATOR) {
|
||||
dir_string_prefix.push(MAIN_SEPARATOR);
|
||||
}
|
||||
let dir_strings_no_prefix = dir_strings
|
||||
.iter()
|
||||
.map(|inner_path| {
|
||||
inner_path
|
||||
.trim()
|
||||
.strip_prefix(&dir_string_prefix)
|
||||
.unwrap()
|
||||
.to_owned()
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
Ok(dir_strings_no_prefix)
|
||||
}
|
||||
|
||||
async fn fs_write_file(_: &Lua, (path, contents): (String, String)) -> Result<()> {
|
||||
Ok(fs::write(&path, &contents)
|
||||
.await
|
||||
.map_err(mlua::Error::external)?)
|
||||
}
|
||||
|
||||
async fn fs_write_dir(_: &Lua, path: String) -> Result<()> {
|
||||
Ok(fs::create_dir_all(&path)
|
||||
.await
|
||||
.map_err(mlua::Error::external)?)
|
||||
}
|
||||
|
||||
async fn fs_remove_file(_: &Lua, path: String) -> Result<()> {
|
||||
Ok(fs::remove_file(&path)
|
||||
.await
|
||||
.map_err(mlua::Error::external)?)
|
||||
}
|
||||
|
||||
async fn fs_remove_dir(_: &Lua, path: String) -> Result<()> {
|
||||
Ok(fs::remove_dir_all(&path)
|
||||
.await
|
||||
.map_err(mlua::Error::external)?)
|
||||
}
|
||||
|
||||
async fn fs_is_file(_: &Lua, path: String) -> Result<bool> {
|
||||
let path = PathBuf::from(path);
|
||||
if path.exists() {
|
||||
Ok(fs::metadata(path)
|
||||
.await
|
||||
.map_err(mlua::Error::external)?
|
||||
.is_file())
|
||||
} else {
|
||||
Ok(false)
|
||||
}
|
||||
}
|
||||
|
||||
async fn fs_is_dir(_: &Lua, path: String) -> Result<bool> {
|
||||
let path = PathBuf::from(path);
|
||||
if path.exists() {
|
||||
Ok(fs::metadata(path)
|
||||
.await
|
||||
.map_err(mlua::Error::external)?
|
||||
.is_dir())
|
||||
} else {
|
||||
Ok(false)
|
||||
}
|
||||
}
|
28
src/lune/json.rs
Normal file
28
src/lune/json.rs
Normal file
|
@ -0,0 +1,28 @@
|
|||
use mlua::{Error, Lua, LuaSerdeExt, Result, UserData, UserDataMethods, Value};
|
||||
|
||||
pub struct LuneJson();
|
||||
|
||||
impl LuneJson {
|
||||
pub fn new() -> Self {
|
||||
Self()
|
||||
}
|
||||
}
|
||||
|
||||
impl UserData for LuneJson {
|
||||
fn add_methods<'lua, M: UserDataMethods<'lua, Self>>(methods: &mut M) {
|
||||
methods.add_function("encode", json_encode);
|
||||
methods.add_function("decode", json_decode);
|
||||
}
|
||||
}
|
||||
|
||||
fn json_encode(_: &Lua, (val, pretty): (Value, Option<bool>)) -> Result<String> {
|
||||
if let Some(true) = pretty {
|
||||
Ok(serde_json::to_string_pretty(&val).map_err(Error::external)?)
|
||||
} else {
|
||||
Ok(serde_json::to_string(&val).map_err(Error::external)?)
|
||||
}
|
||||
}
|
||||
|
||||
fn json_decode(lua: &Lua, json: String) -> Result<Value> {
|
||||
Ok(lua.to_value(&json)?)
|
||||
}
|
3
src/lune/mod.rs
Normal file
3
src/lune/mod.rs
Normal file
|
@ -0,0 +1,3 @@
|
|||
pub mod fs;
|
||||
pub mod json;
|
||||
pub mod process;
|
93
src/lune/process.rs
Normal file
93
src/lune/process.rs
Normal file
|
@ -0,0 +1,93 @@
|
|||
use std::{
|
||||
env::{self, VarError},
|
||||
process::{exit, Stdio},
|
||||
};
|
||||
|
||||
use mlua::{Error, Lua, Result, Table, UserData, UserDataMethods, Value};
|
||||
use tokio::process::Command;
|
||||
|
||||
pub struct LuneProcess();
|
||||
|
||||
impl LuneProcess {
|
||||
pub fn new() -> Self {
|
||||
Self()
|
||||
}
|
||||
}
|
||||
|
||||
impl UserData for LuneProcess {
|
||||
fn add_methods<'lua, M: UserDataMethods<'lua, Self>>(methods: &mut M) {
|
||||
methods.add_function("getEnvVars", process_get_env_vars);
|
||||
methods.add_function("getEnvVar", process_get_env_var);
|
||||
methods.add_function("setEnvVar", process_set_env_var);
|
||||
methods.add_function("exit", process_exit);
|
||||
methods.add_async_function("spawn", process_spawn);
|
||||
}
|
||||
}
|
||||
|
||||
fn process_get_env_vars(_: &Lua, _: ()) -> Result<Vec<String>> {
|
||||
let mut vars = Vec::new();
|
||||
for (key, _) in env::vars() {
|
||||
vars.push(key);
|
||||
}
|
||||
Ok(vars)
|
||||
}
|
||||
|
||||
fn process_get_env_var(lua: &Lua, key: String) -> Result<Value> {
|
||||
match env::var(&key) {
|
||||
Ok(value) => Ok(Value::String(lua.create_string(&value)?)),
|
||||
Err(VarError::NotPresent) => Ok(Value::Nil),
|
||||
Err(VarError::NotUnicode(_)) => Err(Error::external(format!(
|
||||
"The env var '{}' contains invalid utf8",
|
||||
&key
|
||||
))),
|
||||
}
|
||||
}
|
||||
|
||||
fn process_set_env_var(_: &Lua, (key, value): (String, String)) -> Result<()> {
|
||||
Ok(env::set_var(&key, &value))
|
||||
}
|
||||
|
||||
fn process_exit(_: &Lua, exit_code: Option<i32>) -> Result<()> {
|
||||
if let Some(code) = exit_code {
|
||||
exit(code);
|
||||
} else {
|
||||
exit(0)
|
||||
}
|
||||
}
|
||||
|
||||
async fn process_spawn(lua: &Lua, (program, args): (String, Option<Vec<String>>)) -> Result<Table> {
|
||||
// Create and spawn a child process, and
|
||||
// wait for it to terminate with output
|
||||
let mut cmd = Command::new(program);
|
||||
if let Some(args) = args {
|
||||
cmd.args(args);
|
||||
}
|
||||
let child = cmd
|
||||
.current_dir(env::current_dir().map_err(mlua::Error::external)?)
|
||||
.stdin(Stdio::null())
|
||||
.stdout(Stdio::piped())
|
||||
.stderr(Stdio::piped())
|
||||
.spawn()
|
||||
.map_err(mlua::Error::external)?;
|
||||
let output = child
|
||||
.wait_with_output()
|
||||
.await
|
||||
.map_err(mlua::Error::external)?;
|
||||
// NOTE: Exit code defaults to 1 if it did not exist and if there
|
||||
// is any stderr, will otherwise default to 0 if it did not exist
|
||||
let code = output
|
||||
.status
|
||||
.code()
|
||||
.unwrap_or_else(|| match output.stderr.is_empty() {
|
||||
true => 0,
|
||||
false => 1,
|
||||
});
|
||||
// Construct and return a readonly lua table with results
|
||||
let table = lua.create_table()?;
|
||||
table.raw_set("ok", code == 0)?;
|
||||
table.raw_set("code", code)?;
|
||||
table.raw_set("stdout", lua.create_string(&output.stdout)?)?;
|
||||
table.raw_set("stderr", lua.create_string(&output.stderr)?)?;
|
||||
table.set_readonly(true);
|
||||
Ok(table)
|
||||
}
|
30
src/main.rs
Normal file
30
src/main.rs
Normal file
|
@ -0,0 +1,30 @@
|
|||
use clap::Parser;
|
||||
use mlua::Result;
|
||||
|
||||
mod cli;
|
||||
mod lune;
|
||||
mod utils;
|
||||
|
||||
use cli::Cli;
|
||||
use utils::pretty_print_luau_error;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<()> {
|
||||
let cli = Cli::parse();
|
||||
match cli.run().await {
|
||||
Ok(_) => Ok(()),
|
||||
Err(e) => {
|
||||
eprintln!();
|
||||
eprintln!("[ERROR]");
|
||||
pretty_print_luau_error(&e);
|
||||
std::process::exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn hello_lune() {
|
||||
let cli = Cli::from_path("hello_lune");
|
||||
let result = cli.run().await;
|
||||
assert!(result.is_ok());
|
||||
}
|
33
src/utils.rs
Normal file
33
src/utils.rs
Normal file
|
@ -0,0 +1,33 @@
|
|||
pub fn pretty_print_luau_error(e: &mlua::Error) {
|
||||
match e {
|
||||
mlua::Error::RuntimeError(e) => {
|
||||
eprintln!("{}", e);
|
||||
}
|
||||
mlua::Error::CallbackError { cause, traceback } => {
|
||||
pretty_print_luau_error(cause.as_ref());
|
||||
eprintln!("Traceback:");
|
||||
eprintln!("{}", traceback.strip_prefix("stack traceback:\n").unwrap());
|
||||
}
|
||||
mlua::Error::ToLuaConversionError { from, to, message } => {
|
||||
let msg = message
|
||||
.clone()
|
||||
.map(|m| format!("\nDetails:\n\t{m}"))
|
||||
.unwrap_or_else(|| "".to_string());
|
||||
eprintln!(
|
||||
"Failed to convert Rust type '{}' into Luau type '{}'!{}",
|
||||
from, to, msg
|
||||
)
|
||||
}
|
||||
mlua::Error::FromLuaConversionError { from, to, message } => {
|
||||
let msg = message
|
||||
.clone()
|
||||
.map(|m| format!("\nDetails:\n\t{m}"))
|
||||
.unwrap_or_else(|| "".to_string());
|
||||
eprintln!(
|
||||
"Failed to convert Luau type '{}' into Rust type '{}'!{}",
|
||||
from, to, msg
|
||||
)
|
||||
}
|
||||
e => eprintln!("{}", e.to_string()),
|
||||
}
|
||||
}
|
10
stylua.toml
Normal file
10
stylua.toml
Normal file
|
@ -0,0 +1,10 @@
|
|||
column_width = 100
|
||||
|
||||
line_endings = "Unix"
|
||||
|
||||
indent_type = "Tabs"
|
||||
indent_width = 4
|
||||
|
||||
quote_style = "AutoPreferDouble"
|
||||
|
||||
call_parentheses = "Always"
|
Loading…
Reference in a new issue