Add source repository to config & docs.

This commit is contained in:
KtorZ 2022-12-17 03:19:39 +01:00
parent a83900409b
commit 1178fa3f01
No known key found for this signature in database
GPG Key ID: 33173CB6F77F4277
3 changed files with 67 additions and 16 deletions

View File

@ -1,4 +1,4 @@
use std::{fs, io, path::PathBuf}; use std::{fmt::Display, fs, io, path::PathBuf};
use serde::Deserialize; use serde::Deserialize;
@ -8,6 +8,31 @@ pub struct Config {
pub version: String, pub version: String,
#[serde(default)] #[serde(default)]
pub description: String, pub description: String,
pub repository: Option<Repository>,
}
#[derive(Deserialize)]
pub struct Repository {
pub user: String,
pub project: String,
pub platform: Platform,
}
#[derive(Deserialize)]
pub enum Platform {
Github,
Gitlab,
Bitbucket,
}
impl Display for Platform {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::result::Result<(), ::std::fmt::Error> {
match *self {
Platform::Github => f.write_str("github"),
Platform::Gitlab => f.write_str("gitlab"),
Platform::Bitbucket => f.write_str("bitbucket"),
}
}
} }
impl Config { impl Config {

View File

@ -1,4 +1,7 @@
use crate::{config::Config, module::CheckedModule}; use crate::{
config::{Config, Repository},
module::CheckedModule,
};
use aiken_lang::{ use aiken_lang::{
ast::{Definition, RecordConstructor, RecordConstructorArg, TypedDefinition}, ast::{Definition, RecordConstructor, RecordConstructorArg, TypedDefinition},
format, format,
@ -33,13 +36,13 @@ struct ModuleTemplate<'a> {
module_name: String, module_name: String,
project_name: &'a str, project_name: &'a str,
project_version: &'a str, project_version: &'a str,
links: &'a Vec<DocLink>,
modules_prefix: String, modules_prefix: String,
modules: &'a Vec<DocLink>, modules: &'a Vec<DocLink>,
functions: Vec<DocFunction>, functions: Vec<DocFunction>,
types: Vec<DocType>, types: Vec<DocType>,
constants: Vec<DocConstant>, constants: Vec<DocConstant>,
documentation: String, documentation: String,
source: &'a DocLink,
timestamp: String, timestamp: String,
} }
@ -51,10 +54,10 @@ struct PageTemplate<'a> {
page_title: &'a str, page_title: &'a str,
project_name: &'a str, project_name: &'a str,
project_version: &'a str, project_version: &'a str,
links: &'a Vec<DocLink>,
modules_prefix: String, modules_prefix: String,
modules: &'a Vec<DocLink>, modules: &'a Vec<DocLink>,
content: String, content: String,
source: &'a DocLink,
timestamp: &'a str, timestamp: &'a str,
} }
@ -64,6 +67,12 @@ struct DocLink {
path: String, path: String,
} }
impl DocLink {
pub fn is_empty(&self) -> bool {
self.name.is_empty()
}
}
/// Generate documentation files for a given project. /// Generate documentation files for a given project.
/// ///
/// The documentation is built using template files located at the root of this crate. /// The documentation is built using template files located at the root of this crate.
@ -73,6 +82,21 @@ pub fn generate_all(root: &Path, config: &Config, modules: Vec<&CheckedModule>)
let timestamp = new_timestamp(); let timestamp = new_timestamp();
let (modules_prefix, modules_links) = generate_modules_links(&modules); let (modules_prefix, modules_links) = generate_modules_links(&modules);
let source = match &config.repository {
None => DocLink {
name: String::new(),
path: String::new(),
},
Some(Repository {
user,
project,
platform,
}) => DocLink {
name: format!("{user}/{project}"),
path: format!("https://{platform}.com/{user}/{project}"),
},
};
let mut output_files: Vec<DocFile> = vec![]; let mut output_files: Vec<DocFile> = vec![];
let mut search_indexes: Vec<SearchIndex> = vec![]; let mut search_indexes: Vec<SearchIndex> = vec![];
@ -81,6 +105,7 @@ pub fn generate_all(root: &Path, config: &Config, modules: Vec<&CheckedModule>)
config, config,
module, module,
(&modules_prefix, &modules_links), (&modules_prefix, &modules_links),
&source,
&timestamp, &timestamp,
); );
search_indexes.extend(indexes); search_indexes.extend(indexes);
@ -92,6 +117,7 @@ pub fn generate_all(root: &Path, config: &Config, modules: Vec<&CheckedModule>)
root, root,
config, config,
(&modules_prefix, &modules_links), (&modules_prefix, &modules_links),
&source,
&timestamp, &timestamp,
)); ));
@ -102,6 +128,7 @@ fn generate_module(
config: &Config, config: &Config,
module: &CheckedModule, module: &CheckedModule,
(modules_prefix, modules): (&str, &Vec<DocLink>), (modules_prefix, modules): (&str, &Vec<DocLink>),
source: &DocLink,
timestamp: &Duration, timestamp: &Duration,
) -> (Vec<SearchIndex>, DocFile) { ) -> (Vec<SearchIndex>, DocFile) {
let mut search_indexes = vec![]; let mut search_indexes = vec![];
@ -147,7 +174,6 @@ fn generate_module(
let module = ModuleTemplate { let module = ModuleTemplate {
aiken_version: VERSION, aiken_version: VERSION,
breadcrumbs: to_breadcrumbs(&module.name), breadcrumbs: to_breadcrumbs(&module.name),
links: &vec![],
documentation: render_markdown(&module.ast.docs.iter().join("\n")), documentation: render_markdown(&module.ast.docs.iter().join("\n")),
modules_prefix: modules_prefix.to_string(), modules_prefix: modules_prefix.to_string(),
modules, modules,
@ -158,6 +184,7 @@ fn generate_module(
functions, functions,
types, types,
constants, constants,
source,
timestamp: timestamp.as_secs().to_string(), timestamp: timestamp.as_secs().to_string(),
}; };
@ -231,6 +258,7 @@ fn generate_readme(
root: &Path, root: &Path,
config: &Config, config: &Config,
(modules_prefix, modules): (&str, &Vec<DocLink>), (modules_prefix, modules): (&str, &Vec<DocLink>),
source: &DocLink,
timestamp: &Duration, timestamp: &Duration,
) -> DocFile { ) -> DocFile {
let path = PathBuf::from("index.html"); let path = PathBuf::from("index.html");
@ -240,13 +268,13 @@ fn generate_readme(
let template = PageTemplate { let template = PageTemplate {
aiken_version: VERSION, aiken_version: VERSION,
breadcrumbs: ".", breadcrumbs: ".",
links: &vec![],
modules_prefix: modules_prefix.to_string(), modules_prefix: modules_prefix.to_string(),
modules, modules,
project_name: &config.name, project_name: &config.name,
page_title: &config.name, page_title: &config.name,
project_version: &config.version.to_string(), project_version: &config.version.to_string(),
content: render_markdown(&content), content: render_markdown(&content),
source,
timestamp: &timestamp.as_secs().to_string(), timestamp: &timestamp.as_secs().to_string(),
}; };
@ -559,10 +587,10 @@ fn find_modules_prefix(modules: &[DocLink]) -> String {
#[test] #[test]
fn find_modules_prefix_test() { fn find_modules_prefix_test() {
assert_eq!(find_modules_prefix(&vec![]), "".to_string()); assert_eq!(find_modules_prefix(&[]), "".to_string());
assert_eq!( assert_eq!(
find_modules_prefix(&vec![DocLink { find_modules_prefix(&[DocLink {
name: "aiken/list".to_string(), name: "aiken/list".to_string(),
path: String::new() path: String::new()
}]), }]),
@ -570,7 +598,7 @@ fn find_modules_prefix_test() {
); );
assert_eq!( assert_eq!(
find_modules_prefix(&vec![DocLink { find_modules_prefix(&[DocLink {
name: "my_module".to_string(), name: "my_module".to_string(),
path: String::new() path: String::new()
}]), }]),
@ -578,7 +606,7 @@ fn find_modules_prefix_test() {
); );
assert_eq!( assert_eq!(
find_modules_prefix(&vec![ find_modules_prefix(&[
DocLink { DocLink {
name: "aiken/list".to_string(), name: "aiken/list".to_string(),
path: String::new() path: String::new()
@ -592,7 +620,7 @@ fn find_modules_prefix_test() {
); );
assert_eq!( assert_eq!(
find_modules_prefix(&vec![ find_modules_prefix(&[
DocLink { DocLink {
name: "aiken/list".to_string(), name: "aiken/list".to_string(),
path: String::new() path: String::new()

View File

@ -174,12 +174,10 @@
<svg class="label icon icon-x-circle" alt="Close Menu" title="Close Menu"><use xlink:href="#icon-x-circle"></use></svg> <svg class="label icon icon-x-circle" alt="Close Menu" title="Close Menu"><use xlink:href="#icon-x-circle"></use></svg>
</button> </button>
{% if !links.is_empty() %} {% if !source.is_empty() %}
<h2>Links</h2> <h2>Source code</h2>
<ul> <ul>
{% for link in links %} <li><a href="{{ source.path }}">{{ source.name }}</a></li>
<li><a href="{{ link.path }}">{{ link.name }}</a></li>
{% endfor %}
</ul> </ul>
{% endif %} {% endif %}