Remove inputs related codepaths
This commit is contained in:
31
schema.sql
31
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 (
|
CREATE TABLE revisions (
|
||||||
revision_uri TEXT PRIMARY KEY NOT NULL,
|
revision_uri TEXT NOT NULL PRIMARY KEY,
|
||||||
flake_uri TEXT,
|
flake_uri TEXT NOT NULL,
|
||||||
nix_store_path TEXT,
|
store_path TEXT,
|
||||||
nar_hash TEXT,
|
|
||||||
last_modified INT
|
last_modified INT
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE inputs (
|
CREATE TABLE output_attributes (
|
||||||
revision_uri TEXT NOT NULL,
|
revision_uri TEXT NOT NULL,
|
||||||
input_name TEXT NOT NULL,
|
output_attribute_name TEXT NOT NULL,
|
||||||
locked_revision_uri TEXT,
|
derivation_path TEXT,
|
||||||
locked_flake_uri TEXT,
|
PRIMARY KEY (revision_uri, output_attribute_name)
|
||||||
locked_nar_hash TEXT,
|
);
|
||||||
last_modified INT,
|
|
||||||
PRIMARY KEY (revision_uri, input_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)
|
||||||
);
|
);
|
||||||
|
87
src/scan.rs
87
src/scan.rs
@@ -12,7 +12,6 @@ use crate::{
|
|||||||
FlakeUri,
|
FlakeUri,
|
||||||
},
|
},
|
||||||
storage::{
|
storage::{
|
||||||
InputRow,
|
|
||||||
FlakeRow,
|
FlakeRow,
|
||||||
RevisionRow,
|
RevisionRow,
|
||||||
Storage,
|
Storage,
|
||||||
@@ -21,85 +20,16 @@ use crate::{
|
|||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
|
|
||||||
pub async fn scan_flake(storage: Storage, flake_uri: &str) -> Result<()> {
|
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 scan_time = Utc::now().timestamp();
|
||||||
|
|
||||||
let fetch_uri = match revision_uri {
|
let flake_metadata = fetch_metadata(flake_uri)
|
||||||
Some(revision_uri) => revision_uri,
|
|
||||||
None => flake_uri,
|
|
||||||
};
|
|
||||||
|
|
||||||
let flake_metadata = fetch_metadata(fetch_uri)
|
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
let mut revision_row = get_revision_from_metadata(&flake_metadata)?;
|
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)
|
storage.set_revision(revision_row)
|
||||||
.await?;
|
.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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,22 +48,11 @@ pub async fn fetch_metadata(flake_uri: &str) -> Result<FlakeMetadata> {
|
|||||||
Ok(flake_metadata)
|
Ok(flake_metadata)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_flake_from_metadata(flake_metadata: &FlakeMetadata) -> Result<FlakeRow> {
|
|
||||||
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<RevisionRow> {
|
pub fn get_revision_from_metadata(flake_metadata: &FlakeMetadata) -> Result<RevisionRow> {
|
||||||
let revision_row = RevisionRow {
|
let revision_row = RevisionRow {
|
||||||
revision_uri: flake_metadata.locked.flake_uri()?.clone(),
|
revision_uri: flake_metadata.locked.flake_uri()?.clone(),
|
||||||
flake_uri: Some(flake_metadata.resolved.flake_uri()?.clone()),
|
flake_uri: flake_metadata.resolved.flake_uri()?.clone(),
|
||||||
nix_store_path: Some(flake_metadata.path.clone()),
|
store_path: Some(flake_metadata.path.clone()),
|
||||||
nar_hash: Some(flake_metadata.locked.nar_hash.clone()),
|
|
||||||
last_modified: Some(flake_metadata.locked.last_modified.clone()),
|
last_modified: Some(flake_metadata.locked.last_modified.clone()),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
207
src/storage.rs
207
src/storage.rs
@@ -35,40 +35,12 @@ impl Storage {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn set_flake(&self, flake_row: FlakeRow) -> Result<SqliteQueryResult> {
|
|
||||||
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<SqliteQueryResult> {
|
|
||||||
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<Vec<FlakeRow>> {
|
pub async fn flakes(&self) -> Result<Vec<FlakeRow>> {
|
||||||
sqlx::query_as("
|
sqlx::query_as("
|
||||||
SELECT
|
SELECT
|
||||||
flake_uri,
|
flake_uri
|
||||||
tracker_track,
|
FROM revisions
|
||||||
tracker_last_scanned
|
GROUP BY flake_uri
|
||||||
FROM flakes
|
|
||||||
ORDER BY flake_uri
|
|
||||||
")
|
")
|
||||||
.fetch_all(&self.db)
|
.fetch_all(&self.db)
|
||||||
.await
|
.await
|
||||||
@@ -76,148 +48,62 @@ impl Storage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn set_revision(&self, revision_row: RevisionRow) -> Result<SqliteQueryResult> {
|
pub async fn set_revision(&self, revision_row: RevisionRow) -> Result<SqliteQueryResult> {
|
||||||
sqlx::query("INSERT INTO revisions (revision_uri, flake_uri, nix_store_path, nar_hash, last_modified)
|
sqlx::query("INSERT INTO revisions (revision_uri, flake_uri, store_path, last_modified)
|
||||||
VALUES (?, ?, ?, ?, ?)
|
VALUES (?, ?, ?, ?)
|
||||||
ON CONFLICT(revision_uri) DO UPDATE SET
|
ON CONFLICT(revision_uri) DO UPDATE SET
|
||||||
flake_uri=excluded.flake_uri,
|
flake_uri=excluded.flake_uri,
|
||||||
nix_store_path=excluded.nix_store_path,
|
store_path=excluded.store_path,
|
||||||
nar_hash=excluded.nar_hash,
|
|
||||||
last_modified=excluded.last_modified
|
last_modified=excluded.last_modified
|
||||||
")
|
")
|
||||||
.bind(&revision_row.revision_uri)
|
.bind(&revision_row.revision_uri)
|
||||||
.bind(&revision_row.flake_uri)
|
.bind(&revision_row.flake_uri)
|
||||||
.bind(&revision_row.nix_store_path)
|
.bind(&revision_row.store_path)
|
||||||
.bind(&revision_row.nar_hash)
|
|
||||||
.bind(&revision_row.last_modified)
|
.bind(&revision_row.last_modified)
|
||||||
.execute(&self.db)
|
.execute(&self.db)
|
||||||
.await
|
.await
|
||||||
.context("Failed to execute database query")
|
.context("Failed to execute database query")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn set_revision_exist(&self, revision_row: RevisionRow) -> Result<SqliteQueryResult> {
|
pub async fn revisions_from_flake(&self, flake_uri: &str) -> Result<Vec<RevisionRow>> {
|
||||||
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<Vec<RevisionRow>> {
|
|
||||||
sqlx::query_as("
|
sqlx::query_as("
|
||||||
SELECT
|
SELECT
|
||||||
revision_uri,
|
revision_uri,
|
||||||
flake_uri,
|
flake_uri,
|
||||||
nix_store_path,
|
store_path,
|
||||||
nar_hash,
|
|
||||||
last_modified
|
last_modified
|
||||||
FROM revisions
|
FROM revisions
|
||||||
WHERE flake_uri = ?
|
WHERE flake_uri = ?
|
||||||
ORDER BY last_modified DESC
|
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<SqliteQueryResult> {
|
|
||||||
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<Vec<InputRow>> {
|
|
||||||
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<Vec<InputRow>> {
|
|
||||||
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<Vec<InputRow>> {
|
|
||||||
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)
|
.bind(&flake_uri)
|
||||||
.fetch_all(&self.db)
|
.fetch_all(&self.db)
|
||||||
.await
|
.await
|
||||||
.context("Failed to fetch data from database")
|
.context("Failed to fetch data from database")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn revision(&self, revision_uri: &str) -> Result<RevisionRow> {
|
||||||
|
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)]
|
#[derive(FromRow)]
|
||||||
pub struct RevisionRow {
|
pub struct RevisionRow {
|
||||||
pub revision_uri: String,
|
pub revision_uri: String,
|
||||||
pub flake_uri: Option<String>,
|
pub flake_uri: String,
|
||||||
pub nix_store_path: Option<String>,
|
pub store_path: Option<String>,
|
||||||
pub nar_hash: Option<String>,
|
|
||||||
pub last_modified: Option<i64>,
|
pub last_modified: Option<i64>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -227,10 +113,7 @@ impl RevisionRow {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn flake_link(&self) -> String {
|
pub fn flake_link(&self) -> String {
|
||||||
match &self.flake_uri {
|
format!("/flakes/{}", urlencode(&self.flake_uri))
|
||||||
Some(flake_uri) => format!("/flakes/{}", urlencode(&flake_uri)),
|
|
||||||
None => String::from("#"),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn last_modified_time(&self) -> Option<DateTime<Utc>> {
|
pub fn last_modified_time(&self) -> Option<DateTime<Utc>> {
|
||||||
@@ -241,41 +124,9 @@ impl RevisionRow {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(FromRow)]
|
|
||||||
pub struct InputRow {
|
|
||||||
pub revision_uri: String,
|
|
||||||
pub input_name: String,
|
|
||||||
pub locked_revision_uri: Option<String>,
|
|
||||||
pub locked_flake_uri: Option<String>,
|
|
||||||
pub locked_nar_hash: Option<String>,
|
|
||||||
pub last_modified: Option<i64>,
|
|
||||||
}
|
|
||||||
|
|
||||||
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)]
|
#[derive(FromRow)]
|
||||||
pub struct FlakeRow {
|
pub struct FlakeRow {
|
||||||
pub flake_uri: String,
|
pub flake_uri: String,
|
||||||
pub tracker_track: bool,
|
|
||||||
pub tracker_last_scanned: Option<i64>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FlakeRow {
|
impl FlakeRow {
|
||||||
|
@@ -4,7 +4,6 @@ use askama::{
|
|||||||
use crate::{
|
use crate::{
|
||||||
storage::{
|
storage::{
|
||||||
FlakeRow,
|
FlakeRow,
|
||||||
InputRow,
|
|
||||||
RevisionRow,
|
RevisionRow,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@@ -12,26 +11,19 @@ use crate::{
|
|||||||
#[derive(Template)]
|
#[derive(Template)]
|
||||||
#[template(path = "index.html")]
|
#[template(path = "index.html")]
|
||||||
pub struct IndexTemplate {
|
pub struct IndexTemplate {
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Template)]
|
|
||||||
#[template(path = "flake_list.html")]
|
|
||||||
pub struct FlakeListTemplate {
|
|
||||||
pub flakes: Vec<FlakeRow>,
|
pub flakes: Vec<FlakeRow>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Template)]
|
#[derive(Template)]
|
||||||
#[template(path = "flake.html")]
|
#[template(path = "flake.html")]
|
||||||
pub struct FlakeTemplate {
|
pub struct FlakeTemplate {
|
||||||
pub uri: String,
|
pub flake_uri: String,
|
||||||
pub revisions: Vec<RevisionRow>,
|
pub revisions: Vec<RevisionRow>,
|
||||||
pub current_inputs: Vec<InputRow>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Template)]
|
#[derive(Template)]
|
||||||
#[template(path = "revision.html")]
|
#[template(path = "revision.html")]
|
||||||
pub struct RevisionTemplate {
|
pub struct RevisionTemplate {
|
||||||
pub revision_uri: String,
|
pub revision_uri: String,
|
||||||
pub inputs: Vec<InputRow>,
|
pub revision: RevisionRow,
|
||||||
pub input_of: Vec<InputRow>,
|
|
||||||
}
|
}
|
||||||
|
23
src/web.rs
23
src/web.rs
@@ -24,7 +24,6 @@ use crate::{
|
|||||||
Storage,
|
Storage,
|
||||||
},
|
},
|
||||||
templates::{
|
templates::{
|
||||||
FlakeListTemplate,
|
|
||||||
FlakeTemplate,
|
FlakeTemplate,
|
||||||
IndexTemplate,
|
IndexTemplate,
|
||||||
RevisionTemplate,
|
RevisionTemplate,
|
||||||
@@ -85,34 +84,29 @@ pub fn make_router(storage: Storage) -> anyhow::Result<Router> {
|
|||||||
|
|
||||||
let app = Router::new()
|
let app = Router::new()
|
||||||
.route("/", get(route_index))
|
.route("/", get(route_index))
|
||||||
.route("/flakes", get(route_flakes))
|
.route("/flakes/{flake_uri}", get(route_flake))
|
||||||
.route("/flakes/{uri}", get(route_flake))
|
|
||||||
.route("/revisions/{revision_uri}", get(route_revision))
|
.route("/revisions/{revision_uri}", get(route_revision))
|
||||||
|
.route("/derivation/{derivation_path}", get(route_revision))
|
||||||
.with_state(state);
|
.with_state(state);
|
||||||
|
|
||||||
Ok(app)
|
Ok(app)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn route_index() -> Result<impl IntoResponse, AppError> {
|
async fn route_index(
|
||||||
Ok(render_template(&IndexTemplate {})?)
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn route_flakes(
|
|
||||||
State(state): State<AppState>,
|
State(state): State<AppState>,
|
||||||
) -> Result<impl IntoResponse, AppError> {
|
) -> Result<impl IntoResponse, AppError> {
|
||||||
Ok(render_template(&FlakeListTemplate {
|
Ok(render_template(&IndexTemplate {
|
||||||
flakes: state.storage.flakes().await?,
|
flakes: state.storage.flakes().await?,
|
||||||
})?)
|
})?)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn route_flake(
|
async fn route_flake(
|
||||||
State(state): State<AppState>,
|
State(state): State<AppState>,
|
||||||
Path(uri): Path<String>,
|
Path(flake_uri): Path<String>,
|
||||||
) -> Result<impl IntoResponse, AppError> {
|
) -> Result<impl IntoResponse, AppError> {
|
||||||
Ok(render_template(&FlakeTemplate {
|
Ok(render_template(&FlakeTemplate {
|
||||||
uri: uri.clone(),
|
flake_uri: flake_uri.clone(),
|
||||||
revisions: state.storage.revisions_from_flake(&uri).await?,
|
revisions: state.storage.revisions_from_flake(&flake_uri).await?,
|
||||||
current_inputs: state.storage.current_inputs_for_flake(&uri).await?,
|
|
||||||
})?)
|
})?)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,7 +117,6 @@ async fn route_revision(
|
|||||||
|
|
||||||
Ok(render_template(&RevisionTemplate {
|
Ok(render_template(&RevisionTemplate {
|
||||||
revision_uri: revision_uri.clone(),
|
revision_uri: revision_uri.clone(),
|
||||||
inputs: state.storage.inputs_for_revision(&revision_uri).await?,
|
revision: state.storage.revision(&revision_uri).await?,
|
||||||
input_of: state.storage.input_of_for_revision(&revision_uri).await?,
|
|
||||||
})?)
|
})?)
|
||||||
}
|
}
|
||||||
|
@@ -10,7 +10,7 @@
|
|||||||
{% block content %}{% endblock %}
|
{% block content %}{% endblock %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<center><small><a href="/">Home</a> | <a href="/flakes">All flakes</a></small></center>
|
<center><small><a href="/">Home</a></small></center>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
||||||
|
@@ -4,7 +4,7 @@
|
|||||||
<h1>Flake details</h1>
|
<h1>Flake details</h1>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li>Flake: {{ uri }}</li>
|
<li>Flake: {{ flake_uri }}</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<h2>Revisions</h2>
|
<h2>Revisions</h2>
|
||||||
@@ -15,22 +15,5 @@
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<h2>Current Inputs</h2>
|
|
||||||
|
|
||||||
<ul>
|
|
||||||
{% for input in current_inputs %}
|
|
||||||
<li>
|
|
||||||
{{ input.input_name }}
|
|
||||||
<ul>
|
|
||||||
{% match input.locked_flake_uri %}
|
|
||||||
{% when Some with (locked_flake_uri) %}
|
|
||||||
<li>Flake: <a href="{{ input.locked_flake_link() }}">{{ locked_flake_uri }}</a></li>
|
|
||||||
{% when None %}
|
|
||||||
{% endmatch %}
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
{% endfor %}
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
@@ -1,14 +0,0 @@
|
|||||||
{% extends "base.html" %}
|
|
||||||
|
|
||||||
{% block content %}
|
|
||||||
<h1>All flakes</h1>
|
|
||||||
|
|
||||||
<p>Displays all flakes explicitly scanned and automatically discovered by the tracker.</p>
|
|
||||||
|
|
||||||
<ul>
|
|
||||||
{% for flake in flakes %}
|
|
||||||
<li><a href="{{ flake.flake_link() }}">{{ flake.flake_uri }}</a></li>
|
|
||||||
{% endfor %}
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
{% endblock %}
|
|
@@ -4,7 +4,10 @@
|
|||||||
<h1>Flake Tracker</h1>
|
<h1>Flake Tracker</h1>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="/flakes">All flakes</a></li>
|
{% for flake in flakes %}
|
||||||
|
<li><a href="{{ flake.flake_link() }}">{{ flake.flake_uri }}</a></li>
|
||||||
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
@@ -5,37 +5,8 @@
|
|||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li>Revision: {{ revision_uri }}</li>
|
<li>Revision: {{ revision_uri }}</li>
|
||||||
<li>Revision of: <a href="{# flake_revision.flake_link() #}">{# flake_revision.uri #}</a></a>
|
<li>Revision of: <a href="{{ revision.flake_link() }}">{{ revision.flake_uri }}</a></a>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<h2>Inputs</h2>
|
|
||||||
|
|
||||||
<ul>
|
|
||||||
{% for input in inputs %}
|
|
||||||
<li>
|
|
||||||
{{ input.input_name }}
|
|
||||||
<ul>
|
|
||||||
{% match input.locked_flake_uri %}
|
|
||||||
{% when Some with (locked_flake_uri) %}
|
|
||||||
<li>Flake: <a href="{{ input.locked_flake_link() }}">{{ locked_flake_uri }}</a></li>
|
|
||||||
{% when None %}
|
|
||||||
{% endmatch %}
|
|
||||||
{% match input.locked_revision_uri %}
|
|
||||||
{% when Some with (locked_revision_uri) %}
|
|
||||||
<li>Revision: <a href="{{ input.locked_revision_link() }}">{{ locked_revision_uri }}</a></li>
|
|
||||||
{% when None %}
|
|
||||||
{% endmatch %}
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
{% endfor %}
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<h2>Input of</h2>
|
|
||||||
|
|
||||||
<ul>
|
|
||||||
{% for input in input_of %}
|
|
||||||
<li><a href="{{ input.revision_link() }}">{{ input.revision_uri }}</a></li>
|
|
||||||
{% endfor %}
|
|
||||||
</ul>
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user