diff options
| -rw-r--r-- | .cargo/config.toml | 4 | ||||
| -rw-r--r-- | .run/.gitignore | 7 | ||||
| -rw-r--r-- | .run/Cargo.lock (renamed from dev_tools/Cargo.lock) | 0 | ||||
| -rw-r--r-- | .run/Cargo.toml (renamed from dev_tools/Cargo.toml) | 2 | ||||
| -rw-r--r-- | .run/src/bin/build-all.ps1 (renamed from dev_tools/scripts/build-all.ps1) | 0 | ||||
| -rw-r--r--[-rwxr-xr-x] | .run/src/bin/build-all.sh (renamed from dev_tools/scripts/build-all.sh) | 0 | ||||
| -rw-r--r-- | .run/src/bin/ci.rs (renamed from dev_tools/src/bin/ci.rs) | 0 | ||||
| -rw-r--r-- | .run/src/bin/clippy-fix.ps1 (renamed from dev_tools/scripts/clippy-fix.ps1) | 0 | ||||
| -rw-r--r--[-rwxr-xr-x] | .run/src/bin/clippy-fix.sh (renamed from dev_tools/scripts/clippy-fix.sh) | 0 | ||||
| -rw-r--r-- | .run/src/bin/clippy.ps1 (renamed from dev_tools/scripts/clippy.ps1) | 0 | ||||
| -rw-r--r--[-rwxr-xr-x] | .run/src/bin/clippy.sh (renamed from dev_tools/scripts/clippy.sh) | 0 | ||||
| -rw-r--r--[-rwxr-xr-x] | .run/src/bin/doc.ps1 (renamed from dev_tools/scripts/doc.ps1) | 0 | ||||
| -rw-r--r--[-rwxr-xr-x] | .run/src/bin/doc.sh (renamed from dev_tools/scripts/doc.sh) | 0 | ||||
| -rw-r--r-- | .run/src/bin/docs-code-box-fix.rs (renamed from dev_tools/src/bin/docs-code-box-fix.rs) | 0 | ||||
| -rw-r--r-- | .run/src/bin/docsify-sidebar-gen.rs (renamed from dev_tools/src/bin/docsify-sidebar-gen.rs) | 15 | ||||
| -rw-r--r-- | .run/src/bin/http-page-preview.ps1 (renamed from dev_tools/scripts/http-page-preview.ps1) | 0 | ||||
| -rw-r--r--[-rwxr-xr-x] | .run/src/bin/http-page-preview.sh (renamed from dev_tools/scripts/http-page-preview.sh) | 0 | ||||
| -rw-r--r--[-rwxr-xr-x] | .run/src/bin/install-mling.ps1 (renamed from dev_tools/scripts/install-mling.ps1) | 0 | ||||
| -rw-r--r--[-rwxr-xr-x] | .run/src/bin/install-mling.sh (renamed from dev_tools/scripts/install-mling.sh) | 0 | ||||
| -rw-r--r-- | .run/src/bin/refresh-docs.rs (renamed from dev_tools/src/bin/refresh-docs.rs) | 0 | ||||
| -rw-r--r-- | .run/src/bin/refresh-feature-mod.rs (renamed from dev_tools/src/bin/refresh-feature-mod.rs) | 0 | ||||
| -rw-r--r-- | .run/src/bin/sync-examples.rs (renamed from dev_tools/src/bin/sync-examples.rs) | 0 | ||||
| -rw-r--r-- | .run/src/bin/test-all-markdown-code.rs (renamed from dev_tools/src/bin/test-all-markdown-code.rs) | 0 | ||||
| -rw-r--r-- | .run/src/bin/test-all.ps1 (renamed from dev_tools/scripts/test-all.ps1) | 0 | ||||
| -rw-r--r-- | .run/src/bin/test-all.sh (renamed from dev_tools/scripts/test-all.sh) | 0 | ||||
| -rw-r--r-- | .run/src/bin/test-examples.rs (renamed from dev_tools/src/bin/test-examples.rs) | 0 | ||||
| -rw-r--r-- | .run/src/bin/update-version.rs (renamed from dev_tools/src/bin/update-version.rs) | 0 | ||||
| -rw-r--r-- | .run/src/bin/windows-folder-hide.ps1 (renamed from dev_tools/scripts/windows-folder-hide.ps1) | 0 | ||||
| -rw-r--r-- | .run/src/lib.rs (renamed from dev_tools/src/lib.rs) | 0 | ||||
| -rw-r--r-- | .run/src/verify.rs (renamed from dev_tools/src/verify.rs) | 4 | ||||
| -rw-r--r-- | .run/version-files.toml (renamed from dev_tools/version-files.toml) | 0 | ||||
| -rw-r--r-- | ABOUT-CI.md | 22 | ||||
| -rw-r--r-- | CONTRIBUTING.md | 54 | ||||
| -rw-r--r-- | Cargo.toml | 2 | ||||
| -rw-r--r-- | run-tools.ps1 | 60 | ||||
| -rwxr-xr-x | run-tools.sh | 64 | ||||
| -rw-r--r-- | run.ps1 | 232 | ||||
| -rw-r--r-- | run.sh | 257 |
38 files changed, 547 insertions, 176 deletions
diff --git a/.cargo/config.toml b/.cargo/config.toml index 0b45ca9..f375b03 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -4,5 +4,5 @@ target-dir = "./.temp/target" [env] [alias] -ci = "run --manifest-path dev_tools/Cargo.toml --bin ci --quiet --" -dev_tool = "run --manifest-path dev_tools/Cargo.toml --quiet --bin " +ci = "run --manifest-path .run/Cargo.toml --bin ci --quiet --" +dev_tool = "run --manifest-path .run/Cargo.toml --quiet --bin " diff --git a/.run/.gitignore b/.run/.gitignore new file mode 100644 index 0000000..0dc39b0 --- /dev/null +++ b/.run/.gitignore @@ -0,0 +1,7 @@ +# All temp build artifacts will be stored in this dir +/target + +# If you want to add some Rust crates? Remove this line +# /Cargo.* + +last_check diff --git a/dev_tools/Cargo.lock b/.run/Cargo.lock index bb510bd..bb510bd 100644 --- a/dev_tools/Cargo.lock +++ b/.run/Cargo.lock diff --git a/dev_tools/Cargo.toml b/.run/Cargo.toml index 9855580..283aa47 100644 --- a/dev_tools/Cargo.toml +++ b/.run/Cargo.toml @@ -19,3 +19,5 @@ serde = { version = "1", features = ["derive"] } serde_json = "1" tokio = { version = "1", features = ["rt-multi-thread", "macros"] } indicatif = "0.18.4" + +[workspace] diff --git a/dev_tools/scripts/build-all.ps1 b/.run/src/bin/build-all.ps1 index 4f35ed8..4f35ed8 100644 --- a/dev_tools/scripts/build-all.ps1 +++ b/.run/src/bin/build-all.ps1 diff --git a/dev_tools/scripts/build-all.sh b/.run/src/bin/build-all.sh index 2036b41..2036b41 100755..100644 --- a/dev_tools/scripts/build-all.sh +++ b/.run/src/bin/build-all.sh diff --git a/dev_tools/src/bin/ci.rs b/.run/src/bin/ci.rs index f8aed79..f8aed79 100644 --- a/dev_tools/src/bin/ci.rs +++ b/.run/src/bin/ci.rs diff --git a/dev_tools/scripts/clippy-fix.ps1 b/.run/src/bin/clippy-fix.ps1 index 1d24f92..1d24f92 100644 --- a/dev_tools/scripts/clippy-fix.ps1 +++ b/.run/src/bin/clippy-fix.ps1 diff --git a/dev_tools/scripts/clippy-fix.sh b/.run/src/bin/clippy-fix.sh index 9771ad4..9771ad4 100755..100644 --- a/dev_tools/scripts/clippy-fix.sh +++ b/.run/src/bin/clippy-fix.sh diff --git a/dev_tools/scripts/clippy.ps1 b/.run/src/bin/clippy.ps1 index 1858873..1858873 100644 --- a/dev_tools/scripts/clippy.ps1 +++ b/.run/src/bin/clippy.ps1 diff --git a/dev_tools/scripts/clippy.sh b/.run/src/bin/clippy.sh index b393545..b393545 100755..100644 --- a/dev_tools/scripts/clippy.sh +++ b/.run/src/bin/clippy.sh diff --git a/dev_tools/scripts/doc.ps1 b/.run/src/bin/doc.ps1 index 987f0de..987f0de 100755..100644 --- a/dev_tools/scripts/doc.ps1 +++ b/.run/src/bin/doc.ps1 diff --git a/dev_tools/scripts/doc.sh b/.run/src/bin/doc.sh index 5e8a311..5e8a311 100755..100644 --- a/dev_tools/scripts/doc.sh +++ b/.run/src/bin/doc.sh diff --git a/dev_tools/src/bin/docs-code-box-fix.rs b/.run/src/bin/docs-code-box-fix.rs index 21d2cce..21d2cce 100644 --- a/dev_tools/src/bin/docs-code-box-fix.rs +++ b/.run/src/bin/docs-code-box-fix.rs diff --git a/dev_tools/src/bin/docsify-sidebar-gen.rs b/.run/src/bin/docsify-sidebar-gen.rs index b926112..5beda7f 100644 --- a/dev_tools/src/bin/docsify-sidebar-gen.rs +++ b/.run/src/bin/docsify-sidebar-gen.rs @@ -43,7 +43,7 @@ fn find_all_readmes(dir: &Path) -> Vec<PathBuf> { let path = entry.path(); if path.is_dir() { results.extend(find_all_readmes(&path)); - } else if path.file_name().map_or(false, |n| n == "README.md") { + } else if path.file_name().is_some_and(|n| n == "README.md") { results.push(path); } } @@ -67,11 +67,10 @@ fn find_content_dir(site_root: &Path) -> Option<PathBuf> { entries.sort_by_key(|e| e.path()); for entry in entries { let path = entry.path(); - if path.is_dir() { - if has_markdown_files(&path) { + if path.is_dir() + && has_markdown_files(&path) { return Some(path); } - } } } @@ -254,12 +253,10 @@ fn natural_cmp(a: &str, b: &str) -> std::cmp::Ordering { /// Looks at the filename stem (after the last `/`) for a number before the first `-`. /// Returns `usize::MAX` for entries without a numeric prefix. fn extract_leading_number(link: &str) -> usize { - if let Some(file_stem) = link.rsplit('/').next() { - if let Some(num_end) = file_stem.find('-') { - if let Ok(num) = file_stem[..num_end].parse::<usize>() { + if let Some(file_stem) = link.rsplit('/').next() + && let Some(num_end) = file_stem.find('-') + && let Ok(num) = file_stem[..num_end].parse::<usize>() { return num; } - } - } usize::MAX } diff --git a/dev_tools/scripts/http-page-preview.ps1 b/.run/src/bin/http-page-preview.ps1 index 8cc3579..8cc3579 100644 --- a/dev_tools/scripts/http-page-preview.ps1 +++ b/.run/src/bin/http-page-preview.ps1 diff --git a/dev_tools/scripts/http-page-preview.sh b/.run/src/bin/http-page-preview.sh index bed4b1c..bed4b1c 100755..100644 --- a/dev_tools/scripts/http-page-preview.sh +++ b/.run/src/bin/http-page-preview.sh diff --git a/dev_tools/scripts/install-mling.ps1 b/.run/src/bin/install-mling.ps1 index bebe9ff..bebe9ff 100755..100644 --- a/dev_tools/scripts/install-mling.ps1 +++ b/.run/src/bin/install-mling.ps1 diff --git a/dev_tools/scripts/install-mling.sh b/.run/src/bin/install-mling.sh index 5f2ee7a..5f2ee7a 100755..100644 --- a/dev_tools/scripts/install-mling.sh +++ b/.run/src/bin/install-mling.sh diff --git a/dev_tools/src/bin/refresh-docs.rs b/.run/src/bin/refresh-docs.rs index 82ef906..82ef906 100644 --- a/dev_tools/src/bin/refresh-docs.rs +++ b/.run/src/bin/refresh-docs.rs diff --git a/dev_tools/src/bin/refresh-feature-mod.rs b/.run/src/bin/refresh-feature-mod.rs index 2255dbc..2255dbc 100644 --- a/dev_tools/src/bin/refresh-feature-mod.rs +++ b/.run/src/bin/refresh-feature-mod.rs diff --git a/dev_tools/src/bin/sync-examples.rs b/.run/src/bin/sync-examples.rs index 0923b33..0923b33 100644 --- a/dev_tools/src/bin/sync-examples.rs +++ b/.run/src/bin/sync-examples.rs diff --git a/dev_tools/src/bin/test-all-markdown-code.rs b/.run/src/bin/test-all-markdown-code.rs index 280fca7..280fca7 100644 --- a/dev_tools/src/bin/test-all-markdown-code.rs +++ b/.run/src/bin/test-all-markdown-code.rs diff --git a/dev_tools/scripts/test-all.ps1 b/.run/src/bin/test-all.ps1 index 231698a..231698a 100644 --- a/dev_tools/scripts/test-all.ps1 +++ b/.run/src/bin/test-all.ps1 diff --git a/dev_tools/scripts/test-all.sh b/.run/src/bin/test-all.sh index b387463..b387463 100644 --- a/dev_tools/scripts/test-all.sh +++ b/.run/src/bin/test-all.sh diff --git a/dev_tools/src/bin/test-examples.rs b/.run/src/bin/test-examples.rs index 539459e..539459e 100644 --- a/dev_tools/src/bin/test-examples.rs +++ b/.run/src/bin/test-examples.rs diff --git a/dev_tools/src/bin/update-version.rs b/.run/src/bin/update-version.rs index 475e54b..475e54b 100644 --- a/dev_tools/src/bin/update-version.rs +++ b/.run/src/bin/update-version.rs diff --git a/dev_tools/scripts/windows-folder-hide.ps1 b/.run/src/bin/windows-folder-hide.ps1 index 0ab2632..0ab2632 100644 --- a/dev_tools/scripts/windows-folder-hide.ps1 +++ b/.run/src/bin/windows-folder-hide.ps1 diff --git a/dev_tools/src/lib.rs b/.run/src/lib.rs index d38a156..d38a156 100644 --- a/dev_tools/src/lib.rs +++ b/.run/src/lib.rs diff --git a/dev_tools/src/verify.rs b/.run/src/verify.rs index 2ddff0c..0a4b354 100644 --- a/dev_tools/src/verify.rs +++ b/.run/src/verify.rs @@ -76,10 +76,10 @@ fn parse_single_block(lines: &[&str], start: usize, source_file: &str) -> Option // @@@ lines: strip the prefix and treat as regular Rust code // These lines are hidden in the rendered docs (filtered by a docsify plugin) // but must still compile. - if trimmed.starts_with("@@@") { + if let Some(stripped) = trimmed.strip_prefix("@@@") { in_header = false; // Strip @@@ and optionally one following space - let code = trimmed[3..].trim_start(); + let code = stripped.trim_start(); if code.contains("fn main") { has_main = true; } diff --git a/dev_tools/version-files.toml b/.run/version-files.toml index ca104d2..ca104d2 100644 --- a/dev_tools/version-files.toml +++ b/.run/version-files.toml diff --git a/ABOUT-CI.md b/ABOUT-CI.md index 762fab8..4cbcd6f 100644 --- a/ABOUT-CI.md +++ b/ABOUT-CI.md @@ -1,6 +1,6 @@ # About Mingling CI Process -Mingling's CI process is built into the project, with its execution logic located in `dev_tools/src/bin/ci.rs`. You can run it locally via the `cargo ci` command, which produces the same results as the `CI` workflow in GitHub Actions. +Mingling's CI process is built into the project, with its execution logic located in `.run/src/bin/ci.rs`. You can run it locally via the `cargo ci` command, which produces the same results as the `CI` workflow in GitHub Actions. During development, you can run `cargo ci` at any time to verify that your code hasn't introduced regressions. @@ -10,7 +10,7 @@ An alias is defined in `.cargo/config.toml` at the project root: ```toml [alias] -ci = "run --manifest-path dev_tools/Cargo.toml --bin ci --quiet --" +ci = "run --manifest-path .run/Cargo.toml --bin ci --quiet --" ``` Simply execute: @@ -34,11 +34,11 @@ cargo ci - **Test all examples**: Runs the `test-examples` tool. - **Verify Markdown code blocks compile**: Runs the `test-all-markdown-code` tool to check code blocks in all `*.md` files. See [ABOUT_CODE_VERIFY](docs/_ABOUT_CODE_VERIFY.md) for details. - **Check if documentation is up to date**: Runs the following documentation refresh tools in sequence: - - `docs-code-box-fix` - - `docsify-sidebar-gen` - - `refresh-docs` - - `refresh-feature-mod` - - `sync-examples` + - `docs-code-box-fix` + - `docsify-sidebar-gen` + - `refresh-docs` + - `refresh-feature-mod` + - `sync-examples` - Finally, runs `cargo fmt` to unify code formatting. ### 3. File Normalization @@ -50,11 +50,11 @@ Runs `git add --renormalize .` to ensure file attributes such as line endings co To ensure reproducible CI results, `ci.rs` imposes strict requirements on the workspace state: - If the current workspace is not clean and `--dirty` has not been specified, the script will prompt whether to create a temporary commit: - - The commit message is `[DO NOT PUSH] CI TEMP [DO NOT PUSH]`. - - Use `-y` to auto-confirm without interaction. + - The commit message is `[DO NOT PUSH] CI TEMP [DO NOT PUSH]`. + - Use `-y` to auto-confirm without interaction. - After CI finishes, the script automatically restores the workspace: - - First, `git reset --hard` discards all changes. - - If a temporary commit was created, it then runs `git reset --soft HEAD~1` and unstages everything, restoring the state to before CI started. + - First, `git reset --hard` discards all changes. + - If a temporary commit was created, it then runs `git reset --soft HEAD~1` and unstages everything, restoring the state to before CI started. - If `--dirty` is specified, the temporary commit and the final cleanliness check are skipped. > **Warning**: `git reset --hard` is executed at the end of CI. If you use `--dirty`, ensure you have no unsaved important changes. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d90db4a..e8e4bed 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -6,46 +6,46 @@ Before contributing, we recommend reading [README](README.md) to get an overview ## 1. Project Structure -| Category | Path/Name | Description | -| ---------------------------- | ------------------------- | ------------------------------------------------------------------------------------- | -| **Entry crate** | `mingling/` | Project entry point | -| **Core library** | `mingling_core/` | Imported as an external dependency | -| **Macro library** | `mingling_macros/` | Imported as an external dependency | -| **Examples** | `examples/` | To add expected output tests, modify `examples/test-examples.toml` | -| **Documentation, resources** | `docs/` | All documentation and resource files | -| **Development tools** | `dev_tools/` | Contains scripts and Rust tools | -| Scripts | `dev_tools/scripts/` | Helper `.sh`/`.ps1`/`.py` scripts, executed via `./run-tools.sh` or `.\run-tools.ps1` | -| Rust tools | `dev_tools/src/bin/` | Same as above | -| CI check entry | `dev_tools/src/bin/ci.rs` | Can be invoked directly via `cargo ci` | -| **Scaffolding tool** | `mling/` | Scaffolding tool `mingling-cli` | -| **Temporary files** | `.temp/` | Ignored by `.gitignore` | +| Category | Path/Name | Description | +| ---------------------------- | ------------------------- | ------------------------------------------------------------------------- | +| **Entry crate** | `mingling/` | Project entry point | +| **Core library** | `mingling_core/` | Imported as an external dependency | +| **Macro library** | `mingling_macros/` | Imported as an external dependency | +| **Examples** | `examples/` | To add expected output tests, modify `examples/test-examples.toml` | +| **Documentation, resources** | `docs/` | All documentation and resource files | +| **Development tools** | `.run/src/bin` | Contains scripts and Rust tools | +| Scripts | `.run/src/bin` | Helper `.sh`/`.ps1`/`.py` scripts, executed via `./run.sh` or `.\run.ps1` | +| Rust tools | `dev_tools/src/bin/` | Same as above | +| CI check entry | `dev_tools/src/bin/ci.rs` | Can be invoked directly via `cargo ci` | +| **Scaffolding tool** | `mling/` | Scaffolding tool `mingling-cli` | +| **Temporary files** | `.temp/` | Ignored by `.gitignore` | ## 2. Submission Guide 1. **Pull Request** - - Submit a GitHub Pull Request and @Reviewer **[Weicao-CatilGrass](https://github.com/Weicao-CatilGrass)** for review - - Or send patches to **catil_grass@qq.com** + - Submit a GitHub Pull Request and @Reviewer **[Weicao-CatilGrass](https://github.com/Weicao-CatilGrass)** for review + - Or send patches to **catil_grass@qq.com** 2. **Commit Messages** - - Clearly and concisely describe the changes, no stringent requirements - - Provide more detail for complex changes, keep it brief for simple changes - - But: if you use [Conventional Commits](https://www.conventionalcommits.org/), it would make me even happier :) + - Clearly and concisely describe the changes, no stringent requirements + - Provide more detail for complex changes, keep it brief for simple changes + - But: if you use [Conventional Commits](https://www.conventionalcommits.org/), it would make me even happier :) 3. **CHANGELOG** - - If the submission includes functional changes or fixes, **the PR must include modifications to CHANGELOG.md** to describe the changes - - For minor changes like typo fixes, **CHANGELOG.md modification is not required**, and we will merge faster + - If the submission includes functional changes or fixes, **the PR must include modifications to CHANGELOG.md** to describe the changes + - For minor changes like typo fixes, **CHANGELOG.md modification is not required**, and we will merge faster 4. **Multi-commit PR** - - A PR can contain multiple commits - - However, at least one commit must modify CHANGELOG.md + - A PR can contain multiple commits + - However, at least one commit must modify CHANGELOG.md 5. **Review** - - After submission, please notify [Weicao-CatilGrass](https://github.com/Weicao-CatilGrass) for review — this is the most efficient way to get feedback + - After submission, please notify [Weicao-CatilGrass](https://github.com/Weicao-CatilGrass) for review — this is the most efficient way to get feedback 6. **Binary Resources** - - For binary resource files (images, etc.), please be cautious about adding them to avoid repository bloat + - For binary resource files (images, etc.), please be cautious about adding them to avoid repository bloat ## 3. Documentation Contribution @@ -60,11 +60,11 @@ After editing documentation, refresh relevant files: ```bash # Refresh sidebar and README sync -./run-tools.sh docsify-sidebar-gen -./run-tools.sh refresh-docs +./run.sh docsify-sidebar-gen +./run.sh refresh-docs # Fix code block blank line issues -./run-tools.sh docs-code-box-fix +./run.sh docs-code-box-fix ``` These steps are included in `cargo ci`; running `cargo ci` will execute them automatically. @@ -9,7 +9,7 @@ exclude = [ "examples/*", # Dev Tools - "dev_tools", + ".run", # Tests "mingling_core/tests/*", diff --git a/run-tools.ps1 b/run-tools.ps1 deleted file mode 100644 index 7aa2c9c..0000000 --- a/run-tools.ps1 +++ /dev/null @@ -1,60 +0,0 @@ -Set-Location -Path (Split-Path -Parent $MyInvocation.MyCommand.Path) -ErrorAction Stop - -# Collect all available tool names -$tools = @() - -if (Test-Path "dev_tools/scripts") { - $scripts = Get-ChildItem -Path "dev_tools/scripts/*.ps1", "dev_tools/scripts/*.py" - foreach ($script in $scripts) { - if ($script -is [System.IO.FileInfo]) { - $tools += $script.BaseName - } - } -} -if (Test-Path "dev_tools/src/bin") { - $files = Get-ChildItem -Path "dev_tools/src/bin/*.rs" - foreach ($file in $files) { - if ($file -is [System.IO.FileInfo]) { - $tools += $file.BaseName - } - } -} - -if ($args.Count -eq 0) { - Write-Host "Available:" - for ($i = 0; $i -lt $tools.Count; $i++) { - Write-Host (" [{0,2}] {1}" -f ($i + 1), $tools[$i]) - } - exit 1 -} - -$target_name = $args[0] - -# Check if input is a number -if ($target_name -match '^\d+$') { - $idx = [int]$target_name - 1 - if ($idx -ge 0 -and $idx -lt $tools.Count) { - $target_name = $tools[$idx] - } else { - Write-Host "Error: invalid number '$target_name', valid range is 1-$($tools.Count)" - exit 1 - } -} - -# Collect remaining arguments to pass to the script -$script_args = $args[1..$args.Count] - -$script_file_ps1 = "dev_tools/scripts/${target_name}.ps1" -$script_file_py = "dev_tools/scripts/${target_name}.py" -$rust_file = "dev_tools/src/bin/${target_name}.rs" - -if (Test-Path $script_file_ps1) { - & $script_file_ps1 $script_args -} elseif (Test-Path $script_file_py) { - python $script_file_py $script_args -} elseif (Test-Path $rust_file) { - cargo run --manifest-path dev_tools/Cargo.toml --bin $target_name --quiet -- $script_args -} else { - Write-Host "Error: target '$target_name' does not exist as a script or Rust program" - exit 1 -} diff --git a/run-tools.sh b/run-tools.sh deleted file mode 100755 index 9a68f0e..0000000 --- a/run-tools.sh +++ /dev/null @@ -1,64 +0,0 @@ -#!/bin/bash - -cd "$(dirname "$0")" || exit 1 - -# Collect all available tool names -tools=() - -if [ -d "dev_tools/scripts" ]; then - for file in dev_tools/scripts/*.sh; do - if [ -f "$file" ]; then - tools+=("$(basename "$file" .sh)") - fi - done - for file in dev_tools/scripts/*.py; do - if [ -f "$file" ]; then - tools+=("$(basename "$file" .py)") - fi - done -fi -if [ -d "dev_tools/src/bin" ]; then - for file in dev_tools/src/bin/*.rs; do - if [ -f "$file" ]; then - tools+=("$(basename "$file" .rs)") - fi - done -fi - -if [ $# -eq 0 ]; then - echo "Available:" - for i in "${!tools[@]}"; do - printf " [%2d] %s\n" $((i + 1)) "${tools[$i]}" - done - exit 1 -fi - -target_bin="$1" -shift # Remove the first argument (tool name), keep the rest as tool arguments - -# Check if input is a number -if [[ "$target_bin" =~ ^[0-9]+$ ]]; then - idx=$((target_bin - 1)) - if [ "$idx" -ge 0 ] && [ "$idx" -lt "${#tools[@]}" ]; then - target_bin="${tools[$idx]}" - else - echo "Error: invalid number '$target_bin', valid range is 1-${#tools[@]}" - exit 1 - fi -fi - -target_script="dev_tools/scripts/${target_bin}.sh" -target_python="dev_tools/scripts/${target_bin}.py" -target_file="dev_tools/src/bin/${target_bin}.rs" - -if [ -f "$target_script" ]; then - chmod +x "$target_script" - "$target_script" "$@" -elif [ -f "$target_python" ]; then - python "$target_python" "$@" -elif [ -f "$target_file" ]; then - cargo run --manifest-path dev_tools/Cargo.toml --bin "$target_bin" --quiet -- "$@" -else - echo "Error: target '$target_bin' does not exist" - exit 1 -fi @@ -0,0 +1,232 @@ +# +# ██ ██████ ██ ██ ███ ██ ██████ ███████ ██ +# ██ ██ ██ ██ ██ ████ ██ ██ ██ ██ ███ +# ██ ██████ ██ ██ ██ ██ ██ ██████ ███████ ██ +# ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ +# ██ ██ ██ ██ ██████ ██ ████ ██ ██ ███████ ██ +# +# You can go to [https://catilgrass.github.io/run] to install it +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Set-Location -Path (Split-Path -Parent $MyInvocation.MyCommand.Path) -ErrorAction Stop + +$tools = @{} + +if (Test-Path ".run/src/bin/*.ps1") { + Get-ChildItem -Path ".run/src/bin/*.ps1" | ForEach-Object { + $tools[$_.BaseName] = @{ Type = "ps1"; Path = $_.FullName } + } +} + +if (Test-Path ".run/src/bin/*.cs") { + Get-ChildItem -Path ".run/src/bin/*.cs" | ForEach-Object { + $tools[$_.BaseName] = @{ Type = "cs"; Path = $_.FullName } + } +} + +if (Test-Path ".run/src/bin/*.exe") { + Get-ChildItem -Path ".run/src/bin/*.exe" | ForEach-Object { + $tools[$_.BaseName] = @{ Type = "exe"; Path = $_.FullName } + } +} + +if (Test-Path ".run/src/bin/*.go") { + Get-ChildItem -Path ".run/src/bin/*.go" | ForEach-Object { + $tools[$_.BaseName] = @{ Type = "go"; Path = $_.FullName } + } +} + +if (Test-Path ".run/src/bin/*.nim") { + Get-ChildItem -Path ".run/src/bin/*.nim" | ForEach-Object { + $tools[$_.BaseName] = @{ Type = "nim"; Path = $_.FullName } + } +} + +if (Test-Path ".run/src/bin/*.pl") { + Get-ChildItem -Path ".run/src/bin/*.pl" | ForEach-Object { + $tools[$_.BaseName] = @{ Type = "pl"; Path = $_.FullName } + } +} + +if (Test-Path ".run/src/bin/*.py") { + Get-ChildItem -Path ".run/src/bin/*.py" | ForEach-Object { + $tools[$_.BaseName] = @{ Type = "py"; Path = $_.FullName } + } +} + +if (Test-Path ".run/src/bin/*.rb") { + Get-ChildItem -Path ".run/src/bin/*.rb" | ForEach-Object { + $tools[$_.BaseName] = @{ Type = "rb"; Path = $_.FullName } + } +} + +if (Test-Path ".run/src/bin/*.rs") { + Get-ChildItem -Path ".run/src/bin/*.rs" | ForEach-Object { + $tools[$_.BaseName] = @{ Type = "rs"; Path = $_.FullName } + } +} + +if (Test-Path ".run/src/bin/*.zig") { + Get-ChildItem -Path ".run/src/bin/*.zig" | ForEach-Object { + $tools[$_.BaseName] = @{ Type = "zig"; Path = $_.FullName } + } +} + +if ($args.Count -eq 0) { + $sorted = @($tools.Keys | Sort-Object @{Expression={if ($tools[$_].Type -eq 'ps1') {0} else {1}}}, {$_}) + $total = $sorted.Count + $num_w = $total.ToString().Length + + $max_name = ($sorted | ForEach-Object { $_.Length } | Measure-Object -Maximum).Maximum + + $inner_w = 2 + $num_w + 1 + 1 + $max_name + 2 + 10 + 1 + 2 + if ($inner_w -lt 38) { $inner_w = 38 } + + $title = '.\run.ps1 <NUMBER/NAME> [ARGS...]' + $title_len = $title.Length + $dash_total = $inner_w - 2 - $title_len + $dash_left = [Math]::Floor($dash_total / 2) + $dash_right = $dash_total - $dash_left + + Write-Host ("┌" + ("─" * $dash_left) + " " + $title + " " + ("─" * $dash_right) + "┐") + Write-Host ("│" + (" " * $inner_w) + "│") + + $i = 1 + foreach ($name in $sorted) { + $type = $tools[$name].Type + $lang = switch ($type) { + "ps1" { "PowerShell" } + "cs" { "C#" } + "exe" { "Binary" } + "go" { "Go" } + "nim" { "Nim" } + "pl" { "Perl" } + "py" { "Python" } + "rb" { "Ruby" } + "rs" { "Rust" } + "zig" { "Zig" } + } + $displayName = $name -replace '[_\-]', ' ' + $entry = " " + $i.ToString().PadRight($num_w) + ") " + $displayName.PadRight($max_name) + " [$lang]" + Write-Host ("│" + $entry.PadRight($inner_w) + "│") + $i++ + } + + Write-Host ("│" + (" " * $inner_w) + "│") + Write-Host ("└" + ("─" * $inner_w) + "┘") + exit 1 +} + +$target_name = $args[0] + +if ($target_name -match '^\d+$') { + $sorted = @($tools.Keys | Sort-Object @{Expression={if ($tools[$_].Type -eq 'ps1') {0} else {1}}}, {$_}) + $idx = [int]$target_name - 1 + if ($idx -ge 0 -and $idx -lt $sorted.Count) { + $target_name = $sorted[$idx] + } else { + Write-Host "Error: invalid number '$target_name', valid range is 1-$($sorted.Count)" + exit 1 + } +} + +if (-not $tools.ContainsKey($target_name)) { + $normalized = $target_name.ToLower() -replace '[ _\-\.]', '' + $found = $null + foreach ($key in $tools.Keys) { + $keyNormalized = $key.ToLower() -replace '[ _\-\.]', '' + if ($normalized -eq $keyNormalized) { + $found = $key + break + } + } + if ($found) { + $target_name = $found + } else { + Write-Host "Error: target '$target_name' does not exist" + exit 1 + } +} + +$script_args = $args[1..$args.Count] +$info = $tools[$target_name] + +switch ($info.Type) { + "ps1" { + & $info.Path @script_args + } + "cs" { + $temp_dir = ".run/target/csproj/$target_name" + $null = New-Item -ItemType Directory -Path $temp_dir -Force + + $props_content = @' +<Project> + <PropertyGroup> + <BaseOutputPath>$(MSBuildThisFileDirectory)../../csharp/bin</BaseOutputPath> + <BaseIntermediateOutputPath>$(MSBuildThisFileDirectory)../../csharp/obj</BaseIntermediateOutputPath> + </PropertyGroup> +</Project> +'@ + Set-Content -Path "$temp_dir/Directory.Build.props" -Value $props_content + + $csproj_content = @" +<Project Sdk="Microsoft.NET.Sdk"> + + <PropertyGroup> + <OutputType>Exe</OutputType> + <TargetFramework>net8.0</TargetFramework> + <ImplicitUsings>enable</ImplicitUsings> + <Nullable>enable</Nullable> + </PropertyGroup> + +</Project> +"@ + Set-Content -Path "$temp_dir/$target_name.csproj" -Value $csproj_content + Copy-Item -Path $info.Path -Destination "$temp_dir/Program.cs" -Force + + dotnet run --project "$temp_dir/$target_name.csproj" -- $script_args + } + "exe" { + & $info.Path $script_args + } + "go" { + go run $info.Path $script_args + } + "nim" { + nim r --hints:off $info.Path $script_args + } + "pl" { + perl $info.Path $script_args + } + "py" { + python $info.Path $script_args + } + "rb" { + ruby $info.Path $script_args + } + "rs" { + if (-not (Test-Path ".run/Cargo.toml")) { +@" +[package] +name = "run_rust" +version = "0.1.0" +edition = "2024" + +[workspace] + +[dependencies] +"@ | Set-Content -Path ".run/Cargo.toml" + } + cargo build --manifest-path ".run/Cargo.toml" --target-dir ".run/target" --bin $target_name --quiet + $binary = ".run/target/debug/$target_name.exe" + if (-not (Test-Path $binary)) { + $binary = ".run/target/debug/$target_name" + } + & $binary $script_args + } + "zig" { + zig run $info.Path $script_args + } +} + +exit $LASTEXITCODE @@ -0,0 +1,257 @@ +#!/bin/bash + +# +# ██ ██████ ██ ██ ███ ██ ███████ ██ ██ +# ██ ██ ██ ██ ██ ████ ██ ██ ██ ██ +# ██ ██████ ██ ██ ██ ██ ██ ███████ ███████ +# ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ +# ██ ██ ██ ██ ██████ ██ ████ ██ ███████ ██ ██ +# +# You can go to [https://catilgrass.github.io/run] to install it +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +cd "$(dirname "$0")" || exit 1 + +declare -A tools + +for file in .run/src/bin/*.sh; do + if [ -f "$file" ]; then + name=$(basename "$file" .sh) + tools["$name"]="sh" + fi +done + +for file in .run/src/bin/*; do + if [ -f "$file" ]; then + name=$(basename "$file") + if [[ ! "$name" == *.* ]]; then + tools["$name"]="binary" + fi + fi +done + +for file in .run/src/bin/*.cs; do + if [ -f "$file" ]; then + name=$(basename "$file" .cs) + tools["$name"]="cs" + fi +done + +for file in .run/src/bin/*.go; do + if [ -f "$file" ]; then + name=$(basename "$file" .go) + tools["$name"]="go" + fi +done + +for file in .run/src/bin/*.nim; do + if [ -f "$file" ]; then + name=$(basename "$file" .nim) + tools["$name"]="nim" + fi +done + +for file in .run/src/bin/*.pl; do + if [ -f "$file" ]; then + name=$(basename "$file" .pl) + tools["$name"]="pl" + fi +done + +for file in .run/src/bin/*.py; do + if [ -f "$file" ]; then + name=$(basename "$file" .py) + tools["$name"]="py" + fi +done + +for file in .run/src/bin/*.rb; do + if [ -f "$file" ]; then + name=$(basename "$file" .rb) + tools["$name"]="rb" + fi +done + +for file in .run/src/bin/*.rs; do + if [ -f "$file" ]; then + name=$(basename "$file" .rs) + tools["$name"]="rs" + fi +done + +for file in .run/src/bin/*.zig; do + if [ -f "$file" ]; then + name=$(basename "$file" .zig) + tools["$name"]="zig" + fi +done + +if [ $# -eq 0 ]; then + sorted_names=($( + for name in "${!tools[@]}"; do + if [ "${tools[$name]}" = "sh" ]; then + echo "0 $name" + else + echo "1 $name" + fi + done | sort | while read -r _ n; do echo "$n"; done + )) + total=${#sorted_names[@]} + num_w=${#total} + + max_name=0 + for name in "${sorted_names[@]}"; do + len=${#name} + ((len > max_name)) && max_name=$len + done + + inner_w=$((2 + num_w + 1 + 1 + max_name + 2 + 6 + 1 + 2)) + ((inner_w < 38)) && inner_w=38 + + title="./run.sh <NUMBER/NAME> [ARGS...]" + title_len=${#title} + dash_total=$((inner_w - 2 - title_len)) + dash_left=$((dash_total / 2)) + dash_right=$((dash_total - dash_left)) + + echo "┌$(printf '─%.0s' $(seq 1 $dash_left)) $title $(printf '─%.0s' $(seq 1 $dash_right))┐" + printf "│%*s│\n" $inner_w "" + + i=1 + for name in "${sorted_names[@]}"; do + type="${tools[$name]}" + case "$type" in + sh) lang="Shell";; + binary) lang="Binary";; + cs) lang="C#";; + go) lang="Go";; + nim) lang="Nim";; + pl) lang="Perl";; + py) lang="Python";; + rb) lang="Ruby";; + rs) lang="Rust";; + zig) lang="Zig";; + esac + display_name=$(echo "$name" | tr '_-' ' ') + entry=$(printf " %-*d) %-*s [%s]" $num_w $i $max_name "$display_name" $lang) + printf "│%-*s│\n" $inner_w "$entry" + i=$((i + 1)) + done + + printf "│%*s│\n" $inner_w "" + echo "└$(printf '─%.0s' $(seq 1 $inner_w))┘" + exit 1 +fi + +target_name="$1" +shift + +if [[ "$target_name" =~ ^[0-9]+$ ]]; then + sorted=($( + for name in "${!tools[@]}"; do + if [ "${tools[$name]}" = "sh" ]; then + echo "0 $name" + else + echo "1 $name" + fi + done | sort | while read -r _ n; do echo "$n"; done + )) + idx=$((target_name - 1)) + if [ "$idx" -ge 0 ] && [ "$idx" -lt "${#sorted[@]}" ]; then + target_name="${sorted[$idx]}" + else + echo "Error: invalid number '$target_name', valid range is 1-${#sorted[@]}" + exit 1 + fi +fi + +if [ -z "${tools[$target_name]}" ]; then + normalized_user=$(echo "$target_name" | tr '[:upper:]' '[:lower:]' | sed 's/[_. -]//g') + found="" + for existing_name in "${!tools[@]}"; do + normalized_existing=$(echo "$existing_name" | tr '[:upper:]' '[:lower:]' | sed 's/[_. -]//g') + if [ "$normalized_user" = "$normalized_existing" ]; then + found="$existing_name" + break + fi + done + if [ -n "$found" ]; then + target_name="$found" + else + echo "Error: target '$target_name' does not exist" + exit 1 + fi +fi + +type="${tools[$target_name]}" + +case "$type" in + sh) + chmod +x ".run/src/bin/$target_name.sh" + ".run/src/bin/$target_name.sh" "$@" + ;; + binary) + chmod +x ".run/src/bin/$target_name" + ".run/src/bin/$target_name" "$@" + ;; + cs) + temp_dir=".run/target/csproj/$target_name" + mkdir -p "$temp_dir" + cat > "$temp_dir/Directory.Build.props" <<'PROPS' +<Project> + <PropertyGroup> + <BaseOutputPath>$(MSBuildThisFileDirectory)../../csharp/bin</BaseOutputPath> + <BaseIntermediateOutputPath>$(MSBuildThisFileDirectory)../../csharp/obj</BaseIntermediateOutputPath> + </PropertyGroup> +</Project> +PROPS + cat > "$temp_dir/$target_name.csproj" <<'CSPROJ' +<Project Sdk="Microsoft.NET.Sdk"> + + <PropertyGroup> + <OutputType>Exe</OutputType> + <TargetFramework>net8.0</TargetFramework> + <ImplicitUsings>enable</ImplicitUsings> + <Nullable>enable</Nullable> + </PropertyGroup> + +</Project> +CSPROJ + cp ".run/src/bin/$target_name.cs" "$temp_dir/Program.cs" + dotnet run --project "$temp_dir/$target_name.csproj" -- "$@" + ;; + go) + go run ".run/src/bin/$target_name.go" "$@" + ;; + nim) + nim r --hints:off ".run/src/bin/$target_name.nim" "$@" + ;; + pl) + perl ".run/src/bin/$target_name.pl" "$@" + ;; + py) + python ".run/src/bin/$target_name.py" "$@" + ;; + rb) + ruby ".run/src/bin/$target_name.rb" "$@" + ;; + rs) + if [ ! -f ".run/Cargo.toml" ]; then + cat > ".run/Cargo.toml" <<'EOF' +[package] +name = "run_rust" +version = "0.1.0" +edition = "2024" + +[workspace] + +[dependencies] +EOF + fi + cargo build --manifest-path ".run/Cargo.toml" --target-dir ".run/target" --bin "$target_name" --quiet + ".run/target/debug/$target_name" "$@" + ;; + zig) + zig run ".run/src/bin/$target_name.zig" "$@" + ;; +esac |
