Vis prosjektversjonen i et internkontrollfelt på forsiden
test / test (pull_request) Successful in 2m22s
test / test (pull_request) Successful in 2m22s
Rapporten bar enok-versjonen og datoen i bunnteksten på hver side, men ikke hvilken versjon av prosjektet den var laget fra. Det er den opplysningen som knytter rapporten til en bestemt utgivelse av bygningsmodellen, og den hører hjemme ett sted, tydelig plassert. Forsiden har nå et internkontrollfelt med prosjekt, prosjektversjon, oppdragsgiver, energirådgiver, dato og enok-versjon. Bunnteksten gjentar ikke lenger versjon og dato. Versjonen settes med «rapport.versjon» eller «--versjon», slik at byggeserveren kan sende taggen på utgivelsen uten at noen fil endres. Lukker #1 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015GeH3y8fwTaTudaD88P57o
This commit is contained in:
6 files changed
+152
-4
No files matched your search
@@ -103,7 +103,7 @@ Typst må være installert for PDF-rapporten. Uten Typst kjører du med `--ingen
|
|||||||
| `enok klima --kommune Oslo` | Viser nøkkeltall for ett klimasted |
|
| `enok klima --kommune Oslo` | Viser nøkkeltall for ett klimasted |
|
||||||
| `enok skala smaahus --areal 140` | Viser karakterskalaen med arealkorreksjon |
|
| `enok skala smaahus --areal 140` | Viser karakterskalaen med arealkorreksjon |
|
||||||
|
|
||||||
Nyttige valg til `beregn`: `--tillegg FIL`, `--ingen-pdf`, `--ingen-timeserie`, `--enova-xml`,
|
Nyttige valg til `beregn`: `--tillegg FIL`, `--versjon VERSJON`, `--ingen-pdf`, `--ingen-timeserie`, `--enova-xml`,
|
||||||
`--uten-scenarier`, `--ut KATALOG`.
|
`--uten-scenarier`, `--ut KATALOG`.
|
||||||
|
|
||||||
### Utdata
|
### Utdata
|
||||||
@@ -188,6 +188,18 @@ logo = "logo.svg" # vises øverst på forsiden
|
|||||||
farge = "#880000" # aksentfarge i overskrifter og tabeller
|
farge = "#880000" # aksentfarge i overskrifter og tabeller
|
||||||
avsender = "Firma · Adresse · Org.nr. 000 000 000"
|
avsender = "Firma · Adresse · Org.nr. 000 000 000"
|
||||||
skrift_overskrift = "Futura Now Headline"
|
skrift_overskrift = "Futura Now Headline"
|
||||||
|
versjon = "v1.4.0" # prosjektets versjon, se nedenfor
|
||||||
|
```
|
||||||
|
|
||||||
|
Forsiden har et internkontrollfelt med hvilket prosjekt rapporten hører til, hvilken versjon
|
||||||
|
av prosjektet den er laget fra, oppdragsgiver og energirådgiver, datoen og hvilken
|
||||||
|
enok-versjon som regnet den. Opplysningene står der én gang, ikke i bunnteksten på hver side.
|
||||||
|
|
||||||
|
Prosjektversjonen settes i `rapport.versjon`, eller med `--versjon` på `beregn`. Da kan
|
||||||
|
byggeserveren sende taggen på utgivelsen uten at noen fil må endres:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
enok beregn modell.ifc --tillegg prosjekt.toml --versjon "$GITHUB_REF_NAME"
|
||||||
```
|
```
|
||||||
|
|
||||||
Scenarier flettes inn i bygningsbeskrivelsen: tabeller flettes rekursivt, elementer i lister
|
Scenarier flettes inn i bygningsbeskrivelsen: tabeller flettes rekursivt, elementer i lister
|
||||||
@@ -425,7 +437,7 @@ jobs:
|
|||||||
- name: Lag rapporten
|
- name: Lag rapporten
|
||||||
run: |
|
run: |
|
||||||
chmod +x enok
|
chmod +x enok
|
||||||
./enok beregn bygning.toml --ut dist
|
./enok beregn bygning.toml --ut dist --versjon "$GITHUB_REF_NAME"
|
||||||
```
|
```
|
||||||
|
|
||||||
## Kontroll av beregningen
|
## Kontroll av beregningen
|
||||||
|
|||||||
+9
-1
@@ -61,6 +61,10 @@ struct Beregn {
|
|||||||
/// Tilleggsfil som flettes inn: det modellen ikke beskriver, og rettelser.
|
/// Tilleggsfil som flettes inn: det modellen ikke beskriver, og rettelser.
|
||||||
#[arg(short, long, value_name = "FIL")]
|
#[arg(short, long, value_name = "FIL")]
|
||||||
tillegg: Option<PathBuf>,
|
tillegg: Option<PathBuf>,
|
||||||
|
/// Prosjektets versjon, som vises i internkontrollfeltet på forsiden. Overstyrer
|
||||||
|
/// `rapport.versjon`. Byggeserveren sender gjerne taggen på utgivelsen.
|
||||||
|
#[arg(long, value_name = "VERSJON")]
|
||||||
|
versjon: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Args)]
|
#[derive(Args)]
|
||||||
@@ -174,7 +178,11 @@ fn les_modell(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn beregn(a: Beregn, kilde: &Datakilde) -> Result<()> {
|
fn beregn(a: Beregn, kilde: &Datakilde) -> Result<()> {
|
||||||
let (bygning, merknader, modell) = les_modell(&a.fil, a.tillegg.as_deref())?;
|
let (mut bygning, merknader, modell) = les_modell(&a.fil, a.tillegg.as_deref())?;
|
||||||
|
if let Some(v) = &a.versjon {
|
||||||
|
bygning.rapport.versjon = Some(v.clone());
|
||||||
|
}
|
||||||
|
let bygning = bygning;
|
||||||
for m in &merknader {
|
for m in &merknader {
|
||||||
eprintln!(" · {m}");
|
eprintln!(" · {m}");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -102,6 +102,10 @@ pub struct Rapport {
|
|||||||
/// Skrift for overskrifter. Utelatt: enoks egen.
|
/// Skrift for overskrifter. Utelatt: enoks egen.
|
||||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||||
pub skrift_overskrift: Option<String>,
|
pub skrift_overskrift: Option<String>,
|
||||||
|
/// Prosjektets versjon, typisk taggen på utgivelsen rapporten hører til, for eksempel
|
||||||
|
/// «v0.3.12». Vises i internkontrollfeltet på forsiden. Kan settes med `--versjon`.
|
||||||
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||||
|
pub versjon: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize, Clone, Debug)]
|
#[derive(Deserialize, Serialize, Clone, Debug)]
|
||||||
|
|||||||
+30
-1
@@ -165,6 +165,35 @@ fn kilde(r: &Resultat, scenarier: &[(String, Resultat)]) -> String {
|
|||||||
}
|
}
|
||||||
s.push_str(" ]\n)\n\n#v(0.6cm)\n");
|
s.push_str(" ]\n)\n\n#v(0.6cm)\n");
|
||||||
|
|
||||||
|
// Internkontroll: hvilket prosjekt rapporten hører til, hvilken versjon av det, og
|
||||||
|
// hva den er laget med. Står på forsiden i stedet for i bunnteksten på hver side.
|
||||||
|
let mut felter: Vec<(String, String)> = Vec::new();
|
||||||
|
// Adressen står allerede under tittelen på forsiden.
|
||||||
|
felter.push(("Prosjekt".into(), l.navn.clone()));
|
||||||
|
if let Some(v) = &rap.versjon {
|
||||||
|
felter.push(("Prosjektversjon".into(), v.clone()));
|
||||||
|
}
|
||||||
|
if let Some(o) = &b.oppdragsgiver {
|
||||||
|
felter.push(("Oppdragsgiver".into(), o.clone()));
|
||||||
|
}
|
||||||
|
if let Some(ra) = &b.energiraadgiver {
|
||||||
|
felter.push(("Energirådgiver".into(), ra.clone()));
|
||||||
|
}
|
||||||
|
felter.push(("Dato".into(), i_dag()));
|
||||||
|
felter.push((
|
||||||
|
"Beregnet med".into(),
|
||||||
|
format!("enok {}", env!("CARGO_PKG_VERSION")),
|
||||||
|
));
|
||||||
|
s.push_str("#internkontroll((\n");
|
||||||
|
for (navn, verdi) in &felter {
|
||||||
|
s.push_str(&format!(
|
||||||
|
" (\"{}\", \"{}\"),\n",
|
||||||
|
streng(navn),
|
||||||
|
streng(verdi)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
s.push_str("))\n\n#v(0.6cm)\n");
|
||||||
|
|
||||||
// Nøkkeltall.
|
// Nøkkeltall.
|
||||||
let nøkkel = vec![
|
let nøkkel = vec![
|
||||||
("Bygningskategori".to_string(), e(&k.kategorinavn)),
|
("Bygningskategori".to_string(), e(&k.kategorinavn)),
|
||||||
@@ -828,7 +857,7 @@ fn bunntekst(r: &Resultat) -> String {
|
|||||||
if let Some(e) = &b.energiraadgiver {
|
if let Some(e) = &b.energiraadgiver {
|
||||||
deler.push(e.clone());
|
deler.push(e.clone());
|
||||||
}
|
}
|
||||||
deler.push(format!("enok {} · {}", env!("CARGO_PKG_VERSION"), i_dag()));
|
// Versjon og dato står i internkontrollfeltet på forsiden, ikke på hver side.
|
||||||
deler.join(" · ")
|
deler.join(" · ")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,69 @@
|
|||||||
|
//! Kontroll av opplysningene rapporten skal bære: hvilket prosjekt, hvilken versjon og når.
|
||||||
|
|
||||||
|
use enok::data::Datakilde;
|
||||||
|
use enok::{inndata, kjor, rapport};
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
|
fn rapportkilde(versjon: Option<&str>, katalog: &str) -> String {
|
||||||
|
let mut b = inndata::les_bygning(Path::new("eksempler/referansebygg/smaahus.toml")).unwrap();
|
||||||
|
b.rapport.versjon = versjon.map(str::to_string);
|
||||||
|
let r = kjor::kjor(&b, &Datakilde::default()).unwrap();
|
||||||
|
let ut: PathBuf = std::env::temp_dir().join(katalog);
|
||||||
|
rapport::typst_ut::skriv(&r, &ut, &[]).unwrap();
|
||||||
|
std::fs::read_to_string(ut.join("rapport.typ")).unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn oppsettlinjen(kilde: &str) -> String {
|
||||||
|
kilde
|
||||||
|
.lines()
|
||||||
|
.find(|l| l.starts_with("#show: oppsett.with("))
|
||||||
|
.unwrap_or_default()
|
||||||
|
.to_string()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Prosjektversjonen hører hjemme i internkontrollfeltet på forsiden.
|
||||||
|
#[test]
|
||||||
|
fn prosjektversjonen_staar_i_internkontrollfeltet() {
|
||||||
|
let kilde = rapportkilde(Some("v0.3.12"), "enok-rapport-med-versjon");
|
||||||
|
assert!(
|
||||||
|
kilde.contains("#internkontroll(("),
|
||||||
|
"mangler internkontrollfeltet"
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
kilde.contains("(\"Prosjektversjon\", \"v0.3.12\")"),
|
||||||
|
"mangler prosjektversjonen"
|
||||||
|
);
|
||||||
|
assert!(kilde.contains("(\"Prosjekt\","), "mangler prosjektnavnet");
|
||||||
|
assert!(kilde.contains("(\"Dato\","), "mangler datoen");
|
||||||
|
assert!(
|
||||||
|
kilde.contains("(\"Beregnet med\", \"enok "),
|
||||||
|
"mangler enok-versjonen"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Uten oppgitt versjon står feltet der, men uten en tom versjonslinje.
|
||||||
|
#[test]
|
||||||
|
fn uten_versjon_staar_ingen_versjonslinje() {
|
||||||
|
let kilde = rapportkilde(None, "enok-rapport-uten-versjon");
|
||||||
|
assert!(kilde.contains("#internkontroll(("));
|
||||||
|
assert!(
|
||||||
|
!kilde.contains("Prosjektversjon"),
|
||||||
|
"skal ikke stå tom versjon"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Versjon og dato skal stå ett sted, på forsiden, ikke på hver eneste side.
|
||||||
|
#[test]
|
||||||
|
fn bunnteksten_gjentar_ikke_versjon_og_dato() {
|
||||||
|
let kilde = rapportkilde(Some("v0.3.12"), "enok-rapport-bunntekst");
|
||||||
|
let linje = oppsettlinjen(&kilde);
|
||||||
|
assert!(!linje.is_empty(), "fant ikke oppsettlinjen");
|
||||||
|
assert!(
|
||||||
|
!linje.contains("enok "),
|
||||||
|
"bunnteksten gjentar enok-versjonen: {linje}"
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
!linje.contains("v0.3.12"),
|
||||||
|
"bunnteksten gjentar prosjektversjonen"
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -107,6 +107,32 @@
|
|||||||
)[#tekst]
|
)[#tekst]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Internkontrollfelt på forsiden: hvilket prosjekt, hvilken versjon og når.
|
||||||
|
#let internkontroll(rader) = context {
|
||||||
|
block(
|
||||||
|
width: 100%,
|
||||||
|
inset: 9pt,
|
||||||
|
radius: 4pt,
|
||||||
|
fill: lys,
|
||||||
|
stroke: 0.4pt + kantlinje,
|
||||||
|
stack(
|
||||||
|
spacing: 6pt,
|
||||||
|
text(
|
||||||
|
font: overskriftsskrift(),
|
||||||
|
size: 7.5pt,
|
||||||
|
fill: aksent-valgt.get(),
|
||||||
|
tracking: 0.8pt,
|
||||||
|
)[INTERNKONTROLL],
|
||||||
|
..rader.map(rad => grid(
|
||||||
|
columns: (3.8cm, 1fr),
|
||||||
|
gutter: 6pt,
|
||||||
|
text(size: 8.5pt, fill: mid)[#rad.at(0)],
|
||||||
|
text(size: 8.5pt)[#rad.at(1)],
|
||||||
|
)),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
// Stor karakterrute på forsiden.
|
// Stor karakterrute på forsiden.
|
||||||
#let karakterrute(bokstav, verdi, farge) = {
|
#let karakterrute(bokstav, verdi, farge) = {
|
||||||
box(
|
box(
|
||||||
|
|||||||
Reference in new issue
Block a user