Commit 7c7b30c1 authored by Jeremy Soller's avatar Jeremy Soller Committed by GitHub

Merge pull request #2 from ids1024/pkgutils_cookbook

Use install methods from pkgutils, and allow installing directly from cookbook with --cookbook=path
parents 4e9d22ad bb94edcb
......@@ -16,7 +16,6 @@ pkgutils = { git = "https://github.com/redox-os/pkgutils.git" }
rand = "0.3"
serde = "0.8"
serde_derive = "0.8"
tar = { git = "https://github.com/redox-os/tar-rs.git" }
termion = "1.1"
toml = { version = "0.2", default-features = false, features = ["serde"] }
userutils = { git = "https://github.com/redox-os/userutils.git" }
......@@ -7,13 +7,26 @@ extern crate toml;
use std::{env, process};
use std::fs::File;
use std::io::{self, Read, Write};
use std::path::Path;
fn main() {
let stderr = io::stderr();
let mut stderr = stderr.lock();
let mut configs = vec![];
let mut cookbook = None;
for arg in env::args().skip(1) {
if arg.starts_with("--cookbook=") {
let path = arg.splitn(2, "--cookbook=").nth(1).unwrap().to_string();
if !Path::new(&path).is_dir() {
writeln!(stderr, "installer: {}: cookbook not found", arg).unwrap();
process::exit(1);
}
cookbook = Some(path);
continue;
}
match File::open(&arg) {
Ok(mut config_file) => {
let mut config_data = String::new();
......@@ -59,7 +72,7 @@ fn main() {
}
for config in configs {
if let Err(err) = redox_installer::install(config) {
if let Err(err) = redox_installer::install(config, cookbook.as_ref().map(String::as_ref)) {
writeln!(stderr, "installer: failed to install: {}", err).unwrap();
process::exit(1);
}
......
extern crate liner;
extern crate pkgutils;
extern crate rand;
extern crate tar;
extern crate termion;
extern crate userutils;
use self::rand::Rng;
use self::tar::{Archive, EntryType};
use self::termion::input::TermRead;
use self::pkgutils::Repo;
use std::{env, fs};
use std::io::{self, Read, Write};
use std::os::unix::fs::OpenOptionsExt;
use std::path::Path;
use std::io::{self, stderr, Write};
use std::str::FromStr;
use std::process::{self, Command};
use config::Config;
const REMOTE: &'static str = "https://static.redox-os.org/pkg";
const TARGET: &'static str = "x86_64-unknown-redox";
fn unwrap_or_prompt<T: FromStr>(option: Option<T>, context: &mut liner::Context, prompt: &str) -> Result<T, String> {
match option {
None => {
......@@ -63,47 +64,40 @@ fn prompt_password(prompt: &str, confirm_prompt: &str) -> Result<String, String>
}
}
fn extract_inner<T: Read>(ar: &mut Archive<T>, root: &Path) -> io::Result<()> {
for entry_result in try!(ar.entries()) {
let mut entry = try!(entry_result);
match entry.header().entry_type() {
EntryType::Regular => {
let mut file = {
let mut path = root.to_path_buf();
path.push(try!(entry.path()));
if let Some(parent) = path.parent() {
println!("Extract file parent {}", parent.display());
try!(fs::create_dir_all(parent));
}
println!("Extract file {}", path.display());
try!(
fs::OpenOptions::new()
.read(true)
.write(true)
.truncate(true)
.create(true)
.mode(entry.header().mode().unwrap_or(644))
.open(path)
)
};
try!(io::copy(&mut entry, &mut file));
},
EntryType::Directory => {
let mut path = root.to_path_buf();
path.push(try!(entry.path()));
println!("Extract directory {}", path.display());
try!(fs::create_dir_all(path));
},
other => {
panic!("Unsupported entry type {:?}", other);
}
fn install_packages(config: &Config, dest: &str, cookbook: Option<&str>) {
let mut repo = Repo::new(TARGET);
repo.add_remote(REMOTE);
repo.set_dest(dest);
if let Some(cookbook) = cookbook {
let status = Command::new("./update-packages.sh")
.current_dir(cookbook)
.args(config.packages.keys())
.spawn()
.unwrap()
.wait()
.unwrap();
if !status.success() {
write!(stderr(), "./update-package.sh failed.").unwrap();
process::exit(1);
}
}
Ok(())
for (packagename, _package) in &config.packages {
let path = format!("{}/{}/repo/{}/{}.tar",
env::current_dir().unwrap().to_string_lossy(),
cookbook, TARGET, packagename);
repo.install_file(&path).unwrap();
}
} else {
for (packagename, _package) in &config.packages {
println!("Installing package {}", packagename);
repo.install(&packagename).unwrap();
}
}
}
pub fn install(config: Config) -> Result<(), String> {
pub fn install(config: Config, cookbook: Option<&str>) -> Result<(), String> {
println!("Install {:#?}", config);
let mut context = liner::Context::new();
......@@ -125,7 +119,7 @@ pub fn install(config: Config) -> Result<(), String> {
let sysroot = {
let mut wd = env::current_dir().map_err(|err| format!("failed to get current dir: {}", err))?;
let path = prompt!(config.general.sysroot, "sysroot".to_string(), "sysroot [sysroot]: ")?;
let path = prompt!(config.general.sysroot.clone(), "sysroot".to_string(), "sysroot [sysroot]: ")?;
wd.push(path);
wd
};
......@@ -155,21 +149,7 @@ pub fn install(config: Config) -> Result<(), String> {
dir!("");
for (packagename, _package) in config.packages {
let remote_path = format!("{}/{}/{}.tar", "https://static.redox-os.org/pkg", "x86_64-unknown-redox", packagename);
let local_path = format!("pkg/{}.tar", packagename);
if let Some(parent) = Path::new(&local_path).parent() {
println!("Create package repository {}", parent.display());
fs::create_dir_all(parent).map_err(|err| format!("failed to create package repository {}: {}", parent.display(), err))?;
}
println!("Download package {} to {}", remote_path, local_path);
pkgutils::download(&remote_path, &local_path).map_err(|err| format!("failed to download {} to {}: {}", remote_path, local_path, err))?;
let path = Path::new(&local_path);
println!("Extract package {}", path.display());
let file = fs::File::open(&path).map_err(|err| format!("failed to open {}: {}", path.display(), err))?;
extract_inner(&mut Archive::new(file), &sysroot).map_err(|err| format!("failed to extract {}: {}", path.display(), err))?;
}
install_packages(&config, sysroot.to_str().unwrap(), cookbook);
for file in config.files {
file!(file.path.trim_matches('/'), file.data.as_bytes());
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment