Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Propagate exit code from Dart command #440

Merged
merged 6 commits into from
Sep 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions documentation/docs/running-and-building.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ To serve[^3] the web application:
[^3]: Note that Flutter apps in debug mode are known to be quite slow on the web. It is recommended to use release mode when testing on a web browser. Debug mode can be used if you need to analyze the code more deeply, without the `--release` argument.

```bash title="CLI"
rinf wasm --release
flutter run --release # Choose a browser
rinf wasm
flutter run --web-header=Cross-Origin-Opener-Policy=same-origin --web-header=Cross-Origin-Embedder-Policy=require-corp
```

To build the optimized release version of the web application[^4]:
Expand All @@ -42,6 +42,12 @@ rinf wasm --release
flutter build web
```

Since repeatedly writing web header arguments during development can be overwhelming, Rinf provides a convenient command that prints the full Flutter web command.

```bash title="CLI"
rinf server
```

When deploying your web app on a web server, ensure that your web server is configured to include cross-origin-related HTTP headers in its responses. These headers enable web browsers using your website to gain access to `SharedArrayBuffer` web API, which is something similar to shared memory on the web.

- [`Cross-Origin-Opener-Policy`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Opener-Policy): `same-origin`
Expand Down
6 changes: 5 additions & 1 deletion flutter_package/bin/rinf.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import 'dart:io';

import 'package:args/command_runner.dart';
import 'package:chalkdart/chalkstrings.dart';

Expand All @@ -10,7 +12,7 @@ import 'src/common.dart';
Future<void> main(List<String> args) async {
// When running `dart run rinf`,
// Unnecessary two lines of
//`Building package executable...\nBuilt rinf:rinf.` appear.
// `Building package executable...\nBuilt rinf:rinf.` appear.
// Remove those before proceeding.
removeCliLines(2);

Expand All @@ -34,6 +36,8 @@ Future<void> main(List<String> args) async {
} catch (error) {
// Print the error gracefully without backtrace.
print(error.toString().trim().red);
// Exit code 1 is assigned to Rust-side wrapper executable.
exit(2);
}
}

Expand Down
39 changes: 21 additions & 18 deletions rust_crate/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,51 +8,47 @@ fn main() -> Result<(), String> {
// Ensure Protobuf compiler.
let protoc_path = if let Ok(installed) = which::which("protoc") {
// Get the path of Protobuf compiler that's already installed.
println!("Detected `protoc`, skipping auto installation.");
println!("Detected `protoc`, skipping auto installation");
installed
.parent()
.ok_or("Could not get the parent of `protoc` path.")?
.ok_or("Could not get the parent of `protoc` path")?
.to_path_buf()
} else {
// Install Protobuf compiler and get the path.
let home_path = home::home_dir()
.ok_or("Could not get home directory for `protoc` installation.")?;
.ok_or("Could not get home directory for `protoc` installation")?;
let out_path = home_path.join(".local").join("bin");
fs::create_dir_all(&out_path).map_err(|_| {
"Could not create the folder for `protoc` installation."
"Could not create the folder for `protoc` installation"
})?;
env::set_var(
"OUT_DIR",
out_path
.to_str()
.ok_or("Could not set the path for `protoc` installation.")?,
.ok_or("Could not set the path for `protoc` installation")?,
);
let install_result = protoc_prebuilt::init("25.2");
let (protoc_binary_path, _) = install_result.map_err(|_| {
format!(
"{}\n{}",
"Automatic installation of `protoc` failed.",
"Try installing `protoc` manually and adding it to PATH."
)
})?;
let (protoc_binary_path, _) = install_result.map_err(|_|
"Automatic installation of `protoc` failed, try installing it manually"
)?;
protoc_binary_path
.parent()
.ok_or("Could not get the parent of installed `protoc` path.")?
.ok_or("Could not get the parent of newly-installed `protoc` path")?
.to_path_buf()
};

// Find the path where Dart executables are located.
#[cfg(target_family = "windows")]
let pub_cache_bin_path = path::PathBuf::from(
env::var("LOCALAPPDATA")
.map_err(|_| "Could not get `LOCALAPPDATA` path.")?,
.map_err(|_| "Could not get `LOCALAPPDATA` path")?,
)
.join("Pub")
.join("Cache")
.join("bin");
#[cfg(target_family = "unix")]
let pub_cache_bin_path = path::PathBuf::from(
env::var("HOME").map_err(|_| "Could get find `HOME` path.")?,
env::var("HOME").map_err(|_| "Could get find `HOME` path")?,
)
.join(".pub-cache")
.join("bin");
Expand All @@ -67,19 +63,26 @@ fn main() -> Result<(), String> {
env::set_var(
"PATH",
env::join_paths(path_var)
.map_err(|_| "Could not push required values to `PATH`.")?,
.map_err(|_| "Could not push required values to `PATH`")?,
);

// Get command-line arguments excluding the program name.
let dart_command_args: Vec<String> = env::args().skip(1).collect();

// Run the Dart script.
let dart_path = which::which("dart")
.map_err(|_| "Could not find where Dart is located.")?;
.map_err(|_| "Could not find where Dart is located")?;
let mut command = process::Command::new(dart_path);
command.args(["run", "rinf"]);
command.args(&dart_command_args);
command.status().map_err(|_| "Rinf command has failed.")?;
let exit_status =
command.status().map_err(|_| "Could not run Rinf command")?;
let exit_code = exit_status
.code()
.ok_or("Could not get Rinf command exit code")?;
if exit_code != 0 {
process::exit(exit_code);
}

Ok(())
}
Expand Down
Loading