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

Use JSON for internal platform config, to avoid TOML issues #220

Merged
merged 4 commits into from
Dec 18, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 2 additions & 2 deletions crates/notion-core/src/path/unix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ cfg_if! {
// ember-cli/
// package.toml
// contents/
// platform.toml user_platform_file
// platform.json user_platform_file
// notion notion_file
// launchbin launchbin_file
// launchscript launchscript_file
Expand Down Expand Up @@ -186,7 +186,7 @@ pub fn user_toolchain_dir() -> Fallible<PathBuf> {
}

pub fn user_platform_file() -> Fallible<PathBuf> {
Ok(user_toolchain_dir()?.join("platform.toml"))
Ok(user_toolchain_dir()?.join("platform.json"))
}

pub fn create_file_symlink(src: PathBuf, dst: PathBuf) -> Result<(), io::Error> {
Expand Down
4 changes: 2 additions & 2 deletions crates/notion-core/src/path/windows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ cfg_if! {
// ember-cli\
// package.toml
// contents\
// platform.toml user_platform_file
// platform.json user_platform_file
// notion.exe notion_file
// launchbin.exe launchbin_file
// launchscript.exe launchscript_file
Expand Down Expand Up @@ -188,7 +188,7 @@ pub fn user_toolchain_dir() -> Fallible<PathBuf> {
}

pub fn user_platform_file() -> Fallible<PathBuf> {
Ok(user_toolchain_dir()?.join("platform.toml"))
Ok(user_toolchain_dir()?.join("platform.json"))
}

pub fn create_file_symlink(src: PathBuf, dst: PathBuf) -> Result<(), io::Error> {
Expand Down
13 changes: 7 additions & 6 deletions crates/notion-core/src/toolchain/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ use std::io::Write;

use readext::ReadExt;
use semver::Version;
use toml;

use distro::node::NodeVersion;
use fs::touch;
Expand All @@ -22,14 +21,13 @@ impl Toolchain {
pub fn current() -> Fallible<Toolchain> {
let path = user_platform_file()?;
let src = touch(&path)?.read_into_string().unknown()?;
let serial: serial::Platform = toml::from_str(&src).unknown()?;
Ok(Toolchain {
platform: serial.into_image()?
platform: serial::Platform::from_json(src)?.into_image()?,
})
}

pub fn get_active_node(&self) -> Option<NodeVersion> {
self.platform.as_ref().map(|ref p| { p.node.clone() })
self.platform.as_ref().map(|ref p| p.node.clone())
}

pub fn set_active_node(&mut self, version: NodeVersion) -> Fallible<()> {
Expand All @@ -56,7 +54,9 @@ impl Toolchain {
}

pub fn get_active_yarn(&self) -> Option<Version> {
self.platform.as_ref().and_then(|ref platform| { platform.yarn.clone() })
self.platform
.as_ref()
.and_then(|ref platform| platform.yarn.clone())
}

pub fn set_active_yarn(&mut self, version: Version) -> Fallible<()> {
Expand All @@ -81,7 +81,7 @@ impl Toolchain {
let mut file = File::create(&path).unknown()?;
match &self.platform {
&Some(ref platform) => {
let src = toml::to_string_pretty(&platform.to_serial()).unwrap();
let src = platform.to_serial().to_json()?;
file.write_all(src.as_bytes()).unknown()?;
}
&None => {
Expand All @@ -91,3 +91,4 @@ impl Toolchain {
Ok(())
}
}

91 changes: 83 additions & 8 deletions crates/notion-core/src/toolchain/serial.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,20 @@ use distro;
use notion_fail::{Fallible, ResultExt};

use semver::Version;
use serde_json;

#[derive(Serialize, Deserialize)]
#[derive(Serialize, Deserialize, Debug, PartialEq)]
pub struct NodeVersion {
runtime: String,
npm: String,
pub runtime: String,
pub npm: String,
}

#[derive(Serialize, Deserialize)]
#[derive(Serialize, Deserialize, Debug, PartialEq)]
pub struct Platform {
#[serde(default)]
dherman marked this conversation as resolved.
Show resolved Hide resolved
node: Option<NodeVersion>,
pub node: Option<NodeVersion>,
#[serde(default)]
yarn: Option<String>,
pub yarn: Option<String>,
}

impl Platform {
Expand All @@ -35,9 +36,23 @@ impl Platform {

Some(Image { node, yarn })
}
None => None
None => None,
})
}

/// Deserialize the input JSON String into a Platform
pub fn from_json(src: String) -> Fallible<Self> {
if src.is_empty() {
serde_json::de::from_str("{}").unknown()
} else {
serde_json::de::from_str(&src).unknown()
}
}

/// Serialize the Platform to a JSON String
pub fn to_json(self) -> Fallible<String> {
serde_json::to_string_pretty(&self).unknown()
}
}

impl Image {
Expand All @@ -47,7 +62,67 @@ impl Image {
runtime: self.node.runtime.to_string(),
npm: self.node.npm.to_string(),
}),
yarn: self.yarn.as_ref().map(|yarn| yarn.to_string())
yarn: self.yarn.as_ref().map(|yarn| yarn.to_string()),
}
}
}


#[cfg(test)]
pub mod tests {

use super::*;
use distro;
use image;
use semver;

// NOTE: serde_json is required with the "preserve_order" feature in Cargo.toml,
// so these tests will serialized/deserialize in a predictable order

const BASIC_JSON_STR: &'static str = r#"{
"node": {
"runtime": "4.5.6",
"npm": "7.8.9"
},
"yarn": "1.2.3"
}"#;

#[test]
fn test_from_json() {
let json_str = BASIC_JSON_STR.to_string();
let platform = Platform::from_json(json_str).expect("could not parse JSON string");
let expected_platform = Platform {
yarn: Some("1.2.3".to_string()),
node: Some(NodeVersion {
runtime: "4.5.6".to_string(),
npm: "7.8.9".to_string(),
}),
};
assert_eq!(platform, expected_platform);
}

#[test]
fn test_from_json_empty_string() {
let json_str = "".to_string();
let platform = Platform::from_json(json_str).expect("could not parse JSON string");
let expected_platform = Platform {
node: None,
yarn: None,
};
assert_eq!(platform, expected_platform);
}

#[test]
fn test_to_json() {
let platform = image::Image {
yarn: Some(semver::Version::parse("1.2.3").expect("could not parse semver version")),
node: distro::node::NodeVersion {
runtime: semver::Version::parse("4.5.6").expect("could not parse semver version"),
npm: semver::Version::parse("7.8.9").expect("could not parse semver version"),
},
};
let json_str = platform.to_serial().to_json().expect("could not serialize platform to JSON");
let expected_json_str = BASIC_JSON_STR.to_string();
assert_eq!(json_str, expected_json_str);
}
}
6 changes: 3 additions & 3 deletions tests/acceptance/notion_current.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ fn pinned_project() {
fn pinned_project_with_user_node_default() {
let s = sandbox()
.package_json(&package_json_with_pinned_node("4.1.0", "2.14.3"))
.platform("node = [ '9.11.2', '5.6.0' ]")
.platform(r#"{"node":{"runtime":"9.11.2","npm":"5.6.0"}}"#)
.build();

assert_that!(
Expand Down Expand Up @@ -68,7 +68,7 @@ fn unpinned_project() {
fn unpinned_project_with_user_node_default() {
let s = sandbox()
.package_json(BASIC_PACKAGE_JSON)
.platform("node = [ '9.11.2', '5.6.0' ]")
.platform(r#"{"node":{"runtime":"9.11.2","npm":"5.6.0"}}"#)
.build();

assert_that!(
Expand All @@ -94,7 +94,7 @@ fn no_project() {
#[test]
fn no_project_with_user_node_default() {
let s = sandbox()
.platform("node = [ '9.11.2', '5.6.0' ]")
.platform(r#"{"node":{"runtime":"9.11.2","npm":"5.6.0"}}"#)
.build();

assert_that!(
Expand Down
6 changes: 3 additions & 3 deletions tests/acceptance/support/sandbox.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ impl EnvVar {
}
}

// used to construct sandboxed package.json and platform.toml
// used to construct sandboxed package.json and platform.json
#[derive(PartialEq, Clone)]
pub struct FileBuilder {
path: PathBuf,
Expand Down Expand Up @@ -219,7 +219,7 @@ impl SandboxBuilder {
self
}

/// Set the platform.toml for the sandbox (chainable)
/// Set the platform.json for the sandbox (chainable)
pub fn platform(mut self, contents: &str) -> Self {
self.files
.push(FileBuilder::new(user_platform_file(), contents));
Expand Down Expand Up @@ -422,7 +422,7 @@ fn package_json_file(mut root: PathBuf) -> PathBuf {
root
}
fn user_platform_file() -> PathBuf {
user_dir().join("platform.toml")
user_dir().join("platform.json")
}

pub struct Sandbox {
Expand Down