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

Avoid global ffigen #605

Merged
merged 31 commits into from
Aug 3, 2022
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
12c869f
:hammer: update just lint to format rust code altogether
Roms1383 Aug 1, 2022
ef84ec4
:arrow_up: add ffi and ffigen dependencies to examples
Roms1383 Aug 1, 2022
26de1f3
:recycle: use local dependencies instead of global
Roms1383 Aug 1, 2022
666b799
:green_heart: remove ffigen as a global dependency from CI
Roms1383 Aug 1, 2022
69b74b9
:art: lint code
Roms1383 Aug 1, 2022
fa0e943
:truck: move redundant code from commands to utils
Roms1383 Aug 1, 2022
185d469
:hammer: update just check to run clippy in frb_codegen altogether
Roms1383 Aug 1, 2022
4488c38
:recycle: refactor ensure dependencies methods
Roms1383 Aug 1, 2022
9c242b3
:recycle: parse dart root only once
Roms1383 Aug 1, 2022
b6a8c8e
:recycle: add dart root or default
Roms1383 Aug 1, 2022
e90a486
:art: lint and fix clippy warnings
Roms1383 Aug 1, 2022
f8f968b
:recycle: refactor, improve naming
Roms1383 Aug 1, 2022
374de6b
:art: simplify code
Roms1383 Aug 1, 2022
92b60ba
:fire: remove version req comparison
Roms1383 Aug 1, 2022
9b9ec7d
:pencil2: remove unecessary fully qualified syntax
Roms1383 Aug 1, 2022
e6ec7da
:memo: update install docs
Roms1383 Aug 1, 2022
fe86a45
Merge branch 'master' into chore/avoid-global-ffigen
Roms1383 Aug 2, 2022
310c89d
:green_heart: add flutter setup action
Roms1383 Aug 2, 2022
6c31eea
:art: fix clippy warning
Roms1383 Aug 2, 2022
4e79ebe
:green_heart: add install deps step
Roms1383 Aug 2, 2022
63603f4
:memo: reuse parts of the docs and fix mardown lint warnings
Roms1383 Aug 2, 2022
9525d5c
Update deps.md
fzyzcjy Aug 2, 2022
98f3a19
Merge branch 'fzyzcjy:master' into chore/avoid-global-ffigen
Roms1383 Aug 3, 2022
c8575ce
:green_heart: remove unused install step
Roms1383 Aug 3, 2022
15d6e46
:fire: remove unused markdown file
Roms1383 Aug 3, 2022
ef86e5b
:pencil2: fix doc wording
Roms1383 Aug 3, 2022
f6b6366
:recycle: refactor pattern matching into condition
Roms1383 Aug 3, 2022
94c11a4
:recycle: reuse impl method
Roms1383 Aug 3, 2022
d56544d
:recycle: add version method to package version
Roms1383 Aug 3, 2022
01ee615
:rewind: remove install deps in CI
Roms1383 Aug 3, 2022
c09c62e
:green_heart: install deps in CI
Roms1383 Aug 3, 2022
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: 0 additions & 10 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,6 @@ jobs:

- uses: dart-lang/setup-dart@v1

- name: Install ffigen
run: dart pub global activate ffigen ^6.0.1

- name: Install dart dependencies (single block)
working-directory: ./frb_example/pure_dart/dart
run: dart pub get
Expand Down Expand Up @@ -335,8 +332,6 @@ jobs:
- uses: actions/checkout@v2

- uses: dart-lang/setup-dart@v1
- name: Install ffigen
run: dart pub global activate ffigen ^6.0.1
- name: Install llvm dependency (Linux)
run: sudo apt update && sudo apt-get install -y libclang-dev
- name: Build codegen
Expand Down Expand Up @@ -403,8 +398,6 @@ jobs:
components: rustfmt, clippy

- uses: dart-lang/setup-dart@v1
- name: Install ffigen
run: dart pub global activate ffigen ^6.0.1
- name: Install llvm dependency (Linux)
run: sudo apt update && sudo apt-get install -y libclang-dev

Expand Down Expand Up @@ -567,9 +560,6 @@ jobs:

- uses: dart-lang/setup-dart@v1
Roms1383 marked this conversation as resolved.
Show resolved Hide resolved

- name: Install dart global dependency
run: dart pub global activate ffigen ^6.0.1

# needed by `ffigen`, see https://github.com/dart-lang/ffigen#installing-llvm
- name: Install llvm dependency (Linux)
if: ${{ matrix.os.family == 'linux' }}
Expand Down
6 changes: 0 additions & 6 deletions .github/workflows/post_release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,6 @@ jobs:

- uses: dart-lang/setup-dart@v1

- name: Install ffigen
run: dart pub global activate ffigen ^6.0.1

- name: Install dart dependencies (single block)
working-directory: ./frb_example/pure_dart/dart
run: dart pub get
Expand Down Expand Up @@ -178,9 +175,6 @@ jobs:

- uses: dart-lang/setup-dart@v1
Roms1383 marked this conversation as resolved.
Show resolved Hide resolved

- name: Install dart global dependency
run: dart pub global activate ffigen ^6.0.1

# needed by `ffigen`, see https://github.com/dart-lang/ffigen#installing-llvm
- name: Install llvm dependency (Linux)
if: ${{ matrix.os.family == 'linux' }}
Expand Down
160 changes: 144 additions & 16 deletions frb_codegen/src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use std::process::Command;
use std::process::Output;

use crate::error::{Error, Result};
use cargo_metadata::VersionReq;
use log::{debug, info, warn};
use serde::Deserialize;

Expand All @@ -18,11 +19,53 @@ fn call_shell(cmd: &str) -> Output {
execute_command("sh", &["-c", cmd], None)
}

pub fn ensure_tools_available() -> Result {
let output = call_shell("dart pub global list");
let output = String::from_utf8_lossy(&output.stdout);
if !output.contains("ffigen") {
return Err(Error::MissingExe(String::from("ffigen")));
pub fn ensure_tools_available(maybe_dart_root: &Option<String>) -> Result {
let dart_root = maybe_dart_root
.as_deref()
.unwrap_or(env!("CARGO_MANIFEST_DIR").into());
let toolchain = guess_toolchain(&dart_root).unwrap();
if toolchain == DartToolchain::Dart {
Roms1383 marked this conversation as resolved.
Show resolved Hide resolved
if !call_shell("dart --version").status.success() {
return Err(Error::MissingExe(String::from("dart")));
};
} else {
if !call_shell("flutter --version").status.success() {
return Err(Error::MissingExe(String::from("flutter")));
};
};

let ffi = ensure_dependencies(&dart_root, "ffi").unwrap();
if let Some(ffi) = ffi {
if VersionReq::parse("^2.0.1").unwrap() != ffi {
return Err(Error::InvalidDep(
"ffi".into(),
"dependencies".into(),
"^2.0.1".into(),
));
}
} else {
return Err(Error::MissingDep(
"ffi".into(),
"dependencies".into(),
"^2.0.1".into(),
));
}

let ffigen = ensure_dev_dependencies(&dart_root, "ffigen").unwrap();
if let Some(ffigen) = ffigen {
if VersionReq::parse("^6.0.1").unwrap() != ffigen {
return Err(Error::InvalidDep(
"ffigen".into(),
"dev_dependencies".into(),
"^6.0.1".into(),
));
}
} else {
return Err(Error::MissingDep(
"ffigen".into(),
"dev_dependencies".into(),
"^6.0.1".into(),
));
Roms1383 marked this conversation as resolved.
Show resolved Hide resolved
}

Ok(())
Expand All @@ -39,7 +82,10 @@ pub(crate) struct BindgenRustToDartArg<'a> {
pub llvm_compiler_opts: &'a str,
}

pub(crate) fn bindgen_rust_to_dart(arg: BindgenRustToDartArg) -> anyhow::Result<()> {
pub(crate) fn bindgen_rust_to_dart(
arg: BindgenRustToDartArg,
dart_root: &Option<String>,
) -> anyhow::Result<()> {
cbindgen(
arg.rust_crate_dir,
arg.c_output_path,
Expand All @@ -52,6 +98,9 @@ pub(crate) fn bindgen_rust_to_dart(arg: BindgenRustToDartArg) -> anyhow::Result<
arg.dart_class_name,
arg.llvm_install_path,
arg.llvm_compiler_opts,
dart_root
.as_deref()
.unwrap_or(env!("CARGO_MANIFEST_DIR").into()),
Roms1383 marked this conversation as resolved.
Show resolved Hide resolved
)
}

Expand Down Expand Up @@ -161,6 +210,7 @@ fn ffigen(
dart_class_name: &str,
llvm_path: &[String],
llvm_compiler_opts: &str,
dart_root: &str,
) -> anyhow::Result<()> {
debug!(
"execute ffigen c_path={} dart_path={} llvm_path={:?}",
Expand Down Expand Up @@ -208,9 +258,16 @@ fn ffigen(
std::io::Write::write_all(&mut config_file, config.as_bytes())?;
debug!("ffigen config_file: {:?}", config_file);

// NOTE please install ffigen globally first: `dart pub global activate ffigen`
let cmd = if guess_toolchain(dart_root).unwrap() == DartToolchain::Dart {
"dart run"
} else {
"flutter pub run"
};
Roms1383 marked this conversation as resolved.
Show resolved Hide resolved
let res = call_shell(&format!(
"dart pub global run ffigen --config \"{}\"",
"cd {}{}{} ffigen --config \"{}\"",
dart_root,
if cfg!(windows) { "; " } else { " && " },
cmd,
config_file.path().to_string_lossy()
));
if !res.status.success() {
Expand Down Expand Up @@ -281,17 +338,23 @@ pub fn build_runner(dart_root: &str) -> Result {
Ok(())
}

fn guess_toolchain(dart_root: &str) -> anyhow::Result<DartToolchain> {
debug!("Guessing toolchain the runner is run into");
let lock_file = PathBuf::from(dart_root).join("pubspec.lock");
if !lock_file.exists() {
#[inline]
fn read_file(at: &str, filename: &str) -> anyhow::Result<String> {
let file = PathBuf::from(at).join(filename);
if !file.exists() {
return Err(anyhow::Error::msg(format!(
"missing pubspec.lock in {}",
dart_root
"missing {} in {}",
filename, at
)));
}
let lock_file = std::fs::read_to_string(lock_file)
.map_err(|_| anyhow::Error::msg(format!("unable to read pubspec.lock in {}", dart_root)))?;
let content = std::fs::read_to_string(file)
.map_err(|_| anyhow::Error::msg(format!("unable to read {} in {}", filename, at)))?;
Ok(content)
}

fn guess_toolchain(dart_root: &str) -> anyhow::Result<DartToolchain> {
debug!("Guessing toolchain the runner is run into");
let lock_file = read_file(dart_root, "pubspec.lock")?;
let lock_file: PubspecLock = serde_yaml::from_str(&lock_file).map_err(|_| {
anyhow::Error::msg(format!("unable to parse pubspec.lock in {}", dart_root))
})?;
Expand All @@ -301,6 +364,58 @@ fn guess_toolchain(dart_root: &str) -> anyhow::Result<DartToolchain> {
Ok(DartToolchain::Dart)
}

fn ensure_dependencies(dart_root: &str, key: &str) -> anyhow::Result<Option<VersionReq>> {
debug!(
"Checking presence of {} in dependencies in {}",
key, dart_root
);
let manifest_file = read_file(dart_root, "pubspec.yaml")?;
info!("{:#?}", manifest_file);
Roms1383 marked this conversation as resolved.
Show resolved Hide resolved
let manifest_file: Pubspec = serde_yaml::from_str(&manifest_file).map_err(|e| {
info!("{}", e);
anyhow::Error::msg(format!("unable to parse pubspec.yaml in {}", dart_root))
Roms1383 marked this conversation as resolved.
Show resolved Hide resolved
})?;
let deps = manifest_file.dependencies.unwrap_or_default();
let version = deps.get(key);
let version = version.map(|v| match v {
DependencyVersion::Inline(ref version) => VersionReq::parse(version).unwrap(),
DependencyVersion::Multiline { ref version } => VersionReq::parse(
version
.as_ref()
.expect(&format!("please specify a version for {}", key)),
)
.unwrap(),
});
info!("found version {:#?} for {}", version, key);
Ok(version)
}

fn ensure_dev_dependencies(dart_root: &str, key: &str) -> anyhow::Result<Option<VersionReq>> {
Roms1383 marked this conversation as resolved.
Show resolved Hide resolved
debug!(
"Checking presence of {} in dev_dependencies in {}",
key, dart_root
);
let manifest_file = read_file(dart_root, "pubspec.yaml")?;
info!("{:#?}", manifest_file);
let manifest_file: Pubspec = serde_yaml::from_str(&manifest_file).map_err(|e| {
info!("{}", e);
anyhow::Error::msg(format!("unable to parse pubspec.yaml in {}", dart_root))
})?;
let deps = manifest_file.dev_dependencies.unwrap_or_default();
let version = deps.get(key);
let version = version.map(|v| match v {
DependencyVersion::Inline(ref version) => VersionReq::parse(version).unwrap(),
DependencyVersion::Multiline { ref version } => VersionReq::parse(
version
.as_ref()
.expect(&format!("please specify a version for {}", key)),
)
.unwrap(),
});
info!("found version {:#?} for {}", version, key);
Ok(version)
}

#[derive(Debug, PartialEq)]
enum DartToolchain {
Dart,
Expand All @@ -321,6 +436,19 @@ struct PubspecLock {
pub packages: HashMap<String, serde_yaml::Value>,
}

#[derive(Debug, Deserialize)]
#[serde(untagged)]
enum DependencyVersion {
Inline(String),
Multiline { version: Option<String> },
}

#[derive(Debug, Deserialize)]
struct Pubspec {
pub dependencies: Option<HashMap<String, DependencyVersion>>,
pub dev_dependencies: Option<HashMap<String, DependencyVersion>>,
}

#[cfg(test)]
mod tests {
use std::path::{Path, PathBuf};
Expand Down
4 changes: 4 additions & 0 deletions frb_codegen/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ pub enum Error {
MissingExe(String),
#[error("{0}")]
StringError(String),
#[error("please add {0} to your {1}. (version {2})")]
MissingDep(String, String, String),
#[error("please update version of {0} in your {1}. (version {2})")]
InvalidDep(String, String, String),
Roms1383 marked this conversation as resolved.
Show resolved Hide resolved
}

impl Error {
Expand Down
33 changes: 18 additions & 15 deletions frb_codegen/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ mod utils;
use error::*;

pub fn frb_codegen(config: &config::Opts, all_symbols: &[String]) -> anyhow::Result<()> {
ensure_tools_available()?;
ensure_tools_available(&config.dart_root)?;

info!("Picked config: {:?}", config);

Expand Down Expand Up @@ -68,20 +68,23 @@ pub fn frb_codegen(config: &config::Opts, all_symbols: &[String]) -> anyhow::Res
&config.rust_output_path,
DUMMY_WIRE_CODE_FOR_BINDGEN,
|| {
commands::bindgen_rust_to_dart(BindgenRustToDartArg {
rust_crate_dir: &config.rust_crate_dir,
c_output_path: temp_bindgen_c_output_file
.path()
.as_os_str()
.to_str()
.unwrap(),
dart_output_path: temp_dart_wire_file.path().as_os_str().to_str().unwrap(),
dart_class_name: &config.dart_wire_class_name(),
c_struct_names: ir_file.get_c_struct_names(),
exclude_symbols,
llvm_install_path: &config.llvm_path[..],
llvm_compiler_opts: &config.llvm_compiler_opts,
})
commands::bindgen_rust_to_dart(
BindgenRustToDartArg {
rust_crate_dir: &config.rust_crate_dir,
c_output_path: temp_bindgen_c_output_file
.path()
.as_os_str()
.to_str()
.unwrap(),
dart_output_path: temp_dart_wire_file.path().as_os_str().to_str().unwrap(),
dart_class_name: &config.dart_wire_class_name(),
c_struct_names: ir_file.get_c_struct_names(),
exclude_symbols,
llvm_install_path: &config.llvm_path[..],
llvm_compiler_opts: &config.llvm_compiler_opts,
},
&config.dart_root,
)
},
)?;

Expand Down
28 changes: 28 additions & 0 deletions frb_example/pure_dart/dart/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.1"
cli_util:
dependency: transitive
description:
name: cli_util
url: "https://pub.dartlang.org"
source: hosted
version: "0.3.5"
code_builder:
dependency: transitive
description:
Expand Down Expand Up @@ -141,6 +148,20 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "2.2.3"
ffi:
dependency: "direct main"
description:
name: ffi
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.1"
ffigen:
dependency: "direct dev"
description:
name: ffigen
url: "https://pub.dartlang.org"
source: hosted
version: "6.0.1"
file:
dependency: transitive
description:
Expand Down Expand Up @@ -309,6 +330,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.0"
quiver:
dependency: transitive
description:
name: quiver
url: "https://pub.dartlang.org"
source: hosted
version: "3.1.0"
shelf:
dependency: transitive
description:
Expand Down
Loading