From 5171770f1a7cb9b76bd037c83cfc4bf8875fef75 Mon Sep 17 00:00:00 2001 From: clerie Date: Sun, 24 Aug 2025 13:38:23 +0200 Subject: [PATCH] Remove inputs related codepaths --- schema.sql | 31 +++--- src/scan.rs | 87 +--------------- src/storage.rs | 207 ++++++-------------------------------- src/templates.rs | 12 +-- src/web.rs | 23 ++--- templates/base.html | 2 +- templates/flake.html | 19 +--- templates/flake_list.html | 14 --- templates/index.html | 5 +- templates/revision.html | 31 +----- 10 files changed, 63 insertions(+), 368 deletions(-) delete mode 100644 templates/flake_list.html diff --git a/schema.sql b/schema.sql index 9f24fd0..b7dcf8f 100644 --- a/schema.sql +++ b/schema.sql @@ -1,23 +1,20 @@ -CREATE TABLE flakes ( - flake_uri TEXT PRIMARY KEY NOT NULL, - tracker_track BOOLEAN NOT NULL, - tracker_last_scanned INT -); - CREATE TABLE revisions ( - revision_uri TEXT PRIMARY KEY NOT NULL, - flake_uri TEXT, - nix_store_path TEXT, - nar_hash TEXT, + revision_uri TEXT NOT NULL PRIMARY KEY, + flake_uri TEXT NOT NULL, + store_path TEXT, last_modified INT ); -CREATE TABLE inputs ( +CREATE TABLE output_attributes ( revision_uri TEXT NOT NULL, - input_name TEXT NOT NULL, - locked_revision_uri TEXT, - locked_flake_uri TEXT, - locked_nar_hash TEXT, - last_modified INT, - PRIMARY KEY (revision_uri, input_name) + output_attribute_name TEXT NOT NULL, + derivation_path TEXT, + PRIMARY KEY (revision_uri, output_attribute_name) +); + +CREATE TABLE build_outputs ( + derivation_path TEXT NOT NULL, + build_output_name TEXT NOT NULL, + store_path TEXT, + PRIMARY KEY (derivation_path, build_output_name) ); diff --git a/src/scan.rs b/src/scan.rs index 609ae99..252087b 100644 --- a/src/scan.rs +++ b/src/scan.rs @@ -12,7 +12,6 @@ use crate::{ FlakeUri, }, storage::{ - InputRow, FlakeRow, RevisionRow, Storage, @@ -21,85 +20,16 @@ use crate::{ use std::process::Command; pub async fn scan_flake(storage: Storage, flake_uri: &str) -> Result<()> { - scan_revision(storage, flake_uri, None) - .await?; - - Ok(()) -} - -pub async fn scan_revision(storage: Storage, flake_uri: &str, revision_uri: Option<&str>) -> Result<()> { let scan_time = Utc::now().timestamp(); - let fetch_uri = match revision_uri { - Some(revision_uri) => revision_uri, - None => flake_uri, - }; - - let flake_metadata = fetch_metadata(fetch_uri) + let flake_metadata = fetch_metadata(flake_uri) .await?; let mut revision_row = get_revision_from_metadata(&flake_metadata)?; - if let Some(_) = revision_uri { - revision_row.flake_uri = Some(flake_uri.to_string()); - } storage.set_revision(revision_row) .await?; - let mut flake_row = get_flake_from_metadata(&flake_metadata)?; - if let Some(_) = revision_uri { - flake_row.flake_uri = flake_uri.to_string(); - } - else { - flake_row.tracker_last_scanned = Some(scan_time.clone()); - } - - storage.set_flake(flake_row) - .await?; - - let locks_root_name = &flake_metadata.locks.root; - let locks_root_node = flake_metadata.locks.nodes.get(locks_root_name) - .context("Failed to get locks root node")?; - - for (input_name, locks_input_name) in locks_root_node.inputs.clone().context("No inputs found for flake")? { - - if let FlakeLocksNodeInputs::String(locks_input_name) = locks_input_name { - let locks_input_node = flake_metadata.locks.nodes.get(&locks_input_name) - .context("Failed to find lock of input")?; - - let input_row = InputRow { - revision_uri: flake_metadata.locked.flake_uri()?.clone(), - input_name: input_name.clone(), - locked_revision_uri: Some(locks_input_node.locked.clone().context("Unexpected missing lock")?.flake_uri()?), - locked_flake_uri: Some(locks_input_node.original.clone().context("Unexpected missing lock")?.flake_uri()?), - locked_nar_hash: Some(locks_input_node.locked.clone().context("Unexpected missing lock")?.nar_hash), - last_modified: Some(locks_input_node.locked.clone().context("Unexpected missing lock")?.last_modified), - }; - storage.set_input(input_row) - .await?; - - let revision_row = RevisionRow { - revision_uri: locks_input_node.locked.clone().context("Unexpected missing lock")?.flake_uri()?.clone(), - flake_uri: Some(locks_input_node.original.clone().context("Unexpected missing lock")?.flake_uri()?.clone()), - nix_store_path: None, - nar_hash: None, - last_modified: None, - }; - storage.set_revision_exist(revision_row) - .await?; - - let flake_row = FlakeRow { - flake_uri: locks_input_node.original.clone().context("Unexpected missing lock")?.flake_uri()?.clone(), - tracker_track: false, - tracker_last_scanned: None, - }; - - storage.set_flake_exist(flake_row) - .await?; - - } - } - Ok(()) } @@ -118,22 +48,11 @@ pub async fn fetch_metadata(flake_uri: &str) -> Result { Ok(flake_metadata) } -pub fn get_flake_from_metadata(flake_metadata: &FlakeMetadata) -> Result { - let flake_row = FlakeRow { - flake_uri: flake_metadata.resolved.flake_uri()?.clone(), - tracker_track: false, - tracker_last_scanned: None, - }; - - Ok(flake_row) -} - pub fn get_revision_from_metadata(flake_metadata: &FlakeMetadata) -> Result { let revision_row = RevisionRow { revision_uri: flake_metadata.locked.flake_uri()?.clone(), - flake_uri: Some(flake_metadata.resolved.flake_uri()?.clone()), - nix_store_path: Some(flake_metadata.path.clone()), - nar_hash: Some(flake_metadata.locked.nar_hash.clone()), + flake_uri: flake_metadata.resolved.flake_uri()?.clone(), + store_path: Some(flake_metadata.path.clone()), last_modified: Some(flake_metadata.locked.last_modified.clone()), }; diff --git a/src/storage.rs b/src/storage.rs index 6775cd4..0201e1f 100644 --- a/src/storage.rs +++ b/src/storage.rs @@ -35,40 +35,12 @@ impl Storage { }) } - pub async fn set_flake(&self, flake_row: FlakeRow) -> Result { - sqlx::query("INSERT INTO flakes (flake_uri, tracker_track, tracker_last_scanned) - VALUES (?, ?, ?) - ON CONFLICT(flake_uri) DO UPDATE SET - tracker_track=excluded.tracker_track, - tracker_last_scanned=excluded.tracker_last_scanned - ") - .bind(&flake_row.flake_uri) - .bind(&flake_row.tracker_track) - .bind(&flake_row.tracker_last_scanned) - .execute(&self.db) - .await - .context("Failed to execute database query") - } - - pub async fn set_flake_exist(&self, flake_row: FlakeRow) -> Result { - sqlx::query("INSERT INTO flakes (flake_uri, tracker_track) - VALUES (?, FALSE) - ON CONFLICT(flake_uri) DO NOTHING - ") - .bind(&flake_row.flake_uri) - .execute(&self.db) - .await - .context("Failed to execute database query") - } - pub async fn flakes(&self) -> Result> { sqlx::query_as(" SELECT - flake_uri, - tracker_track, - tracker_last_scanned - FROM flakes - ORDER BY flake_uri + flake_uri + FROM revisions + GROUP BY flake_uri ") .fetch_all(&self.db) .await @@ -76,148 +48,62 @@ impl Storage { } pub async fn set_revision(&self, revision_row: RevisionRow) -> Result { - sqlx::query("INSERT INTO revisions (revision_uri, flake_uri, nix_store_path, nar_hash, last_modified) - VALUES (?, ?, ?, ?, ?) + sqlx::query("INSERT INTO revisions (revision_uri, flake_uri, store_path, last_modified) + VALUES (?, ?, ?, ?) ON CONFLICT(revision_uri) DO UPDATE SET flake_uri=excluded.flake_uri, - nix_store_path=excluded.nix_store_path, - nar_hash=excluded.nar_hash, + store_path=excluded.store_path, last_modified=excluded.last_modified ") .bind(&revision_row.revision_uri) .bind(&revision_row.flake_uri) - .bind(&revision_row.nix_store_path) - .bind(&revision_row.nar_hash) + .bind(&revision_row.store_path) .bind(&revision_row.last_modified) .execute(&self.db) .await .context("Failed to execute database query") } - pub async fn set_revision_exist(&self, revision_row: RevisionRow) -> Result { - sqlx::query("INSERT INTO revisions (revision_uri, flake_uri) - VALUES (?, ?) - ON CONFLICT(revision_uri) DO NOTHING - ") - .bind(&revision_row.revision_uri) - .bind(&revision_row.flake_uri) - .execute(&self.db) - .await - .context("Failed to execute database query") - } - - pub async fn revisions_from_flake(&self, uri: &str) -> Result> { + pub async fn revisions_from_flake(&self, flake_uri: &str) -> Result> { sqlx::query_as(" SELECT revision_uri, flake_uri, - nix_store_path, - nar_hash, + store_path, last_modified FROM revisions WHERE flake_uri = ? ORDER BY last_modified DESC ") - .bind(&uri) - .fetch_all(&self.db) - .await - .context("Failed to fetch data from database") - } - - pub async fn set_input(&self, input_row: InputRow) -> Result { - sqlx::query("INSERT INTO inputs (revision_uri, input_name, locked_revision_uri, locked_flake_uri, locked_nar_hash, last_modified) - VALUES (?, ?, ?, ?, ?, ?) - ON CONFLICT(revision_uri, input_name) DO UPDATE SET - locked_revision_uri=excluded.locked_revision_uri, - locked_flake_uri=excluded.locked_flake_uri, - locked_nar_hash=excluded.locked_nar_hash, - last_modified=excluded.last_modified - ") - .bind(input_row.revision_uri) - .bind(input_row.input_name) - .bind(input_row.locked_revision_uri) - .bind(input_row.locked_flake_uri) - .bind(input_row.locked_nar_hash) - .bind(input_row.last_modified) - .execute(&self.db) - .await - .context("Failed to execute database query") - - } - - pub async fn inputs_for_revision(&self, revision_uri: &str) -> Result> { - sqlx::query_as(" - SELECT - revision_uri, - input_name, - locked_revision_uri, - locked_flake_uri, - locked_nar_hash, - last_modified - FROM inputs - WHERE revision_uri = ? - ORDER BY input_name - ") - .bind(&revision_uri) - .fetch_all(&self.db) - .await - .context("Failed to fetch data from database") - } - - pub async fn input_of_for_revision(&self, revision_uri: &str) -> Result> { - sqlx::query_as(" - SELECT - revision_uri, - input_name, - locked_revision_uri, - locked_flake_uri, - locked_nar_hash, - last_modified - FROM inputs - WHERE locked_revision_uri = ? - ORDER BY input_name - ") - .bind(&revision_uri) - .fetch_all(&self.db) - .await - .context("Failed to fetch data from database") - } - - pub async fn current_inputs_for_flake(&self, flake_uri: &str) -> Result> { - sqlx::query_as(" - - SELECT - revisions.revision_uri, - inputs.input_name, - inputs.locked_revision_uri, - inputs.locked_flake_uri, - inputs.locked_nar_hash, - inputs.last_modified, - MAX(revisions.last_modified) - FROM - revisions - LEFT JOIN - inputs - ON - revisions.revision_uri = inputs.revision_uri - WHERE - revisions.flake_uri = ? - GROUP BY - inputs.input_name - ") .bind(&flake_uri) .fetch_all(&self.db) .await .context("Failed to fetch data from database") } + + pub async fn revision(&self, revision_uri: &str) -> Result { + sqlx::query_as(" + SELECT + revision_uri, + flake_uri, + store_path, + last_modified + FROM revisions + WHERE revision_uri = ? + LIMIT 1 + ") + .bind(&revision_uri) + .fetch_one(&self.db) + .await + .context("Failed to fetch data from database") + } } #[derive(FromRow)] pub struct RevisionRow { pub revision_uri: String, - pub flake_uri: Option, - pub nix_store_path: Option, - pub nar_hash: Option, + pub flake_uri: String, + pub store_path: Option, pub last_modified: Option, } @@ -227,10 +113,7 @@ impl RevisionRow { } pub fn flake_link(&self) -> String { - match &self.flake_uri { - Some(flake_uri) => format!("/flakes/{}", urlencode(&flake_uri)), - None => String::from("#"), - } + format!("/flakes/{}", urlencode(&self.flake_uri)) } pub fn last_modified_time(&self) -> Option> { @@ -241,41 +124,9 @@ impl RevisionRow { } } -#[derive(FromRow)] -pub struct InputRow { - pub revision_uri: String, - pub input_name: String, - pub locked_revision_uri: Option, - pub locked_flake_uri: Option, - pub locked_nar_hash: Option, - pub last_modified: Option, -} - -impl InputRow { - pub fn revision_link(&self) -> String { - format!("/revisions/{}", urlencode(&self.revision_uri)) - } - - pub fn locked_revision_link(&self) -> String { - match &self.locked_revision_uri { - Some(locked_revision_uri) => format!("/revisions/{}", urlencode(&locked_revision_uri)), - None => String::from("#"), - } - } - - pub fn locked_flake_link(&self) -> String { - match &self.locked_flake_uri { - Some(locked_flake_uri) => format!("/flakes/{}", urlencode(&locked_flake_uri)), - None => String::from("#"), - } - } -} - #[derive(FromRow)] pub struct FlakeRow { pub flake_uri: String, - pub tracker_track: bool, - pub tracker_last_scanned: Option, } impl FlakeRow { diff --git a/src/templates.rs b/src/templates.rs index ebd5019..6982a48 100644 --- a/src/templates.rs +++ b/src/templates.rs @@ -4,7 +4,6 @@ use askama::{ use crate::{ storage::{ FlakeRow, - InputRow, RevisionRow, }, }; @@ -12,26 +11,19 @@ use crate::{ #[derive(Template)] #[template(path = "index.html")] pub struct IndexTemplate { -} - -#[derive(Template)] -#[template(path = "flake_list.html")] -pub struct FlakeListTemplate { pub flakes: Vec, } #[derive(Template)] #[template(path = "flake.html")] pub struct FlakeTemplate { - pub uri: String, + pub flake_uri: String, pub revisions: Vec, - pub current_inputs: Vec, } #[derive(Template)] #[template(path = "revision.html")] pub struct RevisionTemplate { pub revision_uri: String, - pub inputs: Vec, - pub input_of: Vec, + pub revision: RevisionRow, } diff --git a/src/web.rs b/src/web.rs index 559c59e..eadf87e 100644 --- a/src/web.rs +++ b/src/web.rs @@ -24,7 +24,6 @@ use crate::{ Storage, }, templates::{ - FlakeListTemplate, FlakeTemplate, IndexTemplate, RevisionTemplate, @@ -85,34 +84,29 @@ pub fn make_router(storage: Storage) -> anyhow::Result { let app = Router::new() .route("/", get(route_index)) - .route("/flakes", get(route_flakes)) - .route("/flakes/{uri}", get(route_flake)) + .route("/flakes/{flake_uri}", get(route_flake)) .route("/revisions/{revision_uri}", get(route_revision)) + .route("/derivation/{derivation_path}", get(route_revision)) .with_state(state); Ok(app) } -async fn route_index() -> Result { - Ok(render_template(&IndexTemplate {})?) -} - -async fn route_flakes( +async fn route_index( State(state): State, ) -> Result { - Ok(render_template(&FlakeListTemplate { + Ok(render_template(&IndexTemplate { flakes: state.storage.flakes().await?, })?) } async fn route_flake( State(state): State, - Path(uri): Path, + Path(flake_uri): Path, ) -> Result { Ok(render_template(&FlakeTemplate { - uri: uri.clone(), - revisions: state.storage.revisions_from_flake(&uri).await?, - current_inputs: state.storage.current_inputs_for_flake(&uri).await?, + flake_uri: flake_uri.clone(), + revisions: state.storage.revisions_from_flake(&flake_uri).await?, })?) } @@ -123,7 +117,6 @@ async fn route_revision( Ok(render_template(&RevisionTemplate { revision_uri: revision_uri.clone(), - inputs: state.storage.inputs_for_revision(&revision_uri).await?, - input_of: state.storage.input_of_for_revision(&revision_uri).await?, + revision: state.storage.revision(&revision_uri).await?, })?) } diff --git a/templates/base.html b/templates/base.html index 235a60f..3efe6a9 100644 --- a/templates/base.html +++ b/templates/base.html @@ -10,7 +10,7 @@ {% block content %}{% endblock %} -
Home | All flakes
+
Home
diff --git a/templates/flake.html b/templates/flake.html index 9189c91..99e65c8 100644 --- a/templates/flake.html +++ b/templates/flake.html @@ -4,7 +4,7 @@

Flake details

    -
  • Flake: {{ uri }}
  • +
  • Flake: {{ flake_uri }}

Revisions

@@ -15,22 +15,5 @@ {% endfor %} -

Current Inputs

- -
    -{% for input in current_inputs %} -
  • - {{ input.input_name }} -
      - {% match input.locked_flake_uri %} - {% when Some with (locked_flake_uri) %} -
    • Flake: {{ locked_flake_uri }}
    • - {% when None %} - {% endmatch %} -
    -
  • -{% endfor %} -
- {% endblock %} diff --git a/templates/flake_list.html b/templates/flake_list.html deleted file mode 100644 index c0f20d4..0000000 --- a/templates/flake_list.html +++ /dev/null @@ -1,14 +0,0 @@ -{% extends "base.html" %} - -{% block content %} -

All flakes

- -

Displays all flakes explicitly scanned and automatically discovered by the tracker.

- - - -{% endblock %} diff --git a/templates/index.html b/templates/index.html index c86a5bb..fdcc7f6 100644 --- a/templates/index.html +++ b/templates/index.html @@ -4,7 +4,10 @@

Flake Tracker

+ {% endblock %} diff --git a/templates/revision.html b/templates/revision.html index 358a3ea..f346760 100644 --- a/templates/revision.html +++ b/templates/revision.html @@ -5,37 +5,8 @@ -

Inputs

- -
    -{% for input in inputs %} -
  • - {{ input.input_name }} -
      - {% match input.locked_flake_uri %} - {% when Some with (locked_flake_uri) %} -
    • Flake: {{ locked_flake_uri }}
    • - {% when None %} - {% endmatch %} - {% match input.locked_revision_uri %} - {% when Some with (locked_revision_uri) %} -
    • Revision: {{ locked_revision_uri }}
    • - {% when None %} - {% endmatch %} -
    -
  • -{% endfor %} -
- -

Input of

- - {% endblock %}