Skip to content
This repository has been archived by the owner on Aug 24, 2021. It is now read-only.

Add cargo-spatial-codegen tool #49

Closed
wants to merge 35 commits into from
Closed
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
2aaa589
Initial setup logic in project-example
randomPoison Jan 19, 2019
14dda35
Run the schema compiler on all schema files
randomPoison Jan 19, 2019
aae6322
Run protoc and remove temp dir
randomPoison Jan 19, 2019
aa8a226
Simplify arguments for the setup subcommand
randomPoison Jan 20, 2019
6b15455
Update README.md and remove setup.sh
randomPoison Jan 20, 2019
7810b5d
Cleanup logic in main() around setup vs worker
randomPoison Jan 20, 2019
b2b611b
Fix slashes in paths in README.md
randomPoison Jan 20, 2019
3245abb
Make setup its own binary in spatialos-sdk-tools
randomPoison Jan 21, 2019
e705498
Change globbing logic to match original bash script
randomPoison Jan 22, 2019
9ffccf3
Fixup error handling
randomPoison Jan 22, 2019
57bf2d0
Cleanup spacing and comments
randomPoison Jan 22, 2019
52f7a3d
Cleanup error handling in example
randomPoison Jan 22, 2019
e7d788e
Add clearer comments in example
randomPoison Jan 22, 2019
9041848
Rename schema_dir to output_dir
randomPoison Jan 22, 2019
f713abd
Normalize path separators
randomPoison Jan 23, 2019
a88d8c0
Run rustfmt
randomPoison Jan 23, 2019
4a9b376
Generate bundle.json as part of setup
randomPoison Jan 24, 2019
1a5171a
Allow user to specify more schema paths
randomPoison Jan 24, 2019
a105262
Fix #[structopt] attribute
randomPoison Jan 25, 2019
877acc2
Fix the --schema_path argument to schema_compiler
randomPoison Jan 25, 2019
b788212
Don't append bin to output_dir
randomPoison Jan 25, 2019
0c89058
Merge branch 'master' into example-setup-script
randomPoison Jan 29, 2019
0f20be4
Add logging to setup
randomPoison Jan 29, 2019
926f78f
Run code generation as part of setup
randomPoison Jan 29, 2019
d3d08b1
Delete codegen.sh
randomPoison Jan 29, 2019
dd1275a
Make the output dir a flag, update docs
randomPoison Jan 29, 2019
db68932
Remove leading ./ from paths because it trips up schema_compiler
randomPoison Jan 29, 2019
5ef7ca3
Update docs and comments for setup
randomPoison Jan 29, 2019
ad94734
Delete and ignore generated bindings
randomPoison Jan 29, 2019
661412d
Fix .gitignore for generated bindings
randomPoison Jan 29, 2019
1cc6817
Rename setup to cargo-spatial-codegen
randomPoison Jan 31, 2019
5baba10
Add add_schemas helper function
randomPoison Jan 31, 2019
73477f5
Remove invocation of protoc
randomPoison Jan 31, 2019
8f2a71e
Cleanup error handling for code generation
randomPoison Jan 31, 2019
3ec7231
Actually check the exit status of schema_compiler
randomPoison Jan 31, 2019
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
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@

This is still heavily WIP and should be treated as such. Progress can be seen in the `Projects` boards which define milestones and progress toward those milestones. When this reaches feature parity with the C API and has basic code generation in which all user facing APIs are safe, a crate will be published to `crates.io`.

## Setup
## Setup

1. Clone this repository.
2. Run `cargo run --bin download_sdk -- -d dependencies -s 13.5.1` to download the C API dependencies.
3. Set the `SPATIAL_LIB_DIR` environment variable to the location of the dependencies: `export SPATIAL_LIB_DIR=$(pwd)/dependencies`.
4. Run `cargo build`
4. Run `cargo build`

If these steps complete successfully, the `spatialos-sdk` crate has been built and linked successfully and can be used in user code.

Expand All @@ -21,7 +21,7 @@ If these steps complete successfully, the `spatialos-sdk` crate has been built a
To run the example project, you will need to:

1. Build a release version of the RustWorker - `cargo build --example project-example --release`.
2. Build the schema descriptor for Spatial - `./spatialos-sdk/examples/project-example/setup.sh`
2. Build the schema descriptor for Spatial - `cargo run --example project-example -- setup spatialos-sdk/examples/project-example`
3. In two terminals:
- Navigate to the `spatialos` directory and start spatial: `cd spatialos-sdk/examples/project-example/spatialos/ && spatial local launch`
- Run the example project worker - `cargo run --example project-example -- receptionist --worker_type RustWorker`
Expand Down
5 changes: 4 additions & 1 deletion spatialos-sdk/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,7 @@ path = "./examples/project-example/main.rs"

[dev-dependencies]
uuid = { version = "0.7", features = ["v4"] }
clap = "2.32.0"
clap = "2.32.0"
glob = "0.2.11"
fs_extra = "1.1.0"
tap = "0.3.0"
50 changes: 45 additions & 5 deletions spatialos-sdk/examples/project-example/lib/argument_parsing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,30 @@ use self::clap::{App, Arg, ArgMatches, SubCommand};

use spatialos_sdk::worker::locator::{LocatorCredentials, LocatorParameters};
use spatialos_sdk::worker::parameters::ConnectionParameters;
use std::path::PathBuf;

static RECEPTIONIST_HOST: &str = "127.0.0.1";
static RECEPTIONIST_PORT: u16 = 7777;

static RECEPTIONIST_SUBCOMMAND: &str = "receptionist";
static LOCATOR_SUBCOMMAND: &str = "locator";
static SETUP_SUBCOMMAND: &str = "setup";

static CONNECT_POLL_ARG: &str = "connect_with_poll";
static EXTERNAL_IP_ARG: &str = "use_external_ip";
static LOCATOR_TOKEN_ARG: &str = "locator_token";
static PROJECT_NAME_ARG: &str = "project_name";
static WORKER_TYPE_ARG: &str = "worker_type";
static SPATIAL_LIB_DIR_ARG: &str = "spatial_lib_dir";
static SETUP_OUT_ARG: &str = "out_dir";

pub enum CommandType {
Worker(WorkerConfiguration),
Setup {
spatial_lib_dir: Option<PathBuf>,
out_dir: PathBuf,
},
}

pub enum ConnectionType {
Receptionist(String, u16),
Expand All @@ -29,7 +41,7 @@ pub struct WorkerConfiguration {
}

// Gets the configuration of the worker.
pub fn get_worker_configuration() -> Result<WorkerConfiguration, String> {
pub fn get_worker_configuration() -> Result<CommandType, String> {
let polling_connection_arg = Arg::with_name(CONNECT_POLL_ARG)
.long(CONNECT_POLL_ARG)
.short("p")
Expand Down Expand Up @@ -80,6 +92,22 @@ pub fn get_worker_configuration() -> Result<WorkerConfiguration, String> {
.required(true),
),
)
.subcommand(
SubCommand::with_name(SETUP_SUBCOMMAND)
.arg(
Arg::with_name(SPATIAL_LIB_DIR_ARG)
.long(SPATIAL_LIB_DIR_ARG)
.short("l")
.value_name("SPATIAL_LIB_DIR")
.help("The path to the directory whe the SpatialOS library is installed. If omitted, the command will attempt to use the SPATIAL_LIB_DIR environment variable instead."),
)
.arg(
Arg::with_name(SETUP_OUT_ARG)
.value_name("OUT_DIR")
.help("The output directory")
.required(true),
)
)
.get_matches();

if let Some(sub_matches) = matches.subcommand_matches(LOCATOR_SUBCOMMAND) {
Expand All @@ -100,11 +128,11 @@ pub fn get_worker_configuration() -> Result<WorkerConfiguration, String> {
.using_tcp()
.using_external_ip();

return Ok(WorkerConfiguration {
return Ok(CommandType::Worker(WorkerConfiguration {
connection_params: params,
connect_with_poll: sub_matches.is_present(CONNECT_POLL_ARG),
connection_type: ConnectionType::Locator(locator_params),
});
}));
}

if let Some(sub_matches) = matches.subcommand_matches(RECEPTIONIST_SUBCOMMAND) {
Expand All @@ -114,14 +142,26 @@ pub fn get_worker_configuration() -> Result<WorkerConfiguration, String> {
params.network.use_external_ip = true;
}

return Ok(WorkerConfiguration {
return Ok(CommandType::Worker(WorkerConfiguration {
connection_params: params,
connect_with_poll: sub_matches.is_present(CONNECT_POLL_ARG),
connection_type: ConnectionType::Receptionist(
RECEPTIONIST_HOST.to_string(),
RECEPTIONIST_PORT,
),
});
}));
}

if let Some(sub_matches) = matches.subcommand_matches(SETUP_SUBCOMMAND) {
let spatial_lib_dir = sub_matches
.value_of(SPATIAL_LIB_DIR_ARG)
.map(Into::into);

let out_dir = sub_matches
.value_of(SETUP_OUT_ARG)
.expect("No output directory specified")
.into();
return Ok(CommandType::Setup { spatial_lib_dir, out_dir })
}

Err("Please select one of the subcommands".to_owned())
Expand Down
34 changes: 26 additions & 8 deletions spatialos-sdk/examples/project-example/main.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
extern crate spatialos_sdk;

mod lib;
use crate::lib::{get_connection, get_worker_configuration};
mod setup;
use crate::lib::{get_connection, get_worker_configuration, CommandType};

use spatialos_sdk::worker::commands::{
DeleteEntityRequest, EntityQueryRequest, ReserveEntityIdsRequest,
Expand All @@ -14,18 +15,35 @@ use spatialos_sdk::worker::{EntityId, InterestOverride, LogLevel};
fn main() {
println!("Entered program");

// Get the configuration for the app from the command line arguments, exiting
// with an error code if the arguments are invalid.
let config = match get_worker_configuration() {
Ok(c) => c,
Err(e) => panic!("{}", e),
};
let worker_connection = match get_connection(config) {
Ok(c) => c,
Err(e) => panic!("{}", e),
Err(e) => {
eprintln!("{}", e);
std::process::exit(1);
}
};

println!("Connected as: {}", worker_connection.get_worker_id());
match config {
// Spawn a worker with the configuration specified by the user.
CommandType::Worker(config) => {
let worker_connection = match get_connection(config) {
Ok(c) => c,
Err(e) => panic!("{}", e),
};

println!("Connected as: {}", worker_connection.get_worker_id());

exercise_connection_code_paths(worker_connection);
exercise_connection_code_paths(worker_connection);
},

// Perform initial setup for the example by compiling necessary schema files.
CommandType::Setup { spatial_lib_dir, out_dir } => {
crate::setup::do_setup(spatial_lib_dir, out_dir);
return;
}
}
}

fn exercise_connection_code_paths(mut c: WorkerConnection) {
Expand Down
81 changes: 81 additions & 0 deletions spatialos-sdk/examples/project-example/setup.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
use fs_extra::dir::{self, CopyOptions};
use std::ffi::OsString;
use std::fs;
use std::path::PathBuf;
use std::process::Command;
use tap::*;

pub fn do_setup(spatial_lib_dir: Option<PathBuf>, out_dir: PathBuf) {
let spatial_lib_dir = spatial_lib_dir
.or_else(|| std::env::var("SPATIAL_LIB_DIR").map(Into::into).ok())
.expect("--spatial_lib_dir argument must be specified or the SPATIAL_LIB_DIR environment variable must be set");

// Determine the paths the the schema compiler and protoc relative the the lib
// dir path.
let schema_compiler_path = spatial_lib_dir.join("schema-compiler/schema_compiler");
let protoc_path = spatial_lib_dir.join("schema-compiler/protoc");

// Calculate the various output directories relative to `out_dir`.
let bin_path = out_dir.join("spatialos/schema/bin");
let tmp_path = out_dir.join("tmp");

// Create the output directories if they don't already exist.
fs::create_dir_all(&bin_path).expect("Failed to crate spatialos/schema/bin");
fs::create_dir_all(&tmp_path).expect("Failed to create tmp");

// Copy the contents of the schema-compiler/proto dir into the temp dir.
let proto_dir_glob = spatial_lib_dir.join("schema-compiler/proto/*");
for entry in glob::glob(proto_dir_glob.to_str().unwrap())
.unwrap()
.filter_map(Result::ok)
{
dir::copy(
&entry,
&tmp_path,
&CopyOptions {
overwrite: true,
..CopyOptions::new()
},
)
.expect("Failed to copy contents of schema-compiler/proto");
}

// Run the schema compiler for each of the schema files in std-lib/improbable.
let schema_glob = spatial_lib_dir.join("std-lib/improbable/*.schema");
let schema_path_arg =
OsString::from("--schema_path=").tap(|arg| arg.push(&spatial_lib_dir.join("std-lib")));
let proto_out_arg = OsString::from("--proto_out=").tap(|arg| arg.push(&tmp_path));
for entry in glob::glob(schema_glob.to_str().unwrap())
.unwrap()
.filter_map(Result::ok)
{
Command::new(&schema_compiler_path)
.arg(&schema_path_arg)
.arg(&proto_out_arg)
.arg("--load_all_schema_on_schema_path")
.arg(&entry)
.status()
.expect("Failed to compile schema :'(");
}

// Run protoc on all the generated proto files.
let proto_glob = tmp_path.join("**/*.proto");
let proto_path_arg = OsString::from("--proto_path=").tap(|arg| arg.push(&tmp_path));
let descriptor_out_arg = OsString::from("--descriptor_set_out=")
.tap(|arg| arg.push(&bin_path.join("schema.descriptor")));
for entry in glob::glob(proto_glob.to_str().unwrap())
.unwrap()
.filter_map(Result::ok)
{
let mut command = Command::new(&protoc_path);
command
.arg(&proto_path_arg)
.arg(&descriptor_out_arg)
.arg("--include_imports")
.arg(&entry)
.status()
.expect("Failed to run protoc");
}

fs::remove_dir_all(&tmp_path).expect("Failed to remove temp dir");
}
18 changes: 0 additions & 18 deletions spatialos-sdk/examples/project-example/setup.sh

This file was deleted.