From 3b93c9dde94f371c3cde73836a4d8bff2628380c Mon Sep 17 00:00:00 2001 From: Matthew Bentley Date: Mon, 21 Mar 2016 21:33:00 -0400 Subject: [PATCH 1/3] Add functionality to load prefs.json from profile-dir (as set with --profile-dir on launch) Use T: Read rather than File, so that read_prefs_from_file can be tested --- components/util/opts.rs | 6 +++++- components/util/prefs.rs | 46 ++++++++++++++++++++++++++++++++-------- 2 files changed, 42 insertions(+), 10 deletions(-) diff --git a/components/util/opts.rs b/components/util/opts.rs index e8d5283b9b4..0fd41e4ea96 100644 --- a/components/util/opts.rs +++ b/components/util/opts.rs @@ -799,8 +799,12 @@ pub fn from_cmdline_args(args: &[String]) -> ArgumentParsingResult { set_defaults(opts); - // This must happen after setting the default options, since the prefs rely on + // These must happen after setting the default options, since the prefs rely on // on the resource path. + // Note that command line preferences have the highest precedent + if get().profile_dir.is_some() { + prefs::add_user_prefs(); + } for pref in opt_match.opt_strs("pref").iter() { let split: Vec<&str> = pref.splitn(2, '=').collect(); let pref_name = split[0]; diff --git a/components/util/prefs.rs b/components/util/prefs.rs index 0d6a4c94660..6aa831f9687 100644 --- a/components/util/prefs.rs +++ b/components/util/prefs.rs @@ -4,9 +4,12 @@ use resource_files::resources_dir_path; use rustc_serialize::json::{Json, ToJson}; +use opts; use std::borrow::ToOwned; use std::collections::HashMap; use std::fs::File; +use std::io::Read; +use std::path::PathBuf; use std::sync::{Arc, Mutex}; lazy_static! { @@ -66,7 +69,8 @@ impl ToJson for PrefValue { } } -enum Pref { +#[derive(Debug)] +pub enum Pref { NoDefault(Arc), WithDefault(Arc, Option>) } @@ -118,14 +122,8 @@ impl ToJson for Pref { } } -fn read_prefs() -> Result, ()> { - let mut path = resources_dir_path(); - path.push("prefs.json"); - - let mut file = try!(File::open(path).or_else(|e| { - println!("Error opening preferences: {:?}.", e); - Err(()) - })); +pub fn read_prefs_from_file(mut file: T) + -> Result, ()> where T: Read { let json = try!(Json::from_reader(&mut file).or_else(|e| { println!("Ignoring invalid JSON in preferences: {:?}.", e); Err(()) @@ -145,6 +143,36 @@ fn read_prefs() -> Result, ()> { Ok(prefs) } +pub fn extend_prefs(extension: HashMap) { + PREFS.lock().unwrap().extend(extension); +} + +pub fn add_user_prefs() { + if let Some(ref dir) = opts::get().profile_dir { + let mut path = PathBuf::from(dir); + path.push("prefs.json"); + if let Ok(file) = File::open(path) { + if let Ok(prefs) = read_prefs_from_file(file) { + extend_prefs(prefs); + } + } else { + println!("Error opening prefs.json from profile_dir"); + } + } +} + +fn read_prefs() -> Result, ()> { + let mut path = resources_dir_path(); + path.push("prefs.json"); + + let file = try!(File::open(path).or_else(|e| { + println!("Error opening preferences: {:?}.", e); + Err(()) + })); + + read_prefs_from_file(file) +} + pub fn get_pref(name: &str) -> Arc { PREFS.lock().unwrap().get(name).map_or(Arc::new(PrefValue::Missing), |x| x.value().clone()) } From d06def01ff760c5893527e513713bf3504b0e979 Mon Sep 17 00:00:00 2001 From: Matthew Bentley Date: Mon, 21 Mar 2016 22:39:20 -0400 Subject: [PATCH 2/3] Add testing for prefs Also, spelling fix in opts.rs Fix order of imports to satisfy the lint Fix split line in test Fix multi-line string --- components/util/opts.rs | 2 +- components/util/prefs.rs | 2 +- tests/unit/util/lib.rs | 1 + tests/unit/util/prefs.rs | 44 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 47 insertions(+), 2 deletions(-) create mode 100644 tests/unit/util/prefs.rs diff --git a/components/util/opts.rs b/components/util/opts.rs index 0fd41e4ea96..3e18c9d9d25 100644 --- a/components/util/opts.rs +++ b/components/util/opts.rs @@ -801,7 +801,7 @@ pub fn from_cmdline_args(args: &[String]) -> ArgumentParsingResult { // These must happen after setting the default options, since the prefs rely on // on the resource path. - // Note that command line preferences have the highest precedent + // Note that command line preferences have the highest precedence if get().profile_dir.is_some() { prefs::add_user_prefs(); } diff --git a/components/util/prefs.rs b/components/util/prefs.rs index 6aa831f9687..c6033213fc8 100644 --- a/components/util/prefs.rs +++ b/components/util/prefs.rs @@ -2,9 +2,9 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +use opts; use resource_files::resources_dir_path; use rustc_serialize::json::{Json, ToJson}; -use opts; use std::borrow::ToOwned; use std::collections::HashMap; use std::fs::File; diff --git a/tests/unit/util/lib.rs b/tests/unit/util/lib.rs index a844057a4b0..d124036bef2 100644 --- a/tests/unit/util/lib.rs +++ b/tests/unit/util/lib.rs @@ -16,3 +16,4 @@ extern crate util; #[cfg(test)] mod opts; #[cfg(test)] mod str; #[cfg(test)] mod thread; +#[cfg(test)] mod prefs; diff --git a/tests/unit/util/prefs.rs b/tests/unit/util/prefs.rs new file mode 100644 index 00000000000..bb0226a7d25 --- /dev/null +++ b/tests/unit/util/prefs.rs @@ -0,0 +1,44 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +use util::prefs::{PrefValue, extend_prefs, read_prefs_from_file, get_pref, set_pref, reset_pref, reset_all_prefs}; + +#[test] +fn test_create_pref() { + let json_str = "{\ + \"layout.writing-mode.enabled\": true,\ + \"net.mime.sniff\": false,\ + \"shell.homepage\": \"http://servo.org\"\ +}"; + + let prefs = read_prefs_from_file(json_str.as_bytes()); + assert!(prefs.is_ok()); + let prefs = prefs.unwrap(); + + assert_eq!(prefs.len(), 3); +} + +#[test] +fn test_get_set_reset_extend() { + let json_str = "{\ + \"layout.writing-mode.enabled\": true,\ + \"extra.stuff\": false,\ + \"shell.homepage\": \"https://google.com\"\ +}"; + + assert_eq!(*get_pref("test"), PrefValue::Missing); + set_pref("test", PrefValue::String("hi".to_owned())); + assert_eq!(*get_pref("test"), PrefValue::String("hi".to_owned())); + assert_eq!(*get_pref("shell.homepage"), PrefValue::String("http://servo.org".to_owned())); + set_pref("shell.homepage", PrefValue::Boolean(true)); + assert_eq!(*get_pref("shell.homepage"), PrefValue::Boolean(true)); + reset_pref("shell.homepage"); + assert_eq!(*get_pref("shell.homepage"), PrefValue::String("http://servo.org".to_owned())); + + let extension = read_prefs_from_file(json_str.as_bytes()).unwrap(); + extend_prefs(extension); + assert_eq!(*get_pref("shell.homepage"), PrefValue::String("https://google.com".to_owned())); + assert_eq!(*get_pref("layout.writing-mode.enabled"), PrefValue::Boolean(true)); + assert_eq!(*get_pref("extra.stuff"), PrefValue::Boolean(false)); +} From 324b4d1e6db1a5e76c3702d8b39d7c8789ae9311 Mon Sep 17 00:00:00 2001 From: Matthew Bentley Date: Fri, 1 Apr 2016 11:59:46 -0400 Subject: [PATCH 3/3] Print errors to stderr --- components/util/prefs.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/components/util/prefs.rs b/components/util/prefs.rs index c6033213fc8..ff7fbbe5a7e 100644 --- a/components/util/prefs.rs +++ b/components/util/prefs.rs @@ -8,7 +8,7 @@ use rustc_serialize::json::{Json, ToJson}; use std::borrow::ToOwned; use std::collections::HashMap; use std::fs::File; -use std::io::Read; +use std::io::{Read, Write, stderr}; use std::path::PathBuf; use std::sync::{Arc, Mutex}; @@ -156,7 +156,8 @@ pub fn add_user_prefs() { extend_prefs(prefs); } } else { - println!("Error opening prefs.json from profile_dir"); + writeln!(&mut stderr(), "Error opening prefs.json from profile_dir") + .expect("failed printing to stderr"); } } } @@ -166,7 +167,8 @@ fn read_prefs() -> Result, ()> { path.push("prefs.json"); let file = try!(File::open(path).or_else(|e| { - println!("Error opening preferences: {:?}.", e); + writeln!(&mut stderr(), "Error opening preferences: {:?}.", e) + .expect("failed printing to stderr"); Err(()) }));