Generate example configuration (fix #198)
This commit is contained in:
24
README.md
24
README.md
@@ -113,29 +113,7 @@ Just run `topgrade`. It will run the following steps:
|
|||||||
* **FreeBSD**: Run `freebsd-upgrade`
|
* **FreeBSD**: Run `freebsd-upgrade`
|
||||||
|
|
||||||
## Customization
|
## Customization
|
||||||
Here's an example for a configuration file:
|
See `config.example.toml` for an example configuration file.
|
||||||
|
|
||||||
|
|
||||||
``` toml
|
|
||||||
git_repos = [
|
|
||||||
"~/src/*/",
|
|
||||||
"~/.config/something"
|
|
||||||
]
|
|
||||||
|
|
||||||
# Same options as the command line flag
|
|
||||||
disable = ["system", "emacs"]
|
|
||||||
|
|
||||||
[pre_commands]
|
|
||||||
"Emacs Snapshot" = "rm -rf ~/.emacs.d/elpa.bak && cp -rl ~/.emacs.d/elpa ~/.emacs.d/elpa.bak"
|
|
||||||
|
|
||||||
[commands]
|
|
||||||
"Python Environment" = "~/dev/.env/bin/pip install -i https://pypi.python.org/simple -U --upgrade-strategy eager jupyter"
|
|
||||||
```
|
|
||||||
* `git_repos` - A list of custom Git repositories to pull
|
|
||||||
* `pre_commands` - Commands to execute before starting any action. If any command fails, Topgrade
|
|
||||||
will not proceed
|
|
||||||
* `commands` - Custom upgrade steps. If any command fails it will be reported in the summary as all
|
|
||||||
upgrade steps are reported, but it will not cause Topgrade to stop.
|
|
||||||
|
|
||||||
### Configuration path
|
### Configuration path
|
||||||
|
|
||||||
|
|||||||
19
config.example.toml
Normal file
19
config.example.toml
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
# Additional git repositories to pull
|
||||||
|
#git_repos = [
|
||||||
|
# "~/src/*/",
|
||||||
|
# "~/.config/something"
|
||||||
|
#]
|
||||||
|
|
||||||
|
# Same options as the command line flag
|
||||||
|
#disable = ["system", "emacs"]
|
||||||
|
|
||||||
|
# List of remote machines with Topgrade installed on them
|
||||||
|
#remote_topgrades = ["toothless", "pi", "parnas"]
|
||||||
|
|
||||||
|
# Commands to run before anything
|
||||||
|
#[pre_commands]
|
||||||
|
#"Emacs Snapshot" = "rm -rf ~/.emacs.d/elpa.bak && cp -rl ~/.emacs.d/elpa ~/.emacs.d/elpa.bak"
|
||||||
|
|
||||||
|
# Custom commands
|
||||||
|
#[commands]
|
||||||
|
#"Python Environment" = "~/dev/.env/bin/pip install -i https://pypi.python.org/simple -U --upgrade-strategy eager jupyter"
|
||||||
@@ -2,9 +2,12 @@ use super::error::{Error, ErrorKind};
|
|||||||
use directories::BaseDirs;
|
use directories::BaseDirs;
|
||||||
use failure::ResultExt;
|
use failure::ResultExt;
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
|
use log::{debug, error, LevelFilter};
|
||||||
|
use pretty_env_logger::formatted_timed_builder;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use shellexpand;
|
use shellexpand;
|
||||||
use std::collections::{BTreeMap, HashMap};
|
use std::collections::{BTreeMap, HashMap};
|
||||||
|
use std::fs::write;
|
||||||
use std::{env, fs};
|
use std::{env, fs};
|
||||||
use structopt::StructOpt;
|
use structopt::StructOpt;
|
||||||
use toml;
|
use toml;
|
||||||
@@ -72,7 +75,7 @@ impl std::str::FromStr for Step {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Default)]
|
#[derive(Deserialize, Default, Debug)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
/// Configuration file
|
/// Configuration file
|
||||||
pub struct ConfigFile {
|
pub struct ConfigFile {
|
||||||
@@ -90,6 +93,16 @@ impl ConfigFile {
|
|||||||
fn read(base_dirs: &BaseDirs) -> Result<ConfigFile, Error> {
|
fn read(base_dirs: &BaseDirs) -> Result<ConfigFile, Error> {
|
||||||
let config_path = base_dirs.config_dir().join("topgrade.toml");
|
let config_path = base_dirs.config_dir().join("topgrade.toml");
|
||||||
if !config_path.exists() {
|
if !config_path.exists() {
|
||||||
|
write(&config_path, include_str!("../config.example.toml"))
|
||||||
|
.map_err(|e| {
|
||||||
|
error!(
|
||||||
|
"Unable to write the example configuration file to {}: {}",
|
||||||
|
config_path.display(),
|
||||||
|
e
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.ok();
|
||||||
|
debug!("No configuration exists");
|
||||||
return Ok(Default::default());
|
return Ok(Default::default());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,6 +115,8 @@ impl ConfigFile {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
debug!("Loaded configuration: {:?}", result);
|
||||||
|
|
||||||
Ok(result)
|
Ok(result)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -154,8 +169,18 @@ impl Config {
|
|||||||
///
|
///
|
||||||
/// The function parses the command line arguments and reading the configuration file.
|
/// The function parses the command line arguments and reading the configuration file.
|
||||||
pub fn load(base_dirs: &BaseDirs) -> Result<Self, Error> {
|
pub fn load(base_dirs: &BaseDirs) -> Result<Self, Error> {
|
||||||
|
let opt = CommandLineArgs::from_args();
|
||||||
|
|
||||||
|
let mut builder = formatted_timed_builder();
|
||||||
|
|
||||||
|
if opt.verbose {
|
||||||
|
builder.filter(Some("topgrade"), LevelFilter::Trace);
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.init();
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
opt: CommandLineArgs::from_args(),
|
opt,
|
||||||
config_file: ConfigFile::read(base_dirs)?,
|
config_file: ConfigFile::read(base_dirs)?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -210,11 +235,6 @@ impl Config {
|
|||||||
self.opt.no_retry
|
self.opt.no_retry
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Tell whether we should print log.
|
|
||||||
pub fn verbose(&self) -> bool {
|
|
||||||
self.opt.verbose
|
|
||||||
}
|
|
||||||
|
|
||||||
/// List of remote hosts to run Topgrade in
|
/// List of remote hosts to run Topgrade in
|
||||||
pub fn remote_topgrades(&self) -> &Option<Vec<String>> {
|
pub fn remote_topgrades(&self) -> &Option<Vec<String>> {
|
||||||
&self.config_file.remote_topgrades
|
&self.config_file.remote_topgrades
|
||||||
|
|||||||
11
src/main.rs
11
src/main.rs
@@ -16,10 +16,9 @@ use self::report::Report;
|
|||||||
use self::steps::*;
|
use self::steps::*;
|
||||||
use self::terminal::*;
|
use self::terminal::*;
|
||||||
use failure::{Fail, ResultExt};
|
use failure::{Fail, ResultExt};
|
||||||
use log::{debug, LevelFilter};
|
use log::debug;
|
||||||
#[cfg(feature = "self-update")]
|
#[cfg(feature = "self-update")]
|
||||||
use openssl_probe;
|
use openssl_probe;
|
||||||
use pretty_env_logger::formatted_timed_builder;
|
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
@@ -75,14 +74,6 @@ fn run() -> Result<(), Error> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut builder = formatted_timed_builder();
|
|
||||||
|
|
||||||
if config.verbose() {
|
|
||||||
builder.filter(Some("topgrade"), LevelFilter::Trace);
|
|
||||||
}
|
|
||||||
|
|
||||||
builder.init();
|
|
||||||
|
|
||||||
let git = git::Git::new();
|
let git = git::Git::new();
|
||||||
let mut git_repos = git::Repositories::new(&git);
|
let mut git_repos = git::Repositories::new(&git);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user