diff --git a/crates/ubrn_cli/src/codegen/mod.rs b/crates/ubrn_cli/src/codegen/mod.rs index a1fc8376..a9df7fac 100644 --- a/crates/ubrn_cli/src/codegen/mod.rs +++ b/crates/ubrn_cli/src/codegen/mod.rs @@ -189,7 +189,7 @@ mod files { templated_file!(JavaModule, "ModuleTemplate.java"); impl RenderedFile for JavaModule { fn path(&self, project_root: &Utf8Path) -> Utf8PathBuf { - let name = self.config.project.name_upper_camel(); + let name = self.config.project.module_cpp(); let filename = format!("{name}Module.java"); self.config .project @@ -202,7 +202,7 @@ mod files { templated_file!(JavaPackage, "PackageTemplate.java"); impl RenderedFile for JavaPackage { fn path(&self, project_root: &Utf8Path) -> Utf8PathBuf { - let name = self.config.project.name_upper_camel(); + let name = self.config.project.module_cpp(); let filename = format!("{name}Package.java"); self.config .project @@ -264,7 +264,7 @@ mod files { templated_file!(IndexTs, "index.ts"); impl RenderedFile for IndexTs { fn path(&self, project_root: &Utf8Path) -> Utf8PathBuf { - let filename = "index.ts"; + let filename = "index.tsx"; self.config.project.tm.ts_path(project_root).join(filename) } } @@ -295,7 +295,7 @@ mod files { templated_file!(ModuleTemplateH, "ModuleTemplate.h"); impl RenderedFile for ModuleTemplateH { fn path(&self, project_root: &Utf8Path) -> Utf8PathBuf { - let name = self.config.project.name_upper_camel(); + let name = self.config.project.module_cpp(); let filename = format!("{name}.h"); self.config .project @@ -311,7 +311,7 @@ mod files { templated_file!(ModuleTemplateMm, "ModuleTemplate.mm"); impl RenderedFile for ModuleTemplateMm { fn path(&self, project_root: &Utf8Path) -> Utf8PathBuf { - let name = self.config.project.name_upper_camel(); + let name = self.config.project.module_cpp(); let filename = format!("{name}.mm"); self.config .project @@ -432,7 +432,7 @@ mod tests { templated_file!(TemplateTester, "TemplateTester.txt"); impl RenderedFile for TemplateTester { fn path(&self, project_root: &Utf8Path) -> Utf8PathBuf { - let name = self.config.project.name_upper_camel(); + let name = self.config.project.module_cpp(); let filename = format!("{name}.txt"); self.config .project @@ -454,10 +454,10 @@ mod tests { // This is hard coded into the file. If this isn't here, then the test file hasn't rendered. assert!(s.contains("hardcoded into template.")); assert_eq!( - config.project.name_upper_camel(), + config.project.module_cpp(), "MyTesterTemplateProject".to_string() ); - assert!(s.contains("name_upper_camel = MyTesterTemplateProject.")); + assert!(s.contains("module_cpp = MyTesterTemplateProject.")); assert!(s.contains("list of modules = ['NativeAlice', 'NativeBob', 'NativeCharlie']")); Ok(()) } diff --git a/crates/ubrn_cli/src/codegen/templates/CMakeLists.txt b/crates/ubrn_cli/src/codegen/templates/CMakeLists.txt index 759de225..d976034f 100644 --- a/crates/ubrn_cli/src/codegen/templates/CMakeLists.txt +++ b/crates/ubrn_cli/src/codegen/templates/CMakeLists.txt @@ -1,6 +1,6 @@ # Generated by uniffi-bindgen-react-native cmake_minimum_required(VERSION 3.9.0) -project({{ self.config.project.cpp_filename() }}) +project({{ self.config.project.module_cpp() }}) {%- let root = self.project_root() %} {%- let dir = self.config.project.bindings.cpp_path(root) %} diff --git a/crates/ubrn_cli/src/codegen/templates/ModuleTemplate.h b/crates/ubrn_cli/src/codegen/templates/ModuleTemplate.h index cb2cdd4a..46846fdc 100644 --- a/crates/ubrn_cli/src/codegen/templates/ModuleTemplate.h +++ b/crates/ubrn_cli/src/codegen/templates/ModuleTemplate.h @@ -6,11 +6,11 @@ #ifdef RCT_NEW_ARCH_ENABLED #import "{{ self.config.project.tm.name() }}.h" -@interface {{ self.config.project.name_upper_camel() }} : NSObject <{{ self.config.project.codegen_filename() }}Spec> +@interface {{ self.config.project.module_cpp() }} : NSObject <{{ self.config.project.codegen_filename() }}Spec> #else #import -@interface {{ self.config.project.name_upper_camel() }} : NSObject +@interface {{ self.config.project.module_cpp() }} : NSObject #endif @end diff --git a/crates/ubrn_cli/src/codegen/templates/ModuleTemplate.java b/crates/ubrn_cli/src/codegen/templates/ModuleTemplate.java index fffc7c89..7219d9bb 100644 --- a/crates/ubrn_cli/src/codegen/templates/ModuleTemplate.java +++ b/crates/ubrn_cli/src/codegen/templates/ModuleTemplate.java @@ -1,5 +1,5 @@ {%- let android = self.config.project.android.clone() %} -{%- let name = self.config.project.name_upper_camel() %} +{%- let name = self.config.project.module_cpp() %} {%- let module_class_name = name|fmt("{}Module") -%} // Generated by uniffi-bindgen-react-native package {{ android.package_name() }}; diff --git a/crates/ubrn_cli/src/codegen/templates/ModuleTemplate.mm b/crates/ubrn_cli/src/codegen/templates/ModuleTemplate.mm index fffc3795..40dacd3c 100644 --- a/crates/ubrn_cli/src/codegen/templates/ModuleTemplate.mm +++ b/crates/ubrn_cli/src/codegen/templates/ModuleTemplate.mm @@ -1,4 +1,4 @@ -{%- let module_name = self.config.project.name_upper_camel() %} +{%- let module_name = self.config.project.module_cpp() %} {%- let spec_jsi = self.config.project.tm.spec_name()|fmt("{}JSI") %} {%- let ns = self.config.project.cpp_namespace() %} {%- let uniffi_ns = "uniffi_generated" %} @@ -40,6 +40,15 @@ @implementation {{ module_name }} // Don't compile this code when we build for the old architecture. #ifdef RCT_NEW_ARCH_ENABLED + +// Automated testing checks {{ ns }} +// by comparing the whole line here. +/* +- (NSNumber *)multiply:(double)a b:(double)b { + NSNumber *result = @({{ ns }}::multiply(a, b)); +} +*/ + - (NSNumber *)installRustCrate { @throw [NSException exceptionWithName:@"UnreachableException" reason:@"This method should never be called." diff --git a/crates/ubrn_cli/src/codegen/templates/NativeCodegenTemplate.ts b/crates/ubrn_cli/src/codegen/templates/NativeCodegenTemplate.ts index 0b2e69be..ea3cc058 100644 --- a/crates/ubrn_cli/src/codegen/templates/NativeCodegenTemplate.ts +++ b/crates/ubrn_cli/src/codegen/templates/NativeCodegenTemplate.ts @@ -7,4 +7,4 @@ export interface Spec extends TurboModule { cleanupRustCrate(): boolean; } -export default TurboModuleRegistry.getEnforcing('{{ self.config.project.name_upper_camel() }}'); +export default TurboModuleRegistry.getEnforcing('{{ self.config.project.spec_name() }}'); diff --git a/crates/ubrn_cli/src/codegen/templates/PackageTemplate.java b/crates/ubrn_cli/src/codegen/templates/PackageTemplate.java index aac54712..dfaf4268 100644 --- a/crates/ubrn_cli/src/codegen/templates/PackageTemplate.java +++ b/crates/ubrn_cli/src/codegen/templates/PackageTemplate.java @@ -1,4 +1,4 @@ -{%- let name = self.config.project.name_upper_camel() %} +{%- let name = self.config.project.module_cpp() %} {%- let package_class_name = name|fmt("{}Package") %} {%- let module_class_name = name|fmt("{}Module") -%} // Generated by uniffi-bindgen-react-native diff --git a/crates/ubrn_cli/src/codegen/templates/TemplateTester.txt b/crates/ubrn_cli/src/codegen/templates/TemplateTester.txt index d9760cc0..4b4a3b12 100644 --- a/crates/ubrn_cli/src/codegen/templates/TemplateTester.txt +++ b/crates/ubrn_cli/src/codegen/templates/TemplateTester.txt @@ -1,5 +1,5 @@ hardcoded into template. -name_upper_camel = {{ self.config.project.name_upper_camel() }}. +module_cpp = {{ self.config.project.module_cpp() }}. list of modules = [ {%- for m in self.config.modules %}' diff --git a/crates/ubrn_cli/src/codegen/templates/build.gradle b/crates/ubrn_cli/src/codegen/templates/build.gradle index 63ff7619..7cc4b8d3 100644 --- a/crates/ubrn_cli/src/codegen/templates/build.gradle +++ b/crates/ubrn_cli/src/codegen/templates/build.gradle @@ -1,5 +1,5 @@ // Generated by uniffi-bindgen-react-native -{%- let name = self.config.project.name_upper_camel() %} +{%- let name = self.config.project.module_cpp() %} {%- let package_name = self.config.project.android.package_name() %} buildscript { diff --git a/crates/ubrn_cli/src/codegen/templates/cpp-adapter.cpp b/crates/ubrn_cli/src/codegen/templates/cpp-adapter.cpp index 994bb7e0..d8d1c1a1 100644 --- a/crates/ubrn_cli/src/codegen/templates/cpp-adapter.cpp +++ b/crates/ubrn_cli/src/codegen/templates/cpp-adapter.cpp @@ -4,7 +4,7 @@ #include #include "{{ self.config.project.cpp_filename() }}.h" {%- let package_name = self.config.project.android.package_name().replace(".", "_") %} -{%- let name = self.config.project.name_upper_camel() %} +{%- let name = self.config.project.module_cpp() %} {%- let module_class_name = name|fmt("{}Module") %} {%- let prefix = "Java_{}_{}"|format(package_name, module_class_name) %} {%- let ns = self.config.project.cpp_namespace() %} @@ -12,6 +12,14 @@ namespace jsi = facebook::jsi; namespace react = facebook::react; +// Automated testing checks {{ prefix }} and {{ ns }} +// by comparing the whole line here. +/* +{{ prefix }}_nativeMultiply(JNIEnv *env, jclass type, jdouble a, jdouble b) { + return {{ ns }}::multiply(a, b); +} +*/ + // Installer coming from {{ module_class_name }} extern "C" JNIEXPORT jboolean JNICALL diff --git a/crates/ubrn_cli/src/config/mod.rs b/crates/ubrn_cli/src/config/mod.rs index f3339e47..3fda1216 100644 --- a/crates/ubrn_cli/src/config/mod.rs +++ b/crates/ubrn_cli/src/config/mod.rs @@ -7,6 +7,7 @@ mod npm; use camino::{Utf8Path, Utf8PathBuf}; use globset::GlobSet; +use heck::ToUpperCamelCase; pub(crate) use npm::PackageJson; use serde::Deserialize; @@ -55,15 +56,21 @@ impl ProjectConfig { } } -fn trim_react_native(name: &str) -> String { +fn trim(name: &str) -> String { name.trim_matches('-').trim_matches('_').to_string() } -fn trim_react_native_2(name: &str) -> String { - name.strip_prefix("RN") - .unwrap_or(name) - .replace("ReactNative", "") - .replace("react-native", "") +#[allow(dead_code)] +fn trim_rn(name: &str) -> String { + trim_react_native(strip_prefix(name, "RN")) +} + +fn strip_prefix<'a>(name: &'a str, prefix: &str) -> &'a str { + name.strip_prefix(prefix).unwrap_or(name) +} + +pub(crate) fn trim_react_native(name: &str) -> String { + strip_prefix(strip_prefix(name, "ReactNative"), "react-native") .trim_matches('-') .trim_matches('_') .to_string() @@ -73,13 +80,13 @@ impl ProjectConfig { pub(crate) fn project_root(&self) -> &Utf8Path { &self.crate_.project_root } -} -impl ProjectConfig { - fn name(&self) -> String { - trim_react_native(&self.name) + pub(crate) fn module_cpp(&self) -> String { + trim_react_native(&self.name).to_upper_camel_case() } +} +impl ProjectConfig { pub(crate) fn raw_name(&self) -> &str { &self.name } @@ -88,13 +95,10 @@ impl ProjectConfig { &self.repository } - pub(crate) fn name_upper_camel(&self) -> String { - use heck::ToUpperCamelCase; - self.name().to_upper_camel_case() - } - pub(crate) fn cpp_namespace(&self) -> String { - self.name_upper_camel().to_lowercase() + trim_react_native(&self.name) + .to_upper_camel_case() + .to_lowercase() } pub(crate) fn cpp_filename(&self) -> String { @@ -103,7 +107,11 @@ impl ProjectConfig { } pub(crate) fn codegen_filename(&self) -> String { - format!("Native{}", self.name_upper_camel()) + format!("Native{}", self.spec_name()) + } + + pub(crate) fn spec_name(&self) -> String { + trim_react_native(&self.name).to_upper_camel_case() } pub(crate) fn exclude_files(&self) -> &GlobSet { @@ -185,7 +193,7 @@ impl TurboModulesConfig { fn default_spec_name() -> String { let package_json = workspace::package_json(); let codegen_name = &package_json.codegen().name; - trim_react_native(codegen_name) + trim(codegen_name) } } diff --git a/crates/ubrn_cli/src/config/npm.rs b/crates/ubrn_cli/src/config/npm.rs index 641af69a..3a64056f 100644 --- a/crates/ubrn_cli/src/config/npm.rs +++ b/crates/ubrn_cli/src/config/npm.rs @@ -7,7 +7,7 @@ use heck::ToUpperCamelCase; use serde::Deserialize; -use super::{trim_react_native, trim_react_native_2}; +use super::{trim, trim_react_native}; #[derive(Deserialize)] #[serde(rename_all = "camelCase")] @@ -26,7 +26,7 @@ impl PackageJson { } pub(crate) fn name(&self) -> String { - trim_react_native(&self.name) + trim(&self.name) } pub(crate) fn android_package_name(&self) -> String { @@ -37,7 +37,7 @@ impl PackageJson { .unwrap_or_else(|| { format!( "com.{}", - trim_react_native_2(&self.name) + trim_react_native(&self.name) .to_upper_camel_case() .to_lowercase() ) diff --git a/crates/ubrn_cli/src/ios.rs b/crates/ubrn_cli/src/ios.rs index ca0dfbb1..53a6a15f 100644 --- a/crates/ubrn_cli/src/ios.rs +++ b/crates/ubrn_cli/src/ios.rs @@ -9,13 +9,12 @@ use std::{collections::HashMap, fmt::Display, process::Command, str::FromStr}; use anyhow::{Context, Error, Result}; use camino::{Utf8Path, Utf8PathBuf}; use clap::Args; -use heck::ToUpperCamelCase; use serde::{Deserialize, Serialize}; use ubrn_common::{mk_dir, rm_dir, run_cmd, CrateMetadata}; use crate::{ building::{CommonBuildArgs, ExtraArgs}, - config::ProjectConfig, + config::{trim_react_native, ProjectConfig}, rust::CrateConfig, workspace, }; @@ -47,7 +46,7 @@ impl IOsConfig { fn default_framework_name() -> String { format!( "{}Framework", - workspace::package_json().name().to_upper_camel_case() + trim_react_native(&workspace::package_json().name()) ) } diff --git a/integration/fixtures/turbo-module-testing/ubrn.config.yaml b/integration/fixtures/turbo-module-testing/ubrn.config.yaml new file mode 100644 index 00000000..61ae5610 --- /dev/null +++ b/integration/fixtures/turbo-module-testing/ubrn.config.yaml @@ -0,0 +1,4 @@ +rust: + repo: https://github.com/ianthetechie/uniffi-starter + branch: main + manifestPath: rust/foobar/Cargo.toml diff --git a/scripts/test-turbo-modules.sh b/scripts/test-turbo-modules.sh index d323d86b..580749a4 100755 --- a/scripts/test-turbo-modules.sh +++ b/scripts/test-turbo-modules.sh @@ -1,25 +1,29 @@ #!/bin/bash set -e - ROOT= -PROJECT_DIR=my-test-library -KEEP_ROOT_ON_ERROR=false -BOB_VERSION=latest -PROJECT_SLUG=my-test-library -FORCE_NEW_DIR=false -IOS_NAME=MyTestLibrary -SKIP_IOS=false -SKIP_ANDROID=false -UBRN_CONFIG= UBRN_BIN= PWD= +reset_args() { + PROJECT_DIR=my-test-library + KEEP_ROOT_ON_ERROR=false + BOB_VERSION=latest + PROJECT_SLUG=my-test-library + FORCE_NEW_DIR=false + IOS_NAME=MyTestLibrary + SKIP_IOS=false + SKIP_ANDROID=false + UBRN_CONFIG= +} + usage() { echo "Usage: $0 [options] [PROJECT_DIR]" echo "" echo "Options:" echo " -A, --skip-android Skip building for Android." echo " -I, --skip-ios Skip building for iOS." + echo " -C, --ubrn-config Use a ubrn config file." + echo " -u, --builder-bob-version VERSION Specify the version of builder-bob to use." echo " -s, --slug PROJECT_SLUG Specify the project slug." echo " -i, --ios-name IOS_NAME Specify the iOS project name." @@ -32,16 +36,23 @@ usage() { } cleanup() { - if [ "$KEEP_ROOT_ON_ERROR" == false ] && [ -d "$PROJECT_DIR" ]; then - echo "Removing $PROJECT_DIR..." - rm -rf "$PROJECT_DIR" - fi + echo "Removing $PROJECT_DIR..." + rm -rf "$PROJECT_DIR" cd "$PWD" } +diagnostics() { + echo "-- PROJECT_DIR = $PROJECT_DIR" + echo "-- PROJECT_SLUG = $PROJECT_SLUG" + echo "-- IOS_NAME = $IOS_NAME" +} + error() { - echo "Error: $1" - cleanup + if [ "$KEEP_ROOT_ON_ERROR" == false ] && [ -d "$PROJECT_DIR" ]; then + cleanup + fi + diagnostics + echo "❌ Error: $1" exit 1 } @@ -59,6 +70,7 @@ derive_paths() { } parse_cli_options() { + reset_args # Parse command line options while [ $# -gt 0 ]; do case "$1" in @@ -114,14 +126,16 @@ parse_cli_options() { if [ -z "$PROJECT_DIR" ]; then PROJECT_DIR=my-test-library fi - - echo "-- PROJECT_DIR = $PROJECT_DIR" - echo "-- PROJECT_SLUG = $PROJECT_SLUG" - echo "-- IOS_NAME = $IOS_NAME" - } +enter_dir() { + local dir=$1 + pushd "$dir" >/dev/null || error "Cannot enter $dir" +} +exit_dir() { + popd >/dev/null || error "Cannot exit directory" +} create_library() { local directory @@ -132,7 +146,7 @@ create_library() { mkdir -p "$directory" || error "Cannot create $directory" fi - pushd "$directory" || error "Cannot enter $directory" + enter_dir "$directory" if [ "$FORCE_NEW_DIR" == true ] && [ -d "$base" ]; then rm -rf "$base" || error "Failed to remove existing directory $base" @@ -142,7 +156,8 @@ create_library() { if [ "$BOB_VERSION" == "latest" ] ; then example_type=test-app fi - npx create-react-native-library@$BOB_VERSION \ + echo "-- Creating library $PROJECT_SLUG with create-react-native-library@$BOB_VERSION" + npx "create-react-native-library@$BOB_VERSION" \ --slug "$PROJECT_SLUG" \ --description "An automated test" \ --author-name "James" \ @@ -152,33 +167,33 @@ create_library() { --languages cpp \ --type module-new \ --example $example_type \ - "$base" || error "Failed to create library in $PROJECT_DIR" - popd || error "Cannot exit $directory" + "$base" > /dev/null || error "Failed to create library in $PROJECT_DIR" + exit_dir } install_dependencies() { - pushd "$PROJECT_DIR" || error "Failed to navigate to $PROJECT_DIR" + enter_dir "$PROJECT_DIR" # touch yarn.lock yarn || error "Failed to install dependencies" # rm yarn.lock - popd || error "Failed to return from $PROJECT_DIR" + exit_dir } install_example_dependencies() { - pushd "$PROJECT_DIR/example" || error "Failed to navigate to $PROJECT_DIR/example" + enter_dir "$PROJECT_DIR/example" # touch yarn.lock yarn || error "Failed to install example dependencies" # rm yarn.lock # rm -Rf .yarn - popd || error "Failed to return from $PROJECT_DIR/example" + exit_dir } check_deleted_files() { local extensions="$1" local deleted_files + echo "-- Checking for deleted files with extensions $extensions" deleted_files=$(git status --porcelain | grep '^ D' || true | grep -E "\\.(${extensions// /|})$" || true ) - echo "-- finished grep" if [ -n "$deleted_files" ]; then echo "Error: The following files have been deleted:" echo "$deleted_files" @@ -186,12 +201,65 @@ check_deleted_files() { fi } -generate_turbo_module() { - pushd "$PROJECT_DIR" || error "Can't enter $PROJECT_DIR" - echo "-- Running $UBRN_BIN in PROJECT_DIR = $(pwd)" +check_line_unchanged() { + local file_pattern="$1" + local search_string="$2" + # Find all files matching the pattern + local files + files=$(find . -path "$file_pattern") + for file_path in $files; do + # Get the current content of the line containing the search string + current_line=$(grep -E "$search_string" "$file_path" || true) + # Get the content of the line containing the search string from the last commit + last_commit_line=$(git show HEAD:"$file_path" | grep -E "$search_string" || true) + + # Compare the current line with the line from the last commit + if [ "$current_line" != "$last_commit_line" ]; then + error "$file_path: found line with \"$search_string\" to have changed" + fi + done +} + +check_lines() { + echo "-- Checking for unmodified lines in generated code" + check_line_unchanged "./cpp/*.h" "#ifndef" + check_line_unchanged "./cpp/*.h" "^namespace" + check_line_unchanged "./cpp/*.cpp" ".h\"" + check_line_unchanged "./cpp/*.cpp" "^namespace" + check_line_unchanged "./src/Native*" "getEnforcing" + + check_line_unchanged "./android/CMakeLists.txt" "^project" + check_line_unchanged "./android/build.gradle" "return rootProject" + check_line_unchanged "./android/build.gradle" "libraryName" + check_line_unchanged "./android/src/*/*Package*" "package" + check_line_unchanged "./android/src/*/*Module*" "System.loadLibrary" + check_line_unchanged "./android/src/*/*Module*" "@ReactModule" + check_line_unchanged "./android/src/*/*Module*" "package" + check_line_unchanged "./android/src/*/*Module*" "public class" + check_line_unchanged "./android/cpp-adapter.cpp" "#include \"" + check_line_unchanged "./android/cpp-adapter.cpp" "nativeMultiply" + check_line_unchanged "./android/cpp-adapter.cpp" "::multiply" + + check_line_unchanged "./ios/*.h" "#import" + check_line_unchanged "./ios/*.h" "Spec.h" + check_line_unchanged "./ios/*.h" "/dev/null + echo "-- Running ubrn generate turbo-module" + "$UBRN_BIN" generate turbo-module --config "$UBRN_CONFIG" fake_module local jvm_lang if [ "$BOB_VERSION" == "latest" ] ; then @@ -199,11 +267,18 @@ generate_turbo_module() { else jvm_lang=java fi - echo "-- Checking for deleted files" check_deleted_files "$jvm_lang h mm ts podspec tsx" - echo "-- No deleted files detected" + check_lines + + exit_dir +} - popd || error "Can't exit $PROJECT_DIR" +generate_turbo_module_for_compiling() { + enter_dir "$PROJECT_DIR" + echo "-- Running ubrn checkout" + clean_turbo_modules + "$UBRN_BIN" checkout --config "$UBRN_CONFIG" + exit_dir } copy_into_node_modules() { @@ -213,6 +288,7 @@ copy_into_node_modules() { # Use rsync to copy contents, excluding cpp_modules and rust_modules directories rsync -av \ + --exclude '.git' \ --exclude 'cpp_modules' \ --exclude 'rust_modules' \ --exclude 'build' \ @@ -221,17 +297,21 @@ copy_into_node_modules() { } build_android_example() { - pushd "$PROJECT_DIR" || error "Failed to navigate to $PROJECT_DIR" - "$UBRN_BIN" build android --config "$UBRN_CONFIG" - popd || error "Failed to exit $PROJECT_DIR" - - pushd "$PROJECT_DIR/example/android" || error "Failed to navigate to $PROJECT_DIR/example/android" + enter_dir "$PROJECT_DIR" + echo "-- Running ubrn build" + "$UBRN_BIN" build android --config "$UBRN_CONFIG" --and-generate --targets aarch64-linux-android + exit_dir + enter_dir "$PROJECT_DIR/example/android" ./gradlew build || error "Failed to build Android example" - popd || error "Failed to return from $PROJECT_DIR/example/android" + exit_dir } build_ios_example() { - pushd "$PROJECT_DIR/example/ios" || error "Failed to navigate to $PROJECT_DIR/example/ios" + enter_dir "$PROJECT_DIR" + echo "-- Running ubrn build" + "$UBRN_BIN" build ios --config "$UBRN_CONFIG" --and-generate --targets aarch64-apple-ios-sim + exit_dir + enter_dir "$PROJECT_DIR/example/ios" echo "pod 'uniffi-bindgen-react-native', :path => '../../node_modules/uniffi-bindgen-react-native'" >> Podfile pod install || error "Cannot run Podfile" @@ -246,17 +326,21 @@ build_ios_example() { fi xcodebuild -workspace "${IOS_NAME}Example.xcworkspace" -scheme "${IOS_NAME}Example" -configuration Debug -destination "id=$udid" || error "Failed to build iOS example" - popd || error "Failed to return from $PROJECT_DIR/example/ios" + exit_dir } main() { + parse_cli_options "$@" + echo "ℹ️ Starting $PROJECT_SLUG" create_library - install_dependencies - if [ -n "$UBRN_CONFIG" ]; then - generate_turbo_module + if [ "$SKIP_ANDROID" == false ] || [ "$SKIP_IOS" == false ]; then + generate_turbo_module_for_compiling + install_dependencies + install_example_dependencies + copy_into_node_modules + else + generate_turbo_module_for_diffing fi - install_example_dependencies - copy_into_node_modules if [ "$SKIP_ANDROID" == false ]; then build_android_example fi @@ -264,7 +348,86 @@ main() { build_ios_example fi cleanup + echo "✅ Success!" } + +run_default() { + local fixture_dir="$ROOT/integration/fixtures/turbo-module-testing" + local working_dir="/tmp/turbomodule-tests" + local config="$fixture_dir/ubrn.config.yaml" + main \ + --force-new-directory \ + --keep-directory-on-exit \ + --ubrn-config "$config" \ + --builder-bob-version 0.35.1 \ + --skip-ios \ + --skip-android \ + --slug dummy-lib \ + "$working_dir/dummy-lib" + main \ + --force-new-directory \ + --keep-directory-on-exit \ + --ubrn-config "$config" \ + --builder-bob-version 0.35.1 \ + --skip-ios \ + --skip-android \ + --slug rn-dummy-lib \ + "$working_dir/rn-dummy-lib" + main \ + --force-new-directory \ + --keep-directory-on-exit \ + --ubrn-config "$config" \ + --builder-bob-version 0.35.1 \ + --skip-ios \ + --skip-android \ + --slug react-native-dummy-lib \ + "$working_dir/react-native-dummy-lib" + main \ + --force-new-directory \ + --keep-directory-on-exit \ + --ubrn-config "$config" \ + --builder-bob-version 0.35.1 \ + --skip-ios \ + --skip-android \ + --slug dummy-lib-react-native \ + "$working_dir/dummy-lib-react-native" + main \ + --force-new-directory \ + --keep-directory-on-exit \ + --ubrn-config "$config" \ + --builder-bob-version 0.35.1 \ + --skip-ios \ + --skip-android \ + --slug dummy-lib-react-native \ + "$working_dir/dummy-lib-rn" + # ReactNativeDummyLib fails with "› Must be a valid npm package name" + local os + os=$(uname -o) + if [ "$os" == "Darwin" ] ; then + main \ + --force-new-directory \ + --keep-directory-on-exit \ + --ubrn-config "$config" \ + --builder-bob-version 0.35.1 \ + --slug react-native-dummy-lib-for-ios \ + --skip-android \ + --ios-name DummyLibForIos \ + "$working_dir/react-native-dummy-lib-for-ios" + fi + main \ + --force-new-directory \ + --keep-directory-on-exit \ + --ubrn-config "$config" \ + --builder-bob-version 0.35.1 \ + --slug react-native-dummy-lib-for-android \ + --skip-ios \ + "$working_dir/react-native-dummy-lib-for-android" +} + derive_paths -parse_cli_options "$@" -main +# Check if there are no command line arguments +if [ $# -eq 0 ]; then + run_default +else + main "$@" +fi