diff --git a/.gitignore b/.gitignore index d53fea87..fde266bf 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,9 @@ /target public/ oranda-debug.log -# banish macos to the depths of hell .DS_Store .idea/ +.oranda-cache # oranda-css oranda-css/dist @@ -13,4 +13,4 @@ oranda-css/.pnp* node_modules # nix -result/ \ No newline at end of file +result/ diff --git a/oranda-css/css/main.css b/oranda-css/css/main.css index 087fc2cf..c4462e62 100644 --- a/oranda-css/css/main.css +++ b/oranda-css/css/main.css @@ -12,3 +12,4 @@ @import "themes/axo.css"; @import "themes/hacker.css"; @import "themes/cupcake.css"; +@import "themes/tui.css"; diff --git a/oranda-css/css/themes/tui.css b/oranda-css/css/themes/tui.css new file mode 100644 index 00000000..22ecfa2f --- /dev/null +++ b/oranda-css/css/themes/tui.css @@ -0,0 +1,154 @@ +@import url('https://unpkg.com/fixedsys-css/css/fixedsys.css'); +@import url('https://fonts.googleapis.com/css2?family=Cutive+Mono&display=swap'); + +html.tui main { + max-width: 82%; +} + +html.tui ::selection { + @apply text-axo-black; + background-color: white; + + -webkit-text-fill-color: var(--color-axo-black); +} + +html.tui body { + @apply bg-axo-black text-zinc-100; + font-family: "fixedsys", monospace; +} + +html.tui strong, +html.tui code, +html.tui ul, +html.tui ul li, +html.tui pre { + @apply text-zinc-300; + font-family: "fixedsys", monospace; +} + +html.tui ul li { + list-style-type: square; +} + +html.tui .button { + @apply rounded-none; + box-shadow: 10px 10px 10px #000; +} + +html.tui blockquote { + @apply bg-zinc-100 p-2 border-double border-axo-black border-8 mb-4; + box-shadow: 0 0 0 8px #f4f4f5; +} + +html.tui blockquote p { + @apply text-axo-black p-0 m-0; +} + +html.tui h2, +html.tui h3, +html.tui h4, +html.tui h5, +html.tui h6 { + @apply text-zinc-100; + text-transform: uppercase; +} + +html.tui .repo_banner > a, +html.tui footer { + @apply text-zinc-100; +} + +html.tui p, +html.tui table { + @apply text-zinc-100; + font-family: 'Cutive Mono', monospace; +} + +html.tui p { + @apply pl-8; +} + +html.tui .title { + @apply text-left text-zinc-100 relative inline-block ml-8; +} + +@keyframes blink-animation { + to { + visibility: hidden; + } +} + +html.tui .title:after { + content: ""; + height: 70px; + animation: blink-animation 1s steps(5, start) infinite; + @apply block absolute left-full ml-3 w-4 top-3 bg-cyan-700; +} + +html.tui .title::before { + content: "> "; + @apply block text-zinc-800 text-5xl absolute top-1/2 -translate-y-1/2 -left-8 mt-2; +} + +html.tui div.table .th, +html.tui h1 { + @apply text-cyan-700; +} + +html.tui a { + @apply text-cyan-700 hover:decoration-cyan-700 p-2; +} + +html.tui a:focus, +html.tui .button.primary:focus { + @apply text-axo-black bg-zinc-100 p-2; +} + +html.tui .detect { + @apply p-2; +} + +html.tui .axo-gradient { + background: none; +} + +html.tui .nav ul { + @apply justify-start; +} + +html.tui .nav ul li { + list-style-type: none; +} + +html.tui li.list-none { + list-style-type: none; +} + +html.tui .button.primary { + @apply text-zinc-100 bg-cyan-700 hover:bg-zinc-100 hover:text-axo-black; +} + +html.tui .artifact-header > h4, +html.tui .artifact-header>div:not(.install-code-wrapper) { + @apply text-left items-start justify-start; +} + +html.tui .releases-nav ul li a { + @apply text-cyan-700; +} + +html.hacker .releases-nav ul li:before { + @apply bg-gray-600; +} + +html.hacker .releases-nav ul { + @apply border-l-gray-600; +} + +html.hacker .prereleases-toggle input:checked { + @apply bg-orange-500; +} + +html.hacker .releases-nav ul li a { + @apply hover:decoration-orange-500; +} diff --git a/src/commands/build.rs b/src/commands/build.rs index 7a578b6a..90b43411 100644 --- a/src/commands/build.rs +++ b/src/commands/build.rs @@ -12,13 +12,20 @@ pub struct Build { project_root: Utf8PathBuf, #[arg(long, default_value = "./oranda.json")] config_path: Utf8PathBuf, + #[arg(long, short)] + cached: bool, } impl Build { - pub fn new(project_root: Option, config_path: Option) -> Self { + pub fn new( + project_root: Option, + config_path: Option, + cached: bool, + ) -> Self { Build { project_root: project_root.unwrap_or(Utf8PathBuf::from("./")), config_path: config_path.unwrap_or(Utf8PathBuf::from("./oranda.json")), + cached, } } @@ -26,7 +33,7 @@ impl Build { Message::new(MessageType::Info, "Running build...").print(); tracing::info!("Running build..."); let config = Config::build(&self.config_path)?; - Site::build(&config)?.write(&config)?; + Site::build(&config, self.cached)?.write(&config)?; let msg = format!( "Successfully built your site in the `{}` directory. To view, run `oranda serve`.", { config.dist_dir } diff --git a/src/commands/dev.rs b/src/commands/dev.rs index 012c15c0..0276edf9 100644 --- a/src/commands/dev.rs +++ b/src/commands/dev.rs @@ -33,6 +33,8 @@ pub struct Dev { /// List of extra paths to watch #[arg(short, long)] include_paths: Option>, + #[arg(short, long)] + cached: bool, } impl Dev { @@ -148,7 +150,12 @@ impl Dev { .print(); if !self.no_first_build { - Build::new(self.project_root.clone(), self.config_path.clone()).run()?; + Build::new( + self.project_root.clone(), + self.config_path.clone(), + self.cached, + ) + .run()?; } // Spawn the serve process out into a separate thread so that we can loop through received events on this thread @@ -187,9 +194,13 @@ impl Dev { ) .print(); - Build::new(self.project_root.clone(), self.config_path.clone()) - .run() - .unwrap(); + Build::new( + self.project_root.clone(), + self.config_path.clone(), + self.cached, + ) + .run() + .unwrap(); } } } diff --git a/src/config/theme.rs b/src/config/theme.rs index 3dbe68c8..0c2fe36a 100644 --- a/src/config/theme.rs +++ b/src/config/theme.rs @@ -12,6 +12,7 @@ pub enum Theme { AxoDark, Hacker, Cupcake, + Tui, } pub fn css_class(theme: &Theme) -> &'static str { @@ -19,6 +20,7 @@ pub fn css_class(theme: &Theme) -> &'static str { Theme::Dark => "dark", Theme::AxoLight => "axo", Theme::AxoDark => "dark axo", + Theme::Tui => "tui", Theme::Hacker => "hacker", Theme::Cupcake => "cupcake", _ => "light", diff --git a/src/data/cargo_dist.rs b/src/data/cargo_dist.rs index ae19be5a..c88b0389 100644 --- a/src/data/cargo_dist.rs +++ b/src/data/cargo_dist.rs @@ -1,6 +1,7 @@ use axoasset::{Asset, LocalAsset}; use camino::Utf8PathBuf; pub use cargo_dist_schema::{Artifact, ArtifactKind, DistManifest, Release}; +use serde::{Deserialize, Serialize}; use crate::config::Config; use crate::data::github::GithubRelease; @@ -8,7 +9,7 @@ use crate::errors::*; pub const MANIFEST_FILENAME: &str = "dist-manifest.json"; -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Deserialize, Serialize)] pub struct DistRelease { pub manifest: DistManifest, pub source: GithubRelease, diff --git a/src/data/github/repo.rs b/src/data/github/repo.rs index 26dd9f14..2fe16a9f 100644 --- a/src/data/github/repo.rs +++ b/src/data/github/repo.rs @@ -1,10 +1,11 @@ use crate::errors::*; use miette::{miette, IntoDiagnostic}; +use serde::{Deserialize, Serialize}; use url::Url; /// Represents a GitHub repository that we can query things about. -#[derive(Debug, Clone)] +#[derive(Debug, Deserialize, Clone, Serialize)] pub struct GithubRepo { /// The repository owner. pub owner: String, diff --git a/src/data/mod.rs b/src/data/mod.rs index 9320c129..0721350d 100644 --- a/src/data/mod.rs +++ b/src/data/mod.rs @@ -1,3 +1,6 @@ +use axoasset::LocalAsset; +use serde::{Deserialize, Serialize}; + use crate::data::github::{GithubRelease, GithubRepo}; use crate::errors::*; use crate::message::{Message, MessageType}; @@ -10,6 +13,7 @@ mod release; pub use release::Release; +#[derive(Deserialize, Serialize)] pub struct Context { pub repo: GithubRepo, pub releases: Vec, @@ -22,12 +26,26 @@ impl Context { let repo = GithubRepo::from_url(repo_url)?; let (releases, has_prereleases, latest_dist_release) = Self::fetch_all_releases(&repo, cargo_dist)?; - Ok(Self { + let context = Self { repo, releases, has_prereleases, latest_dist_release, - }) + }; + context.write_cache()?; + Ok(context) + } + + fn write_cache(&self) -> Result<()> { + let context_cache = serde_json::to_string(self)?; + LocalAsset::write_new_all(&context_cache, "./.oranda-cache/context.json")?; + Ok(()) + } + + pub fn read_cache() -> Result { + let json = LocalAsset::load_string("./.oranda-cache/context.json")?; + let context: Context = serde_json::from_str(&json)?; + Ok(context) } #[allow(clippy::unnecessary_unwrap)] diff --git a/src/data/release.rs b/src/data/release.rs index d9193a96..52154143 100644 --- a/src/data/release.rs +++ b/src/data/release.rs @@ -1,10 +1,11 @@ use axoasset::SourceFile; use cargo_dist_schema::DistManifest; +use serde::{Deserialize, Serialize}; use crate::data::{cargo_dist, github::GithubRelease, GithubRepo}; use crate::errors::*; -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Deserialize, Serialize)] pub struct Release { pub manifest: Option, pub source: GithubRelease, diff --git a/src/errors.rs b/src/errors.rs index 28775293..3dde985d 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -44,6 +44,12 @@ pub enum OrandaError { #[diagnostic(help("Please make sure you give a valid path pointing to a css file."))] InvalidOrandaCSSOverride { path: String }, + #[error("Failed to read cached context.")] + CachedContextReadError { + #[source] + details: Box, + }, + #[error("Failed fetching releases from Github.")] GithubReleasesFetchError { #[source] diff --git a/src/site/mdbook.rs b/src/site/mdbook.rs index b89aee11..7dd93d72 100644 --- a/src/site/mdbook.rs +++ b/src/site/mdbook.rs @@ -81,6 +81,8 @@ pub enum AxomdbookTheme { Hacker, /// Equivalent to oranda's "cupcake" Cupcake, + /// Equivalent to oranda's "tui" + Tui, } impl AxomdbookTheme { @@ -96,6 +98,7 @@ impl AxomdbookTheme { Theme::AxoLight => Some(AxoLight), Theme::Hacker => Some(Hacker), Theme::Cupcake => Some(Cupcake), + Theme::Tui => Some(Tui), } } @@ -109,6 +112,7 @@ impl AxomdbookTheme { AxoLight => false, Hacker => true, Cupcake => false, + Tui => true, } } @@ -123,6 +127,7 @@ impl AxomdbookTheme { AxoLight => Some(AxoDark), Hacker => None, Cupcake => None, + Tui => None, } } @@ -148,6 +153,7 @@ impl AxomdbookTheme { AxoLight => "Axo Light", Hacker => "Hacker", Cupcake => "Cupcake", + Tui => "Tui", } } } diff --git a/src/site/mod.rs b/src/site/mod.rs index 88bd6005..4acb48da 100644 --- a/src/site/mod.rs +++ b/src/site/mod.rs @@ -29,7 +29,7 @@ pub struct Site { } impl Site { - pub fn build(config: &Config) -> Result { + pub fn build(config: &Config, cached: bool) -> Result { Self::clean_dist_dir(&config.dist_dir)?; let mut pages = vec![]; @@ -46,7 +46,17 @@ impl Site { if Self::needs_context(config) { match &config.repository { Some(repo_url) => { - let context = Context::new(repo_url, config.artifacts.cargo_dist())?; + let context = if cached { + match Context::read_cache() { + Ok(cached) => { + Message::new(MessageType::Warning, "Using cached context...").print(); + cached + } + Err(e) => Err(OrandaError::CachedContextReadError{ details: Box::new(e) })? + } + } else { + Context::new(repo_url, config.artifacts.cargo_dist())? + }; if config.artifacts.has_some() { index = Some(Page::index_with_artifacts(&context, &layout_template, config)?); if context.latest_dist_release.is_some()