Skip to content

Commit 93bbe6d

Browse files
authored
feat(cli): andromeda satellites (#192)
1 parent 0dbcc88 commit 93bbe6d

File tree

12 files changed

+413
-15
lines changed

12 files changed

+413
-15
lines changed

.github/workflows/release.yml

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,15 @@ jobs:
7979
# PKG_CONFIG settings for cross-compilation
8080
PKG_CONFIG_ALLOW_CROSS: 1
8181

82-
- name: Build installer
82+
- name: Build satellites
8383
continue-on-error: true # Allow individual builds to fail
84-
run: cargo build --bin andromeda-installer --release --target ${{ matrix.rust-target }} --manifest-path ./cli/Cargo.toml
84+
run: |
85+
cargo build --bin andromeda-run --release --target ${{ matrix.rust-target }} --manifest-path ./cli/Cargo.toml
86+
cargo build --bin andromeda-compile --release --target ${{ matrix.rust-target }} --manifest-path ./cli/Cargo.toml
87+
cargo build --bin andromeda-fmt --release --target ${{ matrix.rust-target }} --manifest-path ./cli/Cargo.toml
88+
cargo build --bin andromeda-lint --release --target ${{ matrix.rust-target }} --manifest-path ./cli/Cargo.toml
89+
cargo build --bin andromeda-check --release --target ${{ matrix.rust-target }} --manifest-path ./cli/Cargo.toml
90+
cargo build --bin andromeda-bundle --release --target ${{ matrix.rust-target }} --manifest-path ./cli/Cargo.toml
8591
env:
8692
# Cross-compilation environment variables
8793
CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER: aarch64-linux-gnu-gcc
@@ -103,15 +109,18 @@ jobs:
103109
exit 1
104110
fi
105111
106-
# Prepare installer binary
107-
if [ -f "andromeda-installer.exe" ]; then
108-
mv andromeda-installer.exe ${{ matrix.installer-name }}
109-
elif [ -f "andromeda-installer" ]; then
110-
mv andromeda-installer ${{ matrix.installer-name }}
111-
else
112-
echo "Installer binary not found, build may have failed"
113-
exit 1
114-
fi
112+
# Prepare satellite binaries
113+
for satellite in run compile fmt lint check bundle; do
114+
if [ -f "andromeda-${satellite}.exe" ]; then
115+
# Windows binaries
116+
cp "andromeda-${satellite}.exe" "andromeda-${satellite}-${{ matrix.rust-target }}.exe"
117+
elif [ -f "andromeda-${satellite}" ]; then
118+
# Unix binaries
119+
cp "andromeda-${satellite}" "andromeda-${satellite}-${{ matrix.rust-target }}"
120+
else
121+
echo "Warning: andromeda-${satellite} binary not found"
122+
fi
123+
done
115124
116125
- name: Upload Binary as Artifact
117126
uses: actions/upload-artifact@v4
@@ -127,6 +136,19 @@ jobs:
127136
name: ${{ matrix.installer-name }}
128137
path: target/${{ matrix.rust-target }}/release/${{ matrix.installer-name }}
129138

139+
- name: Upload Satellite Binaries as Artifacts
140+
uses: actions/upload-artifact@v4
141+
if: success()
142+
with:
143+
name: satellites-${{ matrix.rust-target }}
144+
path: |
145+
target/${{ matrix.rust-target }}/release/andromeda-run-${{ matrix.rust-target }}*
146+
target/${{ matrix.rust-target }}/release/andromeda-compile-${{ matrix.rust-target }}*
147+
target/${{ matrix.rust-target }}/release/andromeda-fmt-${{ matrix.rust-target }}*
148+
target/${{ matrix.rust-target }}/release/andromeda-lint-${{ matrix.rust-target }}*
149+
target/${{ matrix.rust-target }}/release/andromeda-check-${{ matrix.rust-target }}*
150+
target/${{ matrix.rust-target }}/release/andromeda-bundle-${{ matrix.rust-target }}*
151+
130152
release:
131153
name: Create Release
132154
needs: build

Cargo.lock

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ authors = ["the Andromeda team"]
77
edition = "2024"
88
license = "Mozilla Public License 2.0"
99
repository = "https://github.com/tryandromeda/andromeda"
10-
version = "0.1.0-draft52"
10+
version = "0.1.0"
1111

1212
[workspace.dependencies]
1313
andromeda-core = { path = "core" }

README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,19 @@ or disabled as needed:
387387
| **URL** | URL parsing and manipulation | `URL`, `URLSearchParams` |
388388
| **Web** | Web standards | `TextEncoder`, `TextDecoder`, `navigator`, `queueMicrotask()` |
389389

390+
## Andromeda Satellites 🛰️
391+
392+
**Satellites** are minimal, purpose-built executables designed for containerized environments and microservice architectures. Each satellite focuses on a single capability, providing smaller container images, faster startup times, and better resource utilization.
393+
394+
### Available Satellites
395+
396+
- **🚀 andromeda-run** - Execute JavaScript/TypeScript in production containers
397+
- **🔨 andromeda-compile** - Compile JS/TS to executables
398+
- **💅 andromeda-fmt** - Format code
399+
- **🔍 andromeda-lint** - Lint code for quality issues
400+
- **✅ andromeda-check** - Type-check TypeScript
401+
- **📦 andromeda-bundle** - Bundle and minify code
402+
390403
## Crates
391404

392405
| Crate | Description |

cli/Cargo.toml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ hotpath-ci = ["hotpath/hotpath-ci"]
2020
[lib]
2121
name = "andromeda"
2222
path = "src/lib.rs"
23+
crate-type = ["rlib"]
2324

2425
[[bin]]
2526
name = "andromeda"
@@ -33,6 +34,31 @@ path = "src/bin/wpt.rs"
3334
name = "andromeda-installer"
3435
path = "src/bin/installer.rs"
3536

37+
# Andromeda Satellites - Minimal executables for specific tasks
38+
[[bin]]
39+
name = "andromeda-run"
40+
path = "src/bin/satellite_run.rs"
41+
42+
[[bin]]
43+
name = "andromeda-compile"
44+
path = "src/bin/satellite_compile.rs"
45+
46+
[[bin]]
47+
name = "andromeda-fmt"
48+
path = "src/bin/satellite_fmt.rs"
49+
50+
[[bin]]
51+
name = "andromeda-lint"
52+
path = "src/bin/satellite_lint.rs"
53+
54+
[[bin]]
55+
name = "andromeda-check"
56+
path = "src/bin/satellite_check.rs"
57+
58+
[[bin]]
59+
name = "andromeda-bundle"
60+
path = "src/bin/satellite_bundle.rs"
61+
3662
[dependencies]
3763
clap.workspace = true
3864
clap_complete.workspace = true

cli/src/bin/satellite_bundle.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
2+
// If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
3+
4+
/// Andromeda Satellite - Bundle
5+
///
6+
/// A minimal executable focused solely on bundling and minifying JavaScript/TypeScript files.
7+
/// Designed for container instances where only bundling capability is needed.
8+
use andromeda::{CliError, CliResult};
9+
use clap::Parser as ClapParser;
10+
use std::path::PathBuf;
11+
12+
#[derive(Debug, ClapParser)]
13+
#[command(name = "andromeda-bundle")]
14+
#[command(about = "Andromeda Satellite - Bundle and minify JavaScript/TypeScript")]
15+
#[command(version = env!("CARGO_PKG_VERSION"))]
16+
struct Cli {
17+
/// The input file to bundle
18+
#[arg(required = true)]
19+
input: PathBuf,
20+
21+
/// The output file to write the bundled code
22+
#[arg(required = true)]
23+
output: PathBuf,
24+
}
25+
26+
fn main() -> CliResult<()> {
27+
andromeda::error::init_error_reporting();
28+
29+
let cli = Cli::parse();
30+
31+
andromeda::bundle::bundle(cli.input.to_str().unwrap(), cli.output.to_str().unwrap())
32+
.map_err(|e| CliError::TestExecution(format!("Bundle failed: {e}")))?;
33+
34+
println!("✅ Successfully bundled and minified to {:?}", cli.output);
35+
36+
Ok(())
37+
}

cli/src/bin/satellite_check.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
2+
// If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
3+
4+
/// Andromeda Satellite - Check
5+
///
6+
/// A minimal executable focused solely on type-checking TypeScript files.
7+
/// Designed for container instances where only type-checking capability is needed.
8+
use andromeda::{CliError, CliResult};
9+
use clap::Parser as ClapParser;
10+
use std::path::PathBuf;
11+
12+
#[derive(Debug, ClapParser)]
13+
#[command(name = "andromeda-check")]
14+
#[command(about = "Andromeda Satellite - Type-check TypeScript files")]
15+
#[command(version = env!("CARGO_PKG_VERSION"))]
16+
struct Cli {
17+
/// The file(s) or directory(ies) to type-check
18+
#[arg(required = false)]
19+
paths: Vec<PathBuf>,
20+
}
21+
22+
fn main() -> CliResult<()> {
23+
andromeda::error::init_error_reporting();
24+
25+
let cli = Cli::parse();
26+
27+
let config = andromeda::config::ConfigManager::load_or_default(None);
28+
29+
andromeda::check::check_files_with_config(&cli.paths, Some(config))
30+
.map_err(|e| CliError::TestExecution(format!("{e}")))?;
31+
32+
Ok(())
33+
}

cli/src/bin/satellite_compile.rs

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
2+
// If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
3+
4+
/// Andromeda Satellite - Compile
5+
///
6+
/// A minimal executable focused solely on compiling JavaScript/TypeScript files into executables.
7+
/// Designed for container instances where only compilation capability is needed.
8+
use andromeda::{CliError, CliResult};
9+
use clap::Parser as ClapParser;
10+
use std::path::PathBuf;
11+
12+
#[derive(Debug, ClapParser)]
13+
#[command(name = "andromeda-compile")]
14+
#[command(about = "Andromeda Satellite - Compile JavaScript/TypeScript to executable")]
15+
#[command(version = env!("CARGO_PKG_VERSION"))]
16+
struct Cli {
17+
/// The path of the file to compile
18+
#[arg(required = true)]
19+
path: PathBuf,
20+
21+
/// The output binary location
22+
#[arg(required = true)]
23+
out: PathBuf,
24+
25+
/// Enable verbose output in the compiled binary
26+
#[arg(short, long)]
27+
verbose: bool,
28+
29+
/// Disable strict mode in the compiled binary
30+
#[arg(short = 's', long)]
31+
no_strict: bool,
32+
}
33+
34+
fn main() -> CliResult<()> {
35+
andromeda::error::init_error_reporting();
36+
37+
let cli = Cli::parse();
38+
39+
andromeda::compile::compile(
40+
cli.out.as_path(),
41+
cli.path.as_path(),
42+
cli.verbose,
43+
cli.no_strict,
44+
)
45+
.map_err(|e| CliError::TestExecution(format!("Compilation failed: {e}")))?;
46+
47+
let mut config_info = Vec::new();
48+
if cli.verbose {
49+
config_info.push("verbose mode enabled");
50+
}
51+
if cli.no_strict {
52+
config_info.push("strict mode disabled");
53+
}
54+
let config_str = if !config_info.is_empty() {
55+
format!(" ({})", config_info.join(", "))
56+
} else {
57+
String::new()
58+
};
59+
60+
println!(
61+
"✅ Successfully created the output binary at {:?}{}",
62+
cli.out, config_str
63+
);
64+
65+
Ok(())
66+
}

cli/src/bin/satellite_fmt.rs

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
2+
// If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
3+
4+
/// Andromeda Satellite - Format
5+
///
6+
/// A minimal executable focused solely on formatting JavaScript/TypeScript files.
7+
/// Designed for container instances where only formatting capability is needed.
8+
use andromeda::{CliError, CliResult};
9+
use clap::Parser as ClapParser;
10+
use console::Style;
11+
use std::path::PathBuf;
12+
13+
#[derive(Debug, ClapParser)]
14+
#[command(name = "andromeda-fmt")]
15+
#[command(about = "Andromeda Satellite - Format JavaScript/TypeScript files")]
16+
#[command(version = env!("CARGO_PKG_VERSION"))]
17+
struct Cli {
18+
/// The file(s) or directory(ies) to format
19+
#[arg(required = false)]
20+
paths: Vec<PathBuf>,
21+
}
22+
23+
fn main() -> CliResult<()> {
24+
andromeda::error::init_error_reporting();
25+
26+
let cli = Cli::parse();
27+
28+
let config = andromeda::config::ConfigManager::load_or_default(None);
29+
30+
let files_to_format =
31+
andromeda::helper::find_formattable_files_for_format(&cli.paths, &config.format)
32+
.map_err(|e| CliError::TestExecution(format!("{e}")))?;
33+
34+
if files_to_format.is_empty() {
35+
let warning = Style::new().yellow().bold().apply_to("⚠️");
36+
let msg = Style::new()
37+
.yellow()
38+
.apply_to("No formattable files found.");
39+
println!("{warning} {msg}");
40+
return Ok(());
41+
}
42+
43+
let count = Style::new().cyan().apply_to(files_to_format.len());
44+
println!("Found {count} file(s) to format");
45+
println!("{}", Style::new().dim().apply_to("─".repeat(40)));
46+
47+
let mut already_formatted_count = 0;
48+
let mut formatted_count = 0;
49+
50+
for path in &files_to_format {
51+
match andromeda::format::format_file(path)
52+
.map_err(|e| CliError::TestExecution(format!("{e}")))?
53+
{
54+
andromeda::format::FormatResult::Changed => formatted_count += 1,
55+
andromeda::format::FormatResult::AlreadyFormatted => already_formatted_count += 1,
56+
}
57+
}
58+
59+
println!();
60+
let success = Style::new().green().bold().apply_to("✅");
61+
let complete_msg = Style::new().green().bold().apply_to("Formatting complete");
62+
println!("{success} {complete_msg}:");
63+
64+
if formatted_count > 0 {
65+
let formatted_icon = Style::new().green().apply_to("📄");
66+
let formatted_num = Style::new().green().bold().apply_to(formatted_count);
67+
let formatted_text = if formatted_count == 1 {
68+
"file"
69+
} else {
70+
"files"
71+
};
72+
println!(" {formatted_icon} {formatted_num} {formatted_text} formatted");
73+
}
74+
75+
if already_formatted_count > 0 {
76+
let already_icon = Style::new().cyan().apply_to("✨");
77+
let already_num = Style::new().cyan().bold().apply_to(already_formatted_count);
78+
let already_text = if already_formatted_count == 1 {
79+
"file"
80+
} else {
81+
"files"
82+
};
83+
let already_msg = Style::new().cyan().apply_to("already formatted");
84+
println!(" {already_icon} {already_num} {already_text} {already_msg}");
85+
}
86+
87+
Ok(())
88+
}

0 commit comments

Comments
 (0)