summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMinijackson <minijackson@riseup.net>2019-11-15 18:14:07 +0100
committerMinijackson <minijackson@riseup.net>2019-11-15 18:14:07 +0100
commit304d9f220cc208dd78fce11b703354ecd8d2168c (patch)
tree22c0bc3b13a21c8696d0e20be217c71d8555eabd /src
parent3301430c676e4af6b95d96b6408a66f9d2768653 (diff)
downloadposeidoc-304d9f220cc208dd78fce11b703354ecd8d2168c.tar.gz
poseidoc-304d9f220cc208dd78fce11b703354ecd8d2168c.zip
add basic config file, use codemap_diagnostic for main errors
Diffstat (limited to 'src')
-rw-r--r--src/cli.rs20
-rw-r--r--src/config.rs107
-rw-r--r--src/main.rs72
3 files changed, 196 insertions, 3 deletions
diff --git a/src/cli.rs b/src/cli.rs
index e106de7..0a883af 100644
--- a/src/cli.rs
+++ b/src/cli.rs
@@ -1,5 +1,9 @@
1use crate::config::Config;
2
1use structopt::StructOpt; 3use structopt::StructOpt;
2 4
5use std::path::PathBuf;
6
3#[derive(Debug, Clone, StructOpt)] 7#[derive(Debug, Clone, StructOpt)]
4pub(crate) struct Cli { 8pub(crate) struct Cli {
5 #[structopt(long, short, parse(from_occurrences))] 9 #[structopt(long, short, parse(from_occurrences))]
@@ -8,11 +12,27 @@ pub(crate) struct Cli {
8 #[structopt(long, number_of_values = 1, parse(try_from_str = shell_words::split))] 12 #[structopt(long, number_of_values = 1, parse(try_from_str = shell_words::split))]
9 pub(crate) extra_arg: Vec<Vec<String>>, 13 pub(crate) extra_arg: Vec<Vec<String>>,
10 14
15 #[structopt(long, short = "C", default_value = ".")]
16 pub(crate) directory: PathBuf,
17
11 #[structopt(subcommand)] 18 #[structopt(subcommand)]
12 pub(crate) command: Command, 19 pub(crate) command: Command,
20
21 #[structopt(flatten)]
22 pub(crate) common_options: Config,
13} 23}
14 24
15#[derive(Debug, Clone, StructOpt)] 25#[derive(Debug, Clone, StructOpt)]
16pub(crate) enum Command { 26pub(crate) enum Command {
17 Generate { file: String }, 27 Generate { file: String },
28 Config {
29 #[structopt(subcommand)]
30 command: ConfigCommand,
31 }
32}
33
34#[derive(Debug, Clone, StructOpt)]
35pub(crate) enum ConfigCommand {
36 Default,
37 Show,
18} 38}
diff --git a/src/config.rs b/src/config.rs
new file mode 100644
index 0000000..4463479
--- /dev/null
+++ b/src/config.rs
@@ -0,0 +1,107 @@
1use anyhow::{anyhow, Context, Result};
2use codemap::CodeMap;
3use codemap_diagnostic::Diagnostic;
4use serde_derive::{Deserialize, Serialize};
5use structopt::StructOpt;
6use thiserror::Error;
7
8use std::path::{Path, PathBuf};
9use std::sync::Arc;
10
11pub(super) const DEFAULT_PROJECT_CONFIGURATION_FILE_NAME: &str = "poseidoc.toml";
12
13#[derive(Debug, Clone, StructOpt, Deserialize, Serialize)]
14#[structopt(rename_all = "kebab-case")]
15#[serde(rename_all = "kebab-case", default)]
16pub(crate) struct Config {
17 #[structopt(skip)]
18 pub(crate) name: String,
19 #[structopt(long, default_value = ".")]
20 pub(crate) compile_commands_location: PathBuf,
21 #[structopt(skip = vec![])]
22 pub(crate) extra_clang_args: Vec<String>,
23}
24
25impl Default for Config {
26 fn default() -> Self {
27 Config {
28 name: "My Project".into(),
29 compile_commands_location: PathBuf::from(r"."),
30 extra_clang_args: Vec::new(),
31 }
32 }
33}
34
35pub(super) fn load_config(location: impl AsRef<Path>, codemap: &mut CodeMap) -> Result<Config> {
36 let location = location.as_ref();
37
38 let final_path = if location.is_dir() {
39 location.join(DEFAULT_PROJECT_CONFIGURATION_FILE_NAME)
40 } else if !location.exists() {
41 return Err(anyhow!("File {:?} does not exists", location))
42 .with_context(|| format!("Failed to open project configuration: {:?}", location));
43 } else {
44 location.to_owned()
45 };
46
47 let config_str =
48 std::fs::read_to_string(&final_path).map_err(|err| ConfigLoadError::IoError {
49 file_name: final_path.clone(),
50 source: err,
51 })?;
52 Ok(
53 toml::from_str(&config_str).map_err(|err| ConfigLoadError::TomlDeserialzation {
54 file: codemap.add_file(final_path.to_string_lossy().into(), config_str),
55 source: err,
56 })?,
57 )
58}
59
60#[derive(Debug, Error)]
61#[error("Error loading project configuration")]
62pub(crate) enum ConfigLoadError {
63 #[error("Failed to read project configuration: {:?}", file_name)]
64 IoError {
65 file_name: PathBuf,
66 source: std::io::Error,
67 },
68 #[error("Failed to parse project configuration: {:?}", file.name())]
69 TomlDeserialzation {
70 file: Arc<codemap::File>,
71 source: toml::de::Error,
72 },
73}
74
75impl From<&ConfigLoadError> for Diagnostic {
76 fn from(err: &ConfigLoadError) -> Diagnostic {
77 use codemap_diagnostic::{Level, SpanLabel, SpanStyle};
78 use std::convert::TryInto;
79
80 let message = err.to_string();
81
82 let spans = match err {
83 ConfigLoadError::IoError { .. } => vec![],
84 ConfigLoadError::TomlDeserialzation { file, source, .. } => {
85 if let Some((line, col)) = source.line_col() {
86 let line_span = file.line_span(line);
87 let col = col.try_into().unwrap();
88 let span = line_span.subspan(col, col);
89 vec![SpanLabel {
90 span,
91 label: None,
92 style: SpanStyle::Primary,
93 }]
94 } else {
95 vec![]
96 }
97 }
98 };
99
100 Diagnostic {
101 level: Level::Error,
102 message,
103 code: None,
104 spans,
105 }
106 }
107}
diff --git a/src/main.rs b/src/main.rs
index e1d4752..503688e 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,5 +1,6 @@
1//mod doxygen; 1//mod doxygen;
2mod cli; 2mod cli;
3mod config;
3mod entities; 4mod entities;
4mod generator; 5mod generator;
5mod pandoc; 6mod pandoc;
@@ -8,14 +9,63 @@ mod parsing;
8#[macro_use] 9#[macro_use]
9extern crate log; 10extern crate log;
10 11
11use cli::Command; 12use cli::{Command, ConfigCommand};
12use generator::generate; 13use generator::generate;
13use parsing::parse_file; 14use parsing::parse_file;
14 15
15use anyhow::Result; 16use anyhow::{Context, Result};
17use codemap::CodeMap;
18use codemap_diagnostic::{Diagnostic, Emitter, Level};
16use structopt::StructOpt; 19use structopt::StructOpt;
17 20
18fn main() -> Result<()> { 21fn into_diagnostic(err: &anyhow::Error) -> Diagnostic {
22 if let Some(err) = err.downcast_ref::<config::ConfigLoadError>() {
23 err.into()
24 } else {
25 Diagnostic {
26 level: Level::Error,
27 message: err.to_string(),
28 code: None,
29 spans: vec![],
30 }
31 }
32}
33
34fn main() {
35 let mut codemap = CodeMap::new();
36
37 match start(&mut codemap) {
38 Ok(()) => {}
39 Err(err) => {
40 let mut emitter =
41 Emitter::stderr(codemap_diagnostic::ColorConfig::Auto, Some(&codemap));
42
43 let mut diagnostics = Vec::new();
44 diagnostics.push(into_diagnostic(&err));
45
46 if let Some(mut source) = err.source() {
47 diagnostics.push(Diagnostic {
48 level: Level::Note,
49 message: format!("Caused by: {}", source),
50 code: None,
51 spans: vec![],
52 });
53 while let Some(source2) = source.source() {
54 source = source2;
55 diagnostics.push(Diagnostic {
56 level: Level::Note,
57 message: format!("Caused by: {}", source),
58 code: None,
59 spans: vec![],
60 });
61 }
62 }
63 emitter.emit(&diagnostics);
64 }
65 }
66}
67
68fn start(codemap: &mut CodeMap) -> Result<()> {
19 let cli = cli::Cli::from_args(); 69 let cli = cli::Cli::from_args();
20 pretty_env_logger::formatted_builder() 70 pretty_env_logger::formatted_builder()
21 .filter( 71 .filter(
@@ -30,6 +80,9 @@ fn main() -> Result<()> {
30 ) 80 )
31 .try_init()?; 81 .try_init()?;
32 82
83 std::env::set_current_dir(&cli.directory)
84 .with_context(|| format!("Cannot change current directory to: {:?}", cli.directory))?;
85
33 match cli.command { 86 match cli.command {
34 Command::Generate { file } => { 87 Command::Generate { file } => {
35 let extra_args = cli.extra_arg.iter().flatten().map(AsRef::as_ref).collect(); 88 let extra_args = cli.extra_arg.iter().flatten().map(AsRef::as_ref).collect();
@@ -38,6 +91,19 @@ fn main() -> Result<()> {
38 let base_output_dir = std::path::Path::new("doc"); 91 let base_output_dir = std::path::Path::new("doc");
39 generate(&base_output_dir, manager)?; 92 generate(&base_output_dir, manager)?;
40 } 93 }
94 Command::Config {
95 command: ConfigCommand::Default,
96 } => {
97 print!("{}", toml::to_string_pretty(&config::Config::default())?);
98 }
99 Command::Config {
100 command: ConfigCommand::Show,
101 } => {
102 print!(
103 "{}",
104 toml::to_string_pretty(&config::load_config(".", codemap)?)?
105 );
106 }
41 } 107 }
42 108
43 Ok(()) 109 Ok(())