Skip to content

Commit

Permalink
Merge #244
Browse files Browse the repository at this point in the history
244: Add mechanism for cloning examples into their own crates r=lulf a=lulf



Co-authored-by: Ulf Lilleengen <[email protected]>
  • Loading branch information
bors[bot] and lulf authored Mar 21, 2022
2 parents 32a233d + 869cd9d commit 7c6a512
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 0 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ Drogue device runs on any platform supported by embassy, which at the time of wr
* Linux, Mac OS X or Windows
* WASM (WebAssembly)

Once you've found an example you like, you can run `cargo xtask clone <example_dir> <target_dir>` to create a copy with the correct dependencies and project files set up.

### Example Actor

Following is a simple drogue-device application with a single Actor implementing concurrent access to a counter.
Expand Down
11 changes: 11 additions & 0 deletions docs/modules/ROOT/pages/getting_started.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,17 @@ DEFMT_LOG=info cargo run --release

IMPORTANT: The DEFMT_LOG environment variable controls the example log verbosity. If not set, you will not see anything logged to the console.

== Creating your own project

Found an example you like? Using the examples in tree have all the dependencies set up for you, but which dependencies should you specify when creating your own project? Since drogue-device is still using nightly rust, and still have dependencies
that are not released on crates.io, we've prepared a mechanism for you to clone an example into its own folder.

To create a project based on one of the microbit examples, run the following command in the toplevel folder of the drogue-device repository:

```
cargo xtask clone examples/nrf52/microbit/jukebox $HOME/myexample
```

== Whats next?

Congratulations, you have your first Drogue Device application running! Here are some alternatives on where to go from here:
Expand Down
99 changes: 99 additions & 0 deletions xtask/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#![allow(dead_code)]
#![deny(unused_must_use)]

use core::str::FromStr;
use std::collections::BTreeMap;
use std::io::Write;
use std::{env, fs, path::PathBuf};
Expand All @@ -23,6 +24,7 @@ fn main() -> Result<(), anyhow::Error> {
["fix"] => fix(),
["update"] => update(),
["docs"] => docs(),
["clone", example, target] => clone(example, target),
["matrix"] => matrix(),
["clean"] => clean(root_dir()),
_ => {
Expand Down Expand Up @@ -244,6 +246,103 @@ fn docs() -> Result<(), anyhow::Error> {
generate_examples_page()
}

fn clone(example: &str, target_dir: &str) -> Result<(), anyhow::Error> {
let source_dir = root_dir().join(example);
let project_file = source_dir.join("Cargo.toml");

let target_dir = PathBuf::from_str(target_dir)?;

fs::create_dir_all(&target_dir)?;
let current_rev = cmd!("git rev-parse HEAD").output()?.stdout;
let mut current_rev = String::from_utf8(current_rev)?;
current_rev.pop();

let contents = fs::read_to_string(&project_file).expect("error reading file");
let mut t = contents.parse::<toml::Value>().unwrap();

if let Some(deps) = t.get_mut("dependencies") {
for dep in [
"drogue-device",
"drogue-lorawan-app",
"drogue-blinky-app",
"ble",
]
.iter()
{
if let Some(toml::Value::Table(table)) = deps.get_mut(dep) {
table.remove("path");
table.insert(
"git".to_string(),
toml::Value::String(
"https://github.com/drogue-iot/drogue-device.git".to_string(),
),
);
table.insert("rev".to_string(), toml::Value::String(current_rev.clone()));
}
}
}

fs::write(target_dir.join("Cargo.toml"), toml::to_string_pretty(&t)?)?;

// Locate closes .cargo dir
let mut cargo_dir: PathBuf = ".cargo".into();
loop {
let d = source_dir.join(&cargo_dir);
if d.exists() {
cargo_dir = d;
break;
}
let p: PathBuf = "..".into();
cargo_dir = p.join(cargo_dir);
}

// Copy files
fs::create_dir_all(&target_dir.join(".cargo"))?;
copy_files(
&cargo_dir,
vec!["config.toml".into()],
&target_dir.join(".cargo"),
)?;

// Copy files
copy_files(
&source_dir,
vec!["src".into(), "memory.x".into(), "build.rs".into()],
&target_dir,
)?;
Ok(())
}

fn copy_files(
source_dir: &PathBuf,
mut files: Vec<PathBuf>,
target_dir: &PathBuf,
) -> Result<(), anyhow::Error> {
while !files.is_empty() {
let mut next_files = Vec::new();
for file in files.drain(..) {
let source_file = source_dir.join(&file);
if let Ok(metadata) = source_file.metadata() {
let file_type = metadata.file_type();
if file_type.is_dir() {
fs::create_dir_all(&target_dir.join(&file))?;
for entry in fs::read_dir(&source_file)? {
let entry = entry?;
let name = entry.file_name().into_string().unwrap();
next_files.push(file.join(name));
}
} else {
let src = source_dir.join(&file);
let dst = target_dir.join(&file);
fs::copy(src, dst)?;
}
}
}
files = next_files;
}
Ok(())
}

fn clean(path: PathBuf) -> Result<(), anyhow::Error> {
for entry in fs::read_dir(path)? {
let entry = entry?;
Expand Down

0 comments on commit 7c6a512

Please sign in to comment.