Compare commits
10 Commits
v0.0.1
...
cb5838345e
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cb5838345e | ||
|
|
1107a653cf | ||
|
|
95d4ee7080 | ||
|
|
fa2dd96f78 | ||
|
|
7741e192f5 | ||
|
|
5dfd46852f | ||
|
|
88e10010d8 | ||
|
|
52c564d4fd | ||
|
|
f7874c1843 | ||
|
|
40120667f7 |
3
.dockerignore
Normal file
3
.dockerignore
Normal file
@@ -0,0 +1,3 @@
|
||||
**/.git
|
||||
target/
|
||||
org_test_documents/
|
||||
151
.lighthouse/pipeline-build-natter.yaml
Normal file
151
.lighthouse/pipeline-build-natter.yaml
Normal file
@@ -0,0 +1,151 @@
|
||||
apiVersion: tekton.dev/v1beta1
|
||||
kind: PipelineRun
|
||||
metadata:
|
||||
name: build-natter
|
||||
spec:
|
||||
pipelineSpec:
|
||||
params:
|
||||
- name: image-name
|
||||
description: The name for the built image
|
||||
type: string
|
||||
- name: path-to-image-context
|
||||
description: The path to the build context
|
||||
type: string
|
||||
- name: path-to-dockerfile
|
||||
description: The path to the Dockerfile
|
||||
type: string
|
||||
tasks:
|
||||
- name: report-pending
|
||||
taskRef:
|
||||
name: gitea-set-status
|
||||
runAfter:
|
||||
- fetch-repository
|
||||
params:
|
||||
- name: CONTEXT
|
||||
value: "$(params.JOB_NAME)"
|
||||
- name: REPO_FULL_NAME
|
||||
value: "$(params.REPO_OWNER)/$(params.REPO_NAME)"
|
||||
- name: GITEA_HOST_URL
|
||||
value: code.fizz.buzz
|
||||
- name: SHA
|
||||
value: "$(tasks.fetch-repository.results.commit)"
|
||||
- name: DESCRIPTION
|
||||
value: "Build $(params.JOB_NAME) has started"
|
||||
- name: STATE
|
||||
value: pending
|
||||
- name: TARGET_URL
|
||||
value: "https://tekton.fizz.buzz/#/namespaces/$(context.pipelineRun.namespace)/pipelineruns/$(context.pipelineRun.name)"
|
||||
- name: fetch-repository
|
||||
taskRef:
|
||||
name: git-clone
|
||||
workspaces:
|
||||
- name: output
|
||||
workspace: git-source
|
||||
params:
|
||||
- name: url
|
||||
value: $(params.REPO_URL)
|
||||
- name: revision
|
||||
value: $(params.PULL_BASE_SHA)
|
||||
- name: deleteExisting
|
||||
value: "true"
|
||||
- name: build-image-runner
|
||||
taskRef:
|
||||
name: kaniko
|
||||
params:
|
||||
- name: IMAGE
|
||||
value: "$(params.image-name):$(tasks.fetch-repository.results.commit)"
|
||||
- name: CONTEXT
|
||||
value: $(params.path-to-image-context)
|
||||
- name: DOCKERFILE
|
||||
value: $(params.path-to-dockerfile)
|
||||
- name: BUILDER_IMAGE
|
||||
value: "gcr.io/kaniko-project/executor:v1.12.1"
|
||||
- name: EXTRA_ARGS
|
||||
value:
|
||||
- "--destination=$(params.image-name)" # Also write the :latest image
|
||||
- --cache=true
|
||||
- --cache-copy-layers
|
||||
- --cache-repo=harbor.fizz.buzz/kanikocache/cache
|
||||
- --use-new-run # Should result in a speed-up
|
||||
- --reproducible # To remove timestamps so layer caching works.
|
||||
- --snapshot-mode=redo
|
||||
- --skip-unused-stages=true
|
||||
- --registry-mirror=dockerhub.dockerhub.svc.cluster.local
|
||||
workspaces:
|
||||
- name: source
|
||||
workspace: git-source
|
||||
- name: dockerconfig
|
||||
workspace: docker-credentials
|
||||
runAfter:
|
||||
- fetch-repository
|
||||
finally:
|
||||
- name: report-success
|
||||
when:
|
||||
- input: "$(tasks.status)"
|
||||
operator: in
|
||||
values: ["Succeeded", "Completed"]
|
||||
taskRef:
|
||||
name: gitea-set-status
|
||||
params:
|
||||
- name: CONTEXT
|
||||
value: "$(params.JOB_NAME)"
|
||||
- name: REPO_FULL_NAME
|
||||
value: "$(params.REPO_OWNER)/$(params.REPO_NAME)"
|
||||
- name: GITEA_HOST_URL
|
||||
value: code.fizz.buzz
|
||||
- name: SHA
|
||||
value: "$(tasks.fetch-repository.results.commit)"
|
||||
- name: DESCRIPTION
|
||||
value: "Build $(params.JOB_NAME) has succeeded"
|
||||
- name: STATE
|
||||
value: success
|
||||
- name: TARGET_URL
|
||||
value: "https://tekton.fizz.buzz/#/namespaces/$(context.pipelineRun.namespace)/pipelineruns/$(context.pipelineRun.name)"
|
||||
- name: report-failure
|
||||
when:
|
||||
- input: "$(tasks.status)"
|
||||
operator: in
|
||||
values: ["Failed"]
|
||||
taskRef:
|
||||
name: gitea-set-status
|
||||
params:
|
||||
- name: CONTEXT
|
||||
value: "$(params.JOB_NAME)"
|
||||
- name: REPO_FULL_NAME
|
||||
value: "$(params.REPO_OWNER)/$(params.REPO_NAME)"
|
||||
- name: GITEA_HOST_URL
|
||||
value: code.fizz.buzz
|
||||
- name: SHA
|
||||
value: "$(tasks.fetch-repository.results.commit)"
|
||||
- name: DESCRIPTION
|
||||
value: "Build $(params.JOB_NAME) has failed"
|
||||
- name: STATE
|
||||
value: failure
|
||||
- name: TARGET_URL
|
||||
value: "https://tekton.fizz.buzz/#/namespaces/$(context.pipelineRun.namespace)/pipelineruns/$(context.pipelineRun.name)"
|
||||
workspaces:
|
||||
- name: git-source
|
||||
- name: docker-credentials
|
||||
workspaces:
|
||||
- name: git-source
|
||||
volumeClaimTemplate:
|
||||
spec:
|
||||
storageClassName: "nfs-client"
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: 10Gi
|
||||
subPath: rust-source
|
||||
- name: docker-credentials
|
||||
secret:
|
||||
secretName: harbor-plain
|
||||
serviceAccountName: build-bot
|
||||
timeout: 240h0m0s
|
||||
params:
|
||||
- name: image-name
|
||||
value: "harbor.fizz.buzz/private/natter"
|
||||
- name: path-to-image-context
|
||||
value: .
|
||||
- name: path-to-dockerfile
|
||||
value: docker/natter/Dockerfile
|
||||
11
.lighthouse/triggers.yaml
Normal file
11
.lighthouse/triggers.yaml
Normal file
@@ -0,0 +1,11 @@
|
||||
apiVersion: config.lighthouse.jenkins-x.io/v1alpha1
|
||||
kind: TriggerConfig
|
||||
spec:
|
||||
postsubmits:
|
||||
- name: build-natter
|
||||
source: "pipeline-build-natter.yaml"
|
||||
# Override https-based url from lighthouse events.
|
||||
clone_uri: "git@code.fizz.buzz:talexander/natter.git"
|
||||
branches:
|
||||
- ^main$
|
||||
- ^master$
|
||||
@@ -32,3 +32,9 @@ serde_json = "1.0.107"
|
||||
tokio = { version = "1.30.0", default-features = false, features = ["rt", "rt-multi-thread", "fs", "io-util"] }
|
||||
toml = "0.8.2"
|
||||
walkdir = "2.4.0"
|
||||
|
||||
# Optimized build for any sort of release.
|
||||
[profile.release-lto]
|
||||
inherits = "release"
|
||||
lto = true
|
||||
strip = "symbols"
|
||||
|
||||
@@ -14,6 +14,10 @@
|
||||
--src-block-language-background: #84828f;
|
||||
|
||||
--quote-block-border-color: #84828f;
|
||||
|
||||
--table-border-color: #6a687a;
|
||||
--table-odd-background-color: #0a0a0a;
|
||||
--table-even-background-color: #141414;
|
||||
}
|
||||
|
||||
body {
|
||||
@@ -184,4 +188,37 @@ body {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.org_table {
|
||||
table-layout: fixed;
|
||||
border-collapse: collapse;
|
||||
border: 1px solid var(--table-border-color);
|
||||
> tbody {
|
||||
border-width: 1px 0;
|
||||
border-style: solid;
|
||||
border-color: var(--table-border-color);
|
||||
> tr {
|
||||
> td {
|
||||
padding: 0.2rem;
|
||||
}
|
||||
}
|
||||
> tr:nth-child(odd) {
|
||||
background-color: var(--table-odd-background-color);
|
||||
}
|
||||
> tr:nth-child(even) {
|
||||
background-color: var(--table-even-background-color);
|
||||
}
|
||||
}
|
||||
> thead {
|
||||
border-width: 1px 0;
|
||||
border-style: solid;
|
||||
border-color: var(--table-border-color);
|
||||
> tr {
|
||||
> th {
|
||||
padding: 0.2rem;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1 +1,5 @@
|
||||
<table>{#.children}{>table_row/}{/.children}</table>
|
||||
<table class="org_table">{#.children}{@select key=.type}
|
||||
{@eq value="head"}{>table_head/}{/eq}
|
||||
{@eq value="body"}{>table_body/}{/eq}
|
||||
{@none}{!TODO: make this panic!}ERROR: Unrecognized type {.type}.{/none}
|
||||
{/select}{/.children}</table>
|
||||
|
||||
1
default_environment/templates/html/table_body.dust
Normal file
1
default_environment/templates/html/table_body.dust
Normal file
@@ -0,0 +1 @@
|
||||
<tbody>{#.children}{>table_row/}{/.children}</tbody>
|
||||
1
default_environment/templates/html/table_head.dust
Normal file
1
default_environment/templates/html/table_head.dust
Normal file
@@ -0,0 +1 @@
|
||||
<thead>{#.children}{>table_head_row/}{/.children}</thead>
|
||||
1
default_environment/templates/html/table_head_cell.dust
Normal file
1
default_environment/templates/html/table_head_cell.dust
Normal file
@@ -0,0 +1 @@
|
||||
<th scope="col">{#.children}{>object/}{/.children}</th>
|
||||
1
default_environment/templates/html/table_head_row.dust
Normal file
1
default_environment/templates/html/table_head_row.dust
Normal file
@@ -0,0 +1 @@
|
||||
<tr>{#.children}{>table_head_cell/}{/.children}</tr>
|
||||
13
docker/natter/Dockerfile
Normal file
13
docker/natter/Dockerfile
Normal file
@@ -0,0 +1,13 @@
|
||||
FROM rustlang/rust:nightly-alpine3.17 AS builder
|
||||
|
||||
RUN apk add --no-cache musl-dev
|
||||
|
||||
RUN mkdir /root/natter
|
||||
WORKDIR /root/natter
|
||||
COPY . .
|
||||
# TODO: Add static build, which currently errors due to proc_macro. RUSTFLAGS="-C target-feature=+crt-static"
|
||||
RUN CARGO_TARGET_DIR=/target cargo build --profile release-lto
|
||||
|
||||
FROM alpine:3.17 AS runner
|
||||
|
||||
COPY --from=builder /target/release-lto/natter /usr/bin/
|
||||
32
docker/natter/Makefile
Normal file
32
docker/natter/Makefile
Normal file
@@ -0,0 +1,32 @@
|
||||
SHELL := bash
|
||||
.ONESHELL:
|
||||
.SHELLFLAGS := -eu -o pipefail -c
|
||||
.DELETE_ON_ERROR:
|
||||
MAKEFLAGS += --warn-undefined-variables
|
||||
MAKEFLAGS += --no-builtin-rules
|
||||
OS:=$(shell uname -s)
|
||||
|
||||
ifeq ($(origin .RECIPEPREFIX), undefined)
|
||||
$(error This Make does not support .RECIPEPREFIX. Please use GNU Make 4.0 or later)
|
||||
endif
|
||||
.RECIPEPREFIX = >
|
||||
|
||||
IMAGE_NAME:=natter
|
||||
TARGET :=
|
||||
|
||||
.PHONY: help
|
||||
help:
|
||||
> @grep -h "##" $(MAKEFILE_LIST) | grep -v grep | sed -E 's/^([^:]*): *## */\1: /'
|
||||
|
||||
.PHONY: build
|
||||
build: ## Build the docker image.
|
||||
> docker build --tag $(IMAGE_NAME) --target=$(TARGET) --file Dockerfile ../../
|
||||
|
||||
.PHONY: shell
|
||||
shell: ## Launch an interactive shell inside the docker image.
|
||||
shell: build
|
||||
> docker run --rm -i -t --entrypoint /bin/sh --mount type=tmpfs,destination=/tmp $(IMAGE_NAME)
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
> docker rmi $(IMAGE_NAME)
|
||||
@@ -59,6 +59,7 @@ mod subscript;
|
||||
mod superscript;
|
||||
mod table;
|
||||
mod table_cell;
|
||||
mod table_group;
|
||||
mod table_row;
|
||||
mod target;
|
||||
mod timestamp;
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
use serde::Serialize;
|
||||
|
||||
use super::render_context::RenderContext;
|
||||
use super::table_group::RenderTableGroup;
|
||||
use crate::error::CustomError;
|
||||
use crate::intermediate::ITable;
|
||||
use crate::intermediate::ITableGroup;
|
||||
|
||||
use super::macros::render;
|
||||
use super::table_row::RenderTableRow;
|
||||
@@ -11,15 +13,29 @@ use super::table_row::RenderTableRow;
|
||||
#[serde(tag = "type")]
|
||||
#[serde(rename = "table")]
|
||||
pub(crate) struct RenderTable {
|
||||
children: Vec<RenderTableRow>,
|
||||
children: Vec<RenderTableGroup>,
|
||||
post_blank: organic::types::PostBlank,
|
||||
}
|
||||
|
||||
render!(RenderTable, ITable, original, render_context, {
|
||||
let children = {
|
||||
let mut ret = Vec::new();
|
||||
for obj in original.children.iter() {
|
||||
ret.push(RenderTableRow::new(render_context.clone(), obj)?);
|
||||
for group in original.children.iter() {
|
||||
let mut rows = Vec::new();
|
||||
match group {
|
||||
ITableGroup::Head(irows) => {
|
||||
for obj in irows {
|
||||
rows.push(RenderTableRow::new(render_context.clone(), obj)?);
|
||||
}
|
||||
ret.push(RenderTableGroup::Head { children: rows });
|
||||
}
|
||||
ITableGroup::Body(irows) => {
|
||||
for obj in irows {
|
||||
rows.push(RenderTableRow::new(render_context.clone(), obj)?);
|
||||
}
|
||||
ret.push(RenderTableGroup::Body { children: rows });
|
||||
}
|
||||
}
|
||||
}
|
||||
ret
|
||||
};
|
||||
|
||||
12
src/context/table_group.rs
Normal file
12
src/context/table_group.rs
Normal file
@@ -0,0 +1,12 @@
|
||||
use super::table_row::RenderTableRow;
|
||||
use serde::Serialize;
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
#[serde(tag = "type")]
|
||||
pub(crate) enum RenderTableGroup {
|
||||
#[serde(rename = "head")]
|
||||
Head { children: Vec<RenderTableRow> },
|
||||
|
||||
#[serde(rename = "body")]
|
||||
Body { children: Vec<RenderTableRow> },
|
||||
}
|
||||
@@ -59,6 +59,7 @@ mod subscript;
|
||||
mod superscript;
|
||||
mod table;
|
||||
mod table_cell;
|
||||
mod table_group;
|
||||
mod table_row;
|
||||
mod target;
|
||||
mod timestamp;
|
||||
@@ -126,6 +127,7 @@ pub(crate) use subscript::ISubscript;
|
||||
pub(crate) use superscript::ISuperscript;
|
||||
pub(crate) use table::ITable;
|
||||
pub(crate) use table_cell::ITableCell;
|
||||
pub(crate) use table_group::ITableGroup;
|
||||
pub(crate) use table_row::ITableRow;
|
||||
pub(crate) use target::ITarget;
|
||||
pub(crate) use timestamp::ITimestamp;
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
use super::macros::intermediate;
|
||||
use super::table_row::ITableRow;
|
||||
use crate::error::CustomError;
|
||||
use crate::intermediate::table_group::ITableGroup;
|
||||
use organic::types::StandardProperties;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub(crate) struct ITable {
|
||||
pub(crate) children: Vec<ITableRow>,
|
||||
pub(crate) children: Vec<ITableGroup>,
|
||||
pub(crate) post_blank: organic::types::PostBlank,
|
||||
}
|
||||
|
||||
@@ -15,10 +16,40 @@ intermediate!(
|
||||
original,
|
||||
intermediate_context,
|
||||
{
|
||||
let children = {
|
||||
// Separate groups by lines, multiple contiguous lines are the same as one.
|
||||
// If there is only one group, it is a tbody.
|
||||
// If there are more than one group, the first is thead and the rest are tbody.
|
||||
|
||||
let sections = group_into_sections(&original.children);
|
||||
|
||||
let children = if sections.len() == 1 {
|
||||
// If there is only one section, then it is a body.
|
||||
let mut ret = Vec::new();
|
||||
for obj in original.children.iter() {
|
||||
ret.push(ITableRow::new(intermediate_context.clone(), obj).await?);
|
||||
for group in sections.into_iter() {
|
||||
let mut rows = Vec::new();
|
||||
for obj in group.into_iter() {
|
||||
rows.push(ITableRow::new(intermediate_context.clone(), obj).await?)
|
||||
}
|
||||
ret.push(ITableGroup::Body(rows));
|
||||
}
|
||||
ret
|
||||
} else {
|
||||
// If there are more than one section, the first is a head and the rest are body.
|
||||
let mut ret = Vec::new();
|
||||
let mut sections = sections.into_iter();
|
||||
if let Some(group) = sections.next() {
|
||||
let mut rows = Vec::new();
|
||||
for obj in group.into_iter() {
|
||||
rows.push(ITableRow::new(intermediate_context.clone(), obj).await?)
|
||||
}
|
||||
ret.push(ITableGroup::Head(rows));
|
||||
}
|
||||
for group in sections {
|
||||
let mut rows = Vec::new();
|
||||
for obj in group.into_iter() {
|
||||
rows.push(ITableRow::new(intermediate_context.clone(), obj).await?)
|
||||
}
|
||||
ret.push(ITableGroup::Body(rows));
|
||||
}
|
||||
ret
|
||||
};
|
||||
@@ -29,3 +60,41 @@ intermediate!(
|
||||
})
|
||||
}
|
||||
);
|
||||
|
||||
enum GroupIntoSectionsState<'orig, 'parse> {
|
||||
NonSection,
|
||||
Section(Vec<&'orig organic::types::TableRow<'parse>>),
|
||||
}
|
||||
|
||||
fn group_into_sections<'orig, 'parse>(
|
||||
rows: &'orig Vec<organic::types::TableRow<'parse>>,
|
||||
) -> Vec<Vec<&'orig organic::types::TableRow<'parse>>> {
|
||||
let mut sections = Vec::new();
|
||||
let mut rows = rows.into_iter();
|
||||
let mut state = GroupIntoSectionsState::NonSection;
|
||||
loop {
|
||||
state = match (state, rows.next()) {
|
||||
(GroupIntoSectionsState::NonSection, None) => break,
|
||||
(GroupIntoSectionsState::NonSection, Some(row)) if row.children.is_empty() => {
|
||||
GroupIntoSectionsState::NonSection
|
||||
}
|
||||
(GroupIntoSectionsState::NonSection, Some(row)) => {
|
||||
GroupIntoSectionsState::Section(vec![row])
|
||||
}
|
||||
(GroupIntoSectionsState::Section(section), None) => {
|
||||
sections.push(section);
|
||||
break;
|
||||
}
|
||||
(GroupIntoSectionsState::Section(section), Some(row)) if row.children.is_empty() => {
|
||||
sections.push(section);
|
||||
GroupIntoSectionsState::NonSection
|
||||
}
|
||||
(GroupIntoSectionsState::Section(mut section), Some(row)) => {
|
||||
section.push(row);
|
||||
GroupIntoSectionsState::Section(section)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sections
|
||||
}
|
||||
|
||||
7
src/intermediate/table_group.rs
Normal file
7
src/intermediate/table_group.rs
Normal file
@@ -0,0 +1,7 @@
|
||||
use super::ITableRow;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub(crate) enum ITableGroup {
|
||||
Head(Vec<ITableRow>),
|
||||
Body(Vec<ITableRow>),
|
||||
}
|
||||
Reference in New Issue
Block a user