Skip to content

Commit 5a053d7

Browse files
authored
Fix build process for unified binary (parseablehq#24)
Fixes parseablehq#18
1 parent 5eedfb5 commit 5a053d7

File tree

2 files changed

+121
-4
lines changed

2 files changed

+121
-4
lines changed

server/Cargo.toml

+9-1
Original file line numberDiff line numberDiff line change
@@ -50,4 +50,12 @@ static-files = "0.2.1"
5050
walkdir = "2"
5151

5252
[build-dependencies]
53-
static-files = "0.2.1"
53+
static-files = "0.2.1"
54+
cargo_toml = "0.11.5"
55+
ureq = "2.5.0"
56+
sha1_smol = { version = "1.0.0", features=["std"] }
57+
zip = { git = "https://github.com/zip-rs/zip" }
58+
59+
[package.metadata.parseable_ui]
60+
assets-url = "https://github.com/parseablehq/frontend/releases/download/v0.0.1/build.zip"
61+
assets-sha1 = "d9243bde7a98bdd8a19ed47cca2f12f9a5ce40ba"

server/build.rs

+112-3
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,117 @@
1616
*
1717
*/
1818

19-
use static_files::resource_dir;
19+
fn main() {
20+
println!("cargo:rerun-if-changed=build.rs");
21+
println!("cargo:rerun-if-changed=Cargo.toml");
22+
println!("cargo:rerun-if-env-changed=LOCAL_ASSETS_PATH");
23+
println!("Build File running");
24+
ui::setup().unwrap()
25+
}
26+
27+
mod ui {
28+
29+
use std::fs::{self, create_dir_all, OpenOptions};
30+
use std::io::{self, Cursor, Read, Write};
31+
use std::path::{Path, PathBuf};
32+
use std::{env, panic};
33+
34+
use cargo_toml::Manifest;
35+
use sha1_smol::Sha1;
36+
use static_files::resource_dir;
37+
use ureq::get as get_from_url;
38+
39+
fn build_resource_from(local_path: impl AsRef<Path>) -> io::Result<()> {
40+
let local_path = local_path.as_ref();
41+
if local_path.exists() {
42+
resource_dir(local_path).build()
43+
} else {
44+
Err(io::Error::new(
45+
io::ErrorKind::NotFound,
46+
"Local UI directory not found!",
47+
))
48+
}
49+
}
50+
51+
pub fn setup() -> io::Result<()> {
52+
let cargo_manifest_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap());
53+
let cargo_toml = cargo_manifest_dir.join("Cargo.toml");
54+
let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
55+
let parseable_ui_path = out_dir.join("ui");
56+
let checksum_path = out_dir.join("parseable_ui.sha1");
57+
58+
let manifest = Manifest::from_path(cargo_toml).unwrap();
59+
60+
let manifest = manifest
61+
.package
62+
.expect("package not specified in Cargo.toml")
63+
.metadata
64+
.expect("no metadata specified in Cargo.toml");
65+
66+
let metadata = manifest
67+
.get("parseable_ui")
68+
.expect("Parseable UI Metadata not defined correctly");
69+
70+
// try fetching frontend path from env var
71+
let local_assets_path: Option<PathBuf> =
72+
env::var("LOCAL_ASSETS_PATH").ok().map(PathBuf::from);
73+
74+
// If local build of ui is to be used
75+
if let Some(ref path) = local_assets_path {
76+
if path.exists() {
77+
println!("cargo:rerun-if-changed={}", path.to_str().unwrap());
78+
build_resource_from(path).unwrap();
79+
return Ok(());
80+
} else {
81+
panic!("Directory specified in LOCAL_ASSETS_PATH is not found")
82+
}
83+
}
84+
85+
// If UI is already downloaded in the target directory then verify and return
86+
if checksum_path.exists() && parseable_ui_path.exists() {
87+
let checksum = fs::read_to_string(&checksum_path)?;
88+
if checksum == metadata["assets-sha1"].as_str().unwrap() {
89+
// Nothing to do.
90+
return Ok(());
91+
}
92+
}
93+
94+
// If there is no UI in the target directory or checksum check failed
95+
// then we downlaod the UI from given url in cargo.toml metadata
96+
let url = metadata["assets-url"].as_str().unwrap();
97+
98+
// See https://docs.rs/ureq/2.5.0/ureq/struct.Response.html#method.into_reader
99+
let parseable_ui_bytes = get_from_url(url)
100+
.call()
101+
.map(|data| {
102+
let mut buf: Vec<u8> = Vec::new();
103+
data.into_reader().read_to_end(&mut buf).unwrap();
104+
buf
105+
})
106+
.expect("Failed to get resource from {url}");
107+
108+
let checksum = Sha1::from(&parseable_ui_bytes).hexdigest();
109+
110+
assert_eq!(
111+
metadata["assets-sha1"].as_str().unwrap(),
112+
checksum,
113+
"Downloaded parseable UI shasum differs from the one specified in the Cargo.toml"
114+
);
115+
116+
create_dir_all(&parseable_ui_path)?;
117+
let mut zip = zip::read::ZipArchive::new(Cursor::new(&parseable_ui_bytes))?;
118+
zip.extract(&parseable_ui_path)?;
119+
resource_dir(&parseable_ui_path).build()?;
120+
121+
let mut file = OpenOptions::new()
122+
.write(true)
123+
.create(true)
124+
.truncate(true)
125+
.open(checksum_path)?;
126+
127+
file.write_all(checksum.as_bytes())?;
128+
file.flush()?;
20129

21-
fn main() -> std::io::Result<()> {
22-
resource_dir("../ui/build").build()
130+
Ok(())
131+
}
23132
}

0 commit comments

Comments
 (0)