Compare commits
214 Commits
175ff1e6c4
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
482d5ecfa3 | ||
|
|
84b8ddb582 | ||
|
|
113bb5888a | ||
|
|
bf5fe6920b | ||
|
|
4b52ed0d2a | ||
|
|
d2c558ccfa | ||
|
|
a01f78b510 | ||
|
|
d80b473fae | ||
|
|
e6b4bc3d94 | ||
|
|
c6cde8db74 | ||
|
|
841a348dd0 | ||
|
|
b46fae331b | ||
|
|
7223e08df3 | ||
|
|
8321f83dac | ||
|
|
bd441a0293 | ||
|
|
f5a07e0d70 | ||
|
|
9d750ed5e1 | ||
|
|
9f111fe445 | ||
|
|
a4e433dab1 | ||
|
|
4e9f1e4fac | ||
|
|
4dee130873 | ||
|
|
8e712532e1 | ||
|
|
4b85236c5f | ||
|
|
66f003e6fd | ||
|
|
b35a2d5f5a | ||
|
|
320b5f8568 | ||
|
|
99b2af6c99 | ||
|
|
6e71acdb7d | ||
|
|
8406d37991 | ||
|
|
64bb597908 | ||
|
|
068864ea87 | ||
|
|
03a3ddbd63 | ||
|
|
122adee23b | ||
|
|
556afecbb8 | ||
|
|
e4407cbdd1 | ||
|
|
f57d60dab0 | ||
|
|
0aa3939a75 | ||
|
|
52cb81e75e | ||
|
|
945121202d | ||
|
|
f4e0dddd9d | ||
|
|
6b62176fd0 | ||
|
|
44483b4d54 | ||
|
|
48d3de77fe | ||
|
|
680b176501 | ||
|
|
dc0338e978 | ||
|
|
ff3e0a50af | ||
|
|
03c8c07fe0 | ||
|
|
3a6fc5b669 | ||
|
|
d258cdb839 | ||
|
|
aa5629354e | ||
|
|
efc4a04829 | ||
|
|
dd611ea64a | ||
|
|
4bd5f3bec7 | ||
|
|
c2b3509b6a | ||
|
|
7f3f5fb889 | ||
|
|
e0fbf17226 | ||
|
|
4e18cbafba | ||
|
|
46c36d7f3e | ||
|
|
c46a935cfc | ||
|
|
f50415cb32 | ||
|
|
4f1a151e97 | ||
|
|
c8e3fdba51 | ||
|
|
4b3fc20c62 | ||
|
|
3131f8ac64 | ||
|
|
60a4835590 | ||
|
|
172d72aa46 | ||
|
|
b4fcc6500b | ||
|
|
ddb6f31562 | ||
|
|
dc080b30fc | ||
|
|
9901e17437 | ||
|
|
ea000894f0 | ||
|
|
e7742b529a | ||
|
|
8eba0c4923 | ||
|
|
e0c0070a13 | ||
|
|
65ce116998 | ||
|
|
e348e7d4e3 | ||
|
|
492090470c | ||
|
|
3ec900c8df | ||
|
|
d0a008ed22 | ||
|
|
f2292f1c07 | ||
|
|
44392cfcca | ||
|
|
110630d230 | ||
|
|
ebe12d96c1 | ||
|
|
24c8ac8e21 | ||
|
|
259ad6e242 | ||
|
|
dd1f7c7777 | ||
|
|
c1b471208d | ||
|
|
606bab9e6d | ||
|
|
0edf5620a2 | ||
|
|
cdf87641c5 | ||
|
|
eb2995dd3b | ||
|
|
cd6a64c015 | ||
|
|
a4a83d047d | ||
|
|
a4414369ce | ||
|
|
83e4b72307 | ||
|
|
34b3e4fa7b | ||
|
|
c0e879dc1e | ||
|
|
fa31b001f4 | ||
|
|
0897061ff6 | ||
|
|
28a3e1bc7b | ||
|
|
3fd3d20722 | ||
|
|
90735586b5 | ||
|
|
78befc7665 | ||
|
|
ef549d3b19 | ||
|
|
777c756a7f | ||
|
|
037caf369c | ||
|
|
54085b5833 | ||
|
|
2bfa8e59e7 | ||
|
|
5d31db39a4 | ||
|
|
adcd0de7e4 | ||
|
|
c2f9789a64 | ||
|
|
579cbb5d11 | ||
|
|
cad2be43bf | ||
|
|
a0a4f0eb90 | ||
|
|
9f4f8e79ce | ||
|
|
77e0dbb42e | ||
|
|
eff5cdbf40 | ||
|
|
eef3571299 | ||
|
|
f227d8405e | ||
|
|
9520e5814b | ||
|
|
28ad4fd046 | ||
|
|
7626a69fa1 | ||
|
|
121c0ce516 | ||
|
|
5a64db98fe | ||
|
|
abfae9c6c0 | ||
|
|
5272e2f1b4 | ||
|
|
90d4b11922 | ||
|
|
d552ef6569 | ||
|
|
f050e9b6a8 | ||
|
|
a5e108bc37 | ||
|
|
58290515b5 | ||
|
|
423f65046e | ||
|
|
badeaf8246 | ||
|
|
d38100581c | ||
|
|
f4eff5ca56 | ||
|
|
5b02c21ebf | ||
|
|
5f1668702a | ||
|
|
1faaeeebf1 | ||
|
|
20a7c89084 | ||
|
|
e83417b243 | ||
|
|
36b80dc093 | ||
|
|
1812b1a56e | ||
|
|
1a70b3d2c0 | ||
|
|
abf066701e | ||
|
|
4984ea4179 | ||
|
|
3cb251ea6c | ||
|
|
4bfea41291 | ||
|
|
99376515ef | ||
|
|
23f4ba4205 | ||
|
|
55ad136283 | ||
|
|
c717541099 | ||
|
|
c2e921c2dc | ||
|
|
e499169f0e | ||
|
|
84c088df67 | ||
|
|
f210f95f99 | ||
|
|
17b81c7c72 | ||
|
|
2911fce7cc | ||
|
|
e622d9fa6b | ||
|
|
8186fbb8b3 | ||
|
|
68ccff74fa | ||
|
|
9a13cb72c6 | ||
|
|
65abaa332f | ||
|
|
67e5829fd9 | ||
|
|
995b41e697 | ||
|
|
eb51bdfe2f | ||
|
|
bbb9ec637a | ||
|
|
dc012b49f5 | ||
|
|
13863a68f7 | ||
|
|
2962f76c81 | ||
|
|
b9b3ef6e74 | ||
|
|
310ab2eab2 | ||
|
|
53320070da | ||
|
|
2d5593681f | ||
|
|
b3f97dbb40 | ||
|
|
a48d76321e | ||
|
|
59222c58b1 | ||
|
|
4d95a7f244 | ||
|
|
5a8159eed7 | ||
|
|
e24fcb9ded | ||
|
|
4b94dc60d2 | ||
|
|
2046603d01 | ||
|
|
30412361e1 | ||
|
|
e846c85188 | ||
|
|
99b74095e6 | ||
|
|
6b802d36bf | ||
|
|
33ca43ca40 | ||
|
|
f5280a3090 | ||
|
|
c28d8ccea4 | ||
|
|
9690545901 | ||
|
|
eba4fb94cf | ||
|
|
565978225a | ||
|
|
cce9ca87fa | ||
|
|
683c523ece | ||
|
|
7a4dc20dc9 | ||
|
|
022dda06eb | ||
|
|
7b88a2d248 | ||
|
|
fce5b92091 | ||
|
|
45a506334c | ||
|
|
e47901a67f | ||
|
|
7430daa768 | ||
|
|
6ce25c8a3b | ||
|
|
7b8fa1eb4a | ||
|
|
ffa5349f25 | ||
|
|
bb472b63cc | ||
|
|
57f566a7a1 | ||
|
|
2181993246 | ||
|
|
60d1ecfa75 | ||
|
|
3962db12a8 | ||
|
|
f192507cd9 | ||
|
|
252be3e001 | ||
|
|
28f12a04f7 | ||
|
|
d6232dc49c | ||
|
|
68a220aa1c | ||
|
|
2e7db0f8bd |
@@ -2,3 +2,4 @@
|
|||||||
target
|
target
|
||||||
Cargo.lock
|
Cargo.lock
|
||||||
notes/
|
notes/
|
||||||
|
.lighthouse/
|
||||||
|
|||||||
@@ -1,191 +0,0 @@
|
|||||||
apiVersion: tekton.dev/v1beta1
|
|
||||||
kind: PipelineRun
|
|
||||||
metadata:
|
|
||||||
name: clippy
|
|
||||||
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
|
|
||||||
- name: GIT_USER_NAME
|
|
||||||
description: The username for git
|
|
||||||
type: string
|
|
||||||
default: "fluxcdbot"
|
|
||||||
- name: GIT_USER_EMAIL
|
|
||||||
description: The email for git
|
|
||||||
type: string
|
|
||||||
default: "fluxcdbot@users.noreply.github.com"
|
|
||||||
tasks:
|
|
||||||
- name: do-stuff
|
|
||||||
taskSpec:
|
|
||||||
metadata: {}
|
|
||||||
stepTemplate:
|
|
||||||
image: alpine:3.18
|
|
||||||
name: ""
|
|
||||||
resources:
|
|
||||||
requests:
|
|
||||||
cpu: 10m
|
|
||||||
memory: 600Mi
|
|
||||||
workingDir: /workspace/source
|
|
||||||
steps:
|
|
||||||
- image: alpine:3.18
|
|
||||||
name: do-stuff-step
|
|
||||||
script: |
|
|
||||||
#!/usr/bin/env sh
|
|
||||||
echo "hello world"
|
|
||||||
- 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
|
|
||||||
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:
|
|
||||||
- --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
|
|
||||||
- name: clippy
|
|
||||||
taskRef:
|
|
||||||
name: run-docker-image
|
|
||||||
workspaces:
|
|
||||||
- name: source
|
|
||||||
workspace: git-source
|
|
||||||
- name: cargo-cache
|
|
||||||
workspace: cargo-cache
|
|
||||||
runAfter:
|
|
||||||
- build-image
|
|
||||||
params:
|
|
||||||
- name: docker-image
|
|
||||||
value: "$(params.image-name):$(tasks.fetch-repository.results.commit)"
|
|
||||||
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: cargo-cache
|
|
||||||
persistentVolumeClaim:
|
|
||||||
claimName: organic-cargo-cache-clippy
|
|
||||||
- name: docker-credentials
|
|
||||||
secret:
|
|
||||||
secretName: harbor-plain
|
|
||||||
serviceAccountName: build-bot
|
|
||||||
timeout: 240h0m0s
|
|
||||||
params:
|
|
||||||
- name: image-name
|
|
||||||
value: "harbor.fizz.buzz/private/organic-clippy"
|
|
||||||
- name: path-to-image-context
|
|
||||||
value: docker/organic_clippy/
|
|
||||||
- name: path-to-dockerfile
|
|
||||||
value: docker/organic_clippy/Dockerfile
|
|
||||||
@@ -1,203 +0,0 @@
|
|||||||
apiVersion: tekton.dev/v1beta1
|
|
||||||
kind: PipelineRun
|
|
||||||
metadata:
|
|
||||||
name: rust-foreign-document-test
|
|
||||||
spec:
|
|
||||||
pipelineSpec:
|
|
||||||
timeouts:
|
|
||||||
pipeline: "2h0m0s"
|
|
||||||
tasks: "1h0m40s"
|
|
||||||
finally: "0h30m0s"
|
|
||||||
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: do-stuff
|
|
||||||
taskSpec:
|
|
||||||
metadata: {}
|
|
||||||
stepTemplate:
|
|
||||||
image: alpine:3.18
|
|
||||||
name: ""
|
|
||||||
resources:
|
|
||||||
requests:
|
|
||||||
cpu: 10m
|
|
||||||
memory: 600Mi
|
|
||||||
workingDir: /workspace/source
|
|
||||||
steps:
|
|
||||||
- image: alpine:3.18
|
|
||||||
name: do-stuff-step
|
|
||||||
script: |
|
|
||||||
#!/usr/bin/env sh
|
|
||||||
echo "hello world"
|
|
||||||
- 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
|
|
||||||
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:
|
|
||||||
- --target=foreign-document-test
|
|
||||||
- --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
|
|
||||||
- name: run-image
|
|
||||||
taskRef:
|
|
||||||
name: run-docker-image
|
|
||||||
workspaces:
|
|
||||||
- name: source
|
|
||||||
workspace: git-source
|
|
||||||
- name: cargo-cache
|
|
||||||
workspace: cargo-cache
|
|
||||||
runAfter:
|
|
||||||
- build-image
|
|
||||||
params:
|
|
||||||
- name: docker-image
|
|
||||||
value: "$(params.image-name):$(tasks.fetch-repository.results.commit)"
|
|
||||||
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)"
|
|
||||||
- name: cargo-cache-autoclean
|
|
||||||
taskRef:
|
|
||||||
name: run-docker-image
|
|
||||||
workspaces:
|
|
||||||
- name: source
|
|
||||||
workspace: git-source
|
|
||||||
- name: cargo-cache
|
|
||||||
workspace: cargo-cache
|
|
||||||
params:
|
|
||||||
- name: command
|
|
||||||
value: [cargo, cache, --autoclean]
|
|
||||||
- name: args
|
|
||||||
value: []
|
|
||||||
- name: docker-image
|
|
||||||
value: "$(params.image-name):$(tasks.fetch-repository.results.commit)"
|
|
||||||
workspaces:
|
|
||||||
- name: git-source
|
|
||||||
- name: docker-credentials
|
|
||||||
- name: cargo-cache
|
|
||||||
workspaces:
|
|
||||||
- name: git-source
|
|
||||||
volumeClaimTemplate:
|
|
||||||
spec:
|
|
||||||
storageClassName: "nfs-client"
|
|
||||||
accessModes:
|
|
||||||
- ReadWriteOnce
|
|
||||||
resources:
|
|
||||||
requests:
|
|
||||||
storage: 10Gi
|
|
||||||
subPath: rust-source
|
|
||||||
- name: cargo-cache
|
|
||||||
persistentVolumeClaim:
|
|
||||||
claimName: organic-cargo-cache-test-foreign-document
|
|
||||||
- name: docker-credentials
|
|
||||||
secret:
|
|
||||||
secretName: harbor-plain
|
|
||||||
serviceAccountName: build-bot
|
|
||||||
params:
|
|
||||||
- name: image-name
|
|
||||||
value: "harbor.fizz.buzz/private/organic-test-foreign-document"
|
|
||||||
- name: path-to-image-context
|
|
||||||
value: docker/organic_test/
|
|
||||||
- name: path-to-dockerfile
|
|
||||||
value: docker/organic_test/Dockerfile
|
|
||||||
@@ -1,284 +0,0 @@
|
|||||||
apiVersion: tekton.dev/v1beta1
|
|
||||||
kind: PipelineRun
|
|
||||||
metadata:
|
|
||||||
name: rust-build
|
|
||||||
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
|
|
||||||
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:
|
|
||||||
- --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
|
|
||||||
- name: run-image-none
|
|
||||||
taskRef:
|
|
||||||
name: run-docker-image
|
|
||||||
workspaces:
|
|
||||||
- name: source
|
|
||||||
workspace: git-source
|
|
||||||
- name: cargo-cache
|
|
||||||
workspace: cargo-cache
|
|
||||||
runAfter:
|
|
||||||
- build-image
|
|
||||||
params:
|
|
||||||
- name: args
|
|
||||||
value: ["--no-default-features"]
|
|
||||||
- name: docker-image
|
|
||||||
value: "$(params.image-name):$(tasks.fetch-repository.results.commit)"
|
|
||||||
- name: run-image-tracing
|
|
||||||
taskRef:
|
|
||||||
name: run-docker-image
|
|
||||||
workspaces:
|
|
||||||
- name: source
|
|
||||||
workspace: git-source
|
|
||||||
- name: cargo-cache
|
|
||||||
workspace: cargo-cache
|
|
||||||
runAfter:
|
|
||||||
- run-image-none
|
|
||||||
params:
|
|
||||||
- name: args
|
|
||||||
value: ["--no-default-features", "--features", "tracing"]
|
|
||||||
- name: docker-image
|
|
||||||
value: "$(params.image-name):$(tasks.fetch-repository.results.commit)"
|
|
||||||
- name: run-image-compare
|
|
||||||
taskRef:
|
|
||||||
name: run-docker-image
|
|
||||||
workspaces:
|
|
||||||
- name: source
|
|
||||||
workspace: git-source
|
|
||||||
- name: cargo-cache
|
|
||||||
workspace: cargo-cache
|
|
||||||
runAfter:
|
|
||||||
- run-image-tracing
|
|
||||||
params:
|
|
||||||
- name: args
|
|
||||||
value: ["--no-default-features", "--features", "compare"]
|
|
||||||
- name: docker-image
|
|
||||||
value: "$(params.image-name):$(tasks.fetch-repository.results.commit)"
|
|
||||||
- name: run-image-default
|
|
||||||
taskRef:
|
|
||||||
name: run-docker-image
|
|
||||||
workspaces:
|
|
||||||
- name: source
|
|
||||||
workspace: git-source
|
|
||||||
- name: cargo-cache
|
|
||||||
workspace: cargo-cache
|
|
||||||
runAfter:
|
|
||||||
- run-image-compare
|
|
||||||
params:
|
|
||||||
- name: args
|
|
||||||
value: []
|
|
||||||
- name: docker-image
|
|
||||||
value: "$(params.image-name):$(tasks.fetch-repository.results.commit)"
|
|
||||||
- name: run-image-tracing-compare
|
|
||||||
taskRef:
|
|
||||||
name: run-docker-image
|
|
||||||
workspaces:
|
|
||||||
- name: source
|
|
||||||
workspace: git-source
|
|
||||||
- name: cargo-cache
|
|
||||||
workspace: cargo-cache
|
|
||||||
runAfter:
|
|
||||||
- run-image-default
|
|
||||||
params:
|
|
||||||
- name: args
|
|
||||||
value: ["--no-default-features", "--features", "tracing,compare"]
|
|
||||||
- name: docker-image
|
|
||||||
value: "$(params.image-name):$(tasks.fetch-repository.results.commit)"
|
|
||||||
- name: run-image-compare-foreign
|
|
||||||
taskRef:
|
|
||||||
name: run-docker-image
|
|
||||||
workspaces:
|
|
||||||
- name: source
|
|
||||||
workspace: git-source
|
|
||||||
- name: cargo-cache
|
|
||||||
workspace: cargo-cache
|
|
||||||
runAfter:
|
|
||||||
- run-image-tracing-compare
|
|
||||||
params:
|
|
||||||
- name: args
|
|
||||||
value:
|
|
||||||
[
|
|
||||||
"--no-default-features",
|
|
||||||
"--features",
|
|
||||||
"compare,foreign_document_test",
|
|
||||||
]
|
|
||||||
- name: docker-image
|
|
||||||
value: "$(params.image-name):$(tasks.fetch-repository.results.commit)"
|
|
||||||
- name: run-image-all
|
|
||||||
taskRef:
|
|
||||||
name: run-docker-image
|
|
||||||
workspaces:
|
|
||||||
- name: source
|
|
||||||
workspace: git-source
|
|
||||||
- name: cargo-cache
|
|
||||||
workspace: cargo-cache
|
|
||||||
runAfter:
|
|
||||||
- run-image-compare-foreign
|
|
||||||
params:
|
|
||||||
- name: args
|
|
||||||
value:
|
|
||||||
[
|
|
||||||
"--no-default-features",
|
|
||||||
"--features",
|
|
||||||
"tracing,compare,foreign_document_test",
|
|
||||||
]
|
|
||||||
- name: docker-image
|
|
||||||
value: "$(params.image-name):$(tasks.fetch-repository.results.commit)"
|
|
||||||
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)"
|
|
||||||
- name: cargo-cache-autoclean
|
|
||||||
taskRef:
|
|
||||||
name: run-docker-image
|
|
||||||
workspaces:
|
|
||||||
- name: source
|
|
||||||
workspace: git-source
|
|
||||||
- name: cargo-cache
|
|
||||||
workspace: cargo-cache
|
|
||||||
params:
|
|
||||||
- name: command
|
|
||||||
value: [cargo, cache, --autoclean]
|
|
||||||
- name: args
|
|
||||||
value: []
|
|
||||||
- name: docker-image
|
|
||||||
value: "$(params.image-name):$(tasks.fetch-repository.results.commit)"
|
|
||||||
workspaces:
|
|
||||||
- name: git-source
|
|
||||||
- name: docker-credentials
|
|
||||||
- name: cargo-cache
|
|
||||||
workspaces:
|
|
||||||
- name: git-source
|
|
||||||
volumeClaimTemplate:
|
|
||||||
spec:
|
|
||||||
storageClassName: "nfs-client"
|
|
||||||
accessModes:
|
|
||||||
- ReadWriteOnce
|
|
||||||
resources:
|
|
||||||
requests:
|
|
||||||
storage: 10Gi
|
|
||||||
subPath: rust-source
|
|
||||||
- name: cargo-cache
|
|
||||||
persistentVolumeClaim:
|
|
||||||
claimName: organic-cargo-cache-build
|
|
||||||
- name: docker-credentials
|
|
||||||
secret:
|
|
||||||
secretName: harbor-plain
|
|
||||||
serviceAccountName: build-bot
|
|
||||||
timeout: 240h0m0s
|
|
||||||
params:
|
|
||||||
- name: image-name
|
|
||||||
value: "harbor.fizz.buzz/private/organic-build"
|
|
||||||
- name: path-to-image-context
|
|
||||||
value: docker/organic_build/
|
|
||||||
- name: path-to-dockerfile
|
|
||||||
value: docker/organic_build/Dockerfile
|
|
||||||
@@ -1,214 +0,0 @@
|
|||||||
apiVersion: tekton.dev/v1beta1
|
|
||||||
kind: PipelineRun
|
|
||||||
metadata:
|
|
||||||
name: rust-test
|
|
||||||
spec:
|
|
||||||
pipelineSpec:
|
|
||||||
timeouts:
|
|
||||||
pipeline: "2h0m0s"
|
|
||||||
tasks: "1h0m40s"
|
|
||||||
finally: "0h30m0s"
|
|
||||||
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: do-stuff
|
|
||||||
taskSpec:
|
|
||||||
metadata: {}
|
|
||||||
stepTemplate:
|
|
||||||
image: alpine:3.18
|
|
||||||
name: ""
|
|
||||||
resources:
|
|
||||||
requests:
|
|
||||||
cpu: 10m
|
|
||||||
memory: 600Mi
|
|
||||||
workingDir: /workspace/source
|
|
||||||
steps:
|
|
||||||
- image: alpine:3.18
|
|
||||||
name: do-stuff-step
|
|
||||||
script: |
|
|
||||||
#!/usr/bin/env sh
|
|
||||||
echo "hello world"
|
|
||||||
- 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
|
|
||||||
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:
|
|
||||||
- --target=tester
|
|
||||||
- --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
|
|
||||||
- name: run-image
|
|
||||||
taskRef:
|
|
||||||
name: run-docker-image
|
|
||||||
workspaces:
|
|
||||||
- name: source
|
|
||||||
workspace: git-source
|
|
||||||
- name: cargo-cache
|
|
||||||
workspace: cargo-cache
|
|
||||||
runAfter:
|
|
||||||
- build-image
|
|
||||||
params:
|
|
||||||
- name: args
|
|
||||||
value:
|
|
||||||
[
|
|
||||||
--no-default-features,
|
|
||||||
--features,
|
|
||||||
compare,
|
|
||||||
--no-fail-fast,
|
|
||||||
--lib,
|
|
||||||
--test,
|
|
||||||
test_loader,
|
|
||||||
]
|
|
||||||
- name: docker-image
|
|
||||||
value: "$(params.image-name):$(tasks.fetch-repository.results.commit)"
|
|
||||||
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)"
|
|
||||||
- name: cargo-cache-autoclean
|
|
||||||
taskRef:
|
|
||||||
name: run-docker-image
|
|
||||||
workspaces:
|
|
||||||
- name: source
|
|
||||||
workspace: git-source
|
|
||||||
- name: cargo-cache
|
|
||||||
workspace: cargo-cache
|
|
||||||
params:
|
|
||||||
- name: command
|
|
||||||
value: [cargo, cache, --autoclean]
|
|
||||||
- name: args
|
|
||||||
value: []
|
|
||||||
- name: docker-image
|
|
||||||
value: "$(params.image-name):$(tasks.fetch-repository.results.commit)"
|
|
||||||
workspaces:
|
|
||||||
- name: git-source
|
|
||||||
- name: docker-credentials
|
|
||||||
- name: cargo-cache
|
|
||||||
workspaces:
|
|
||||||
- name: git-source
|
|
||||||
volumeClaimTemplate:
|
|
||||||
spec:
|
|
||||||
storageClassName: "nfs-client"
|
|
||||||
accessModes:
|
|
||||||
- ReadWriteOnce
|
|
||||||
resources:
|
|
||||||
requests:
|
|
||||||
storage: 10Gi
|
|
||||||
subPath: rust-source
|
|
||||||
- name: cargo-cache
|
|
||||||
persistentVolumeClaim:
|
|
||||||
claimName: organic-cargo-cache-test
|
|
||||||
- name: docker-credentials
|
|
||||||
secret:
|
|
||||||
secretName: harbor-plain
|
|
||||||
serviceAccountName: build-bot
|
|
||||||
params:
|
|
||||||
- name: image-name
|
|
||||||
value: "harbor.fizz.buzz/private/organic-test"
|
|
||||||
- name: path-to-image-context
|
|
||||||
value: docker/organic_test/
|
|
||||||
- name: path-to-dockerfile
|
|
||||||
value: docker/organic_test/Dockerfile
|
|
||||||
@@ -1,230 +0,0 @@
|
|||||||
apiVersion: tekton.dev/v1beta1
|
|
||||||
kind: PipelineRun
|
|
||||||
metadata:
|
|
||||||
name: rustfmt
|
|
||||||
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
|
|
||||||
- name: GIT_USER_NAME
|
|
||||||
description: The username for git
|
|
||||||
type: string
|
|
||||||
default: "fluxcdbot"
|
|
||||||
- name: GIT_USER_EMAIL
|
|
||||||
description: The email for git
|
|
||||||
type: string
|
|
||||||
default: "fluxcdbot@users.noreply.github.com"
|
|
||||||
tasks:
|
|
||||||
- name: do-stuff
|
|
||||||
taskSpec:
|
|
||||||
metadata: {}
|
|
||||||
stepTemplate:
|
|
||||||
image: alpine:3.18
|
|
||||||
name: ""
|
|
||||||
resources:
|
|
||||||
requests:
|
|
||||||
cpu: 10m
|
|
||||||
memory: 600Mi
|
|
||||||
workingDir: /workspace/source
|
|
||||||
steps:
|
|
||||||
- image: alpine:3.18
|
|
||||||
name: do-stuff-step
|
|
||||||
script: |
|
|
||||||
#!/usr/bin/env sh
|
|
||||||
echo "hello world"
|
|
||||||
- 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
|
|
||||||
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:
|
|
||||||
- --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
|
|
||||||
- name: rustfmt
|
|
||||||
taskRef:
|
|
||||||
name: run-docker-image
|
|
||||||
workspaces:
|
|
||||||
- name: source
|
|
||||||
workspace: git-source
|
|
||||||
runAfter:
|
|
||||||
- build-image
|
|
||||||
params:
|
|
||||||
- name: docker-image
|
|
||||||
value: "$(params.image-name):$(tasks.fetch-repository.results.commit)"
|
|
||||||
- name: cargo-fix
|
|
||||||
taskRef:
|
|
||||||
name: run-docker-image
|
|
||||||
workspaces:
|
|
||||||
- name: source
|
|
||||||
workspace: git-source
|
|
||||||
- name: cargo-cache
|
|
||||||
workspace: cargo-cache
|
|
||||||
runAfter:
|
|
||||||
- rustfmt
|
|
||||||
params:
|
|
||||||
- name: command
|
|
||||||
value: ["cargo", "fix"]
|
|
||||||
- name: args
|
|
||||||
value: ["--allow-dirty"]
|
|
||||||
- name: docker-image
|
|
||||||
value: "$(params.image-name):$(tasks.fetch-repository.results.commit)"
|
|
||||||
- name: commit-changes
|
|
||||||
taskRef:
|
|
||||||
name: git-cli
|
|
||||||
params:
|
|
||||||
- name: GIT_USER_NAME
|
|
||||||
value: $(params.GIT_USER_NAME)
|
|
||||||
- name: GIT_USER_EMAIL
|
|
||||||
value: $(params.GIT_USER_EMAIL)
|
|
||||||
- name: GIT_SCRIPT
|
|
||||||
value: |
|
|
||||||
pwd
|
|
||||||
git config --global --add safe.directory /workspace/source
|
|
||||||
git_status=$(git status --porcelain)
|
|
||||||
if [ -n "$git_status" ]; then
|
|
||||||
git commit -a -m "CI: autofix rust code."
|
|
||||||
git push origin HEAD:$(params.PULL_BASE_REF)
|
|
||||||
else
|
|
||||||
echo "No changes to commit."
|
|
||||||
fi
|
|
||||||
workspaces:
|
|
||||||
- name: source
|
|
||||||
workspace: git-source
|
|
||||||
runAfter:
|
|
||||||
- cargo-fix
|
|
||||||
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: cargo-cache
|
|
||||||
persistentVolumeClaim:
|
|
||||||
claimName: organic-cargo-cache-fmt
|
|
||||||
- name: docker-credentials
|
|
||||||
secret:
|
|
||||||
secretName: harbor-plain
|
|
||||||
serviceAccountName: build-bot
|
|
||||||
timeout: 240h0m0s
|
|
||||||
params:
|
|
||||||
- name: image-name
|
|
||||||
value: "harbor.fizz.buzz/private/organic-fmt"
|
|
||||||
- name: path-to-image-context
|
|
||||||
value: docker/cargo_fmt/
|
|
||||||
- name: path-to-dockerfile
|
|
||||||
value: docker/cargo_fmt/Dockerfile
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
apiVersion: config.lighthouse.jenkins-x.io/v1alpha1
|
|
||||||
kind: TriggerConfig
|
|
||||||
spec:
|
|
||||||
postsubmits:
|
|
||||||
- name: rustfmt
|
|
||||||
source: "pipeline-rustfmt.yaml"
|
|
||||||
# Override https-based url from lighthouse events.
|
|
||||||
clone_uri: "git@code.fizz.buzz:talexander/organic.git"
|
|
||||||
branches:
|
|
||||||
- ^main$
|
|
||||||
- ^master$
|
|
||||||
- name: rust-test
|
|
||||||
source: "pipeline-rust-test.yaml"
|
|
||||||
# Override https-based url from lighthouse events.
|
|
||||||
clone_uri: "git@code.fizz.buzz:talexander/organic.git"
|
|
||||||
skip_branches:
|
|
||||||
# We already run on every commit, so running when the semver tags get pushed is causing needless double-processing.
|
|
||||||
- "^v[0-9]+\\.[0-9]+\\.[0-9]+$"
|
|
||||||
- name: rust-foreign-document-test
|
|
||||||
source: "pipeline-foreign-document-test.yaml"
|
|
||||||
# Override https-based url from lighthouse events.
|
|
||||||
clone_uri: "git@code.fizz.buzz:talexander/organic.git"
|
|
||||||
skip_branches:
|
|
||||||
# We already run on every commit, so running when the semver tags get pushed is causing needless double-processing.
|
|
||||||
- "^v[0-9]+\\.[0-9]+\\.[0-9]+$"
|
|
||||||
- name: rust-build
|
|
||||||
source: "pipeline-rust-build.yaml"
|
|
||||||
# Override https-based url from lighthouse events.
|
|
||||||
clone_uri: "git@code.fizz.buzz:talexander/organic.git"
|
|
||||||
skip_branches:
|
|
||||||
# We already run on every commit, so running when the semver tags get pushed is causing needless double-processing.
|
|
||||||
- "^v[0-9]+\\.[0-9]+\\.[0-9]+$"
|
|
||||||
- name: clippy
|
|
||||||
source: "pipeline-clippy.yaml"
|
|
||||||
# Override https-based url from lighthouse events.
|
|
||||||
clone_uri: "git@code.fizz.buzz:talexander/organic.git"
|
|
||||||
skip_branches:
|
|
||||||
# We already run on every commit, so running when the semver tags get pushed is causing needless double-processing.
|
|
||||||
- "^v[0-9]+\\.[0-9]+\\.[0-9]+$"
|
|
||||||
701
.webhook_bridge/pipeline-build-hash.yaml
Normal file
701
.webhook_bridge/pipeline-build-hash.yaml
Normal file
@@ -0,0 +1,701 @@
|
|||||||
|
apiVersion: tekton.dev/v1
|
||||||
|
kind: PipelineRun
|
||||||
|
metadata:
|
||||||
|
name: build
|
||||||
|
spec:
|
||||||
|
timeouts:
|
||||||
|
pipeline: "2h0m0s"
|
||||||
|
tasks: "1h0m0s"
|
||||||
|
finally: "0h30m0s"
|
||||||
|
taskRunTemplate:
|
||||||
|
serviceAccountName: build-bot
|
||||||
|
pipelineSpec:
|
||||||
|
params:
|
||||||
|
- name: image-name
|
||||||
|
description: The name for the built image
|
||||||
|
type: string
|
||||||
|
- name: target-name
|
||||||
|
description: The dockerfile target to build
|
||||||
|
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:
|
||||||
|
resolver: git
|
||||||
|
params:
|
||||||
|
- name: url
|
||||||
|
value: https://code.fizz.buzz/mirror/catalog.git # mirror of https://github.com/tektoncd/catalog.git
|
||||||
|
- name: revision
|
||||||
|
value: df36b3853a5657fd883015cdbf07ad6466918acf
|
||||||
|
- name: pathInRepo
|
||||||
|
value: task/gitea-set-status/0.1/gitea-set-status.yaml
|
||||||
|
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:
|
||||||
|
resolver: git
|
||||||
|
params:
|
||||||
|
- name: url
|
||||||
|
value: https://code.fizz.buzz/mirror/catalog.git # mirror of https://github.com/tektoncd/catalog.git
|
||||||
|
- name: revision
|
||||||
|
value: df36b3853a5657fd883015cdbf07ad6466918acf
|
||||||
|
- name: pathInRepo
|
||||||
|
value: task/git-clone/0.9/git-clone.yaml
|
||||||
|
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: get-git-commit-time
|
||||||
|
taskSpec:
|
||||||
|
metadata: {}
|
||||||
|
stepTemplate:
|
||||||
|
image: alpine:3.20
|
||||||
|
computeResources:
|
||||||
|
requests:
|
||||||
|
cpu: 10m
|
||||||
|
memory: 600Mi
|
||||||
|
workingDir: "$(workspaces.repo.path)"
|
||||||
|
results:
|
||||||
|
- name: unix-time
|
||||||
|
description: The time of the git commit in unix timestamp format.
|
||||||
|
steps:
|
||||||
|
- image: alpine/git:v2.34.2
|
||||||
|
name: detect-tag-step
|
||||||
|
script: |
|
||||||
|
#!/usr/bin/env sh
|
||||||
|
set -euo pipefail
|
||||||
|
echo -n "$(git log -1 --pretty=%ct)" | tee $(results.unix-time.path)
|
||||||
|
workspaces:
|
||||||
|
- name: repo
|
||||||
|
workspace: git-source
|
||||||
|
runAfter:
|
||||||
|
- fetch-repository
|
||||||
|
- name: build-image
|
||||||
|
taskRef:
|
||||||
|
resolver: git
|
||||||
|
params:
|
||||||
|
- name: url
|
||||||
|
value: https://code.fizz.buzz/talexander/personal_tekton_catalog.git
|
||||||
|
- name: revision
|
||||||
|
value: 7ee31a185243ee6da13dcd26a592c585b64c80e5
|
||||||
|
- name: pathInRepo
|
||||||
|
value: task/buildkit-rootless-daemonless/0.1/buildkit-rootless-daemonless.yaml
|
||||||
|
params:
|
||||||
|
- name: OUTPUT
|
||||||
|
value: >-
|
||||||
|
type=image,"name=$(params.image-name):latest,$(params.image-name):$(tasks.fetch-repository.results.commit)",push=true,compression=zstd,compression-level=22,oci-mediatypes=true
|
||||||
|
- name: CONTEXT
|
||||||
|
value: $(params.path-to-image-context)
|
||||||
|
- name: DOCKERFILE
|
||||||
|
value: $(params.path-to-dockerfile)
|
||||||
|
- name: EXTRA_ARGS
|
||||||
|
value:
|
||||||
|
- "--opt"
|
||||||
|
- "target=$(params.target-name)"
|
||||||
|
- --import-cache
|
||||||
|
- "type=registry,ref=$(params.image-name):buildcache"
|
||||||
|
- --export-cache
|
||||||
|
- "type=registry,ref=$(params.image-name):buildcache,mode=max,compression=zstd,compression-level=22,rewrite-timestamp=true,image-manifest=true,oci-mediatypes=true"
|
||||||
|
- --opt
|
||||||
|
- build-arg:SOURCE_DATE_EPOCH=$(tasks.get-git-commit-time.results.unix-time)
|
||||||
|
- name: BUILDKITD_TOML
|
||||||
|
value: |
|
||||||
|
debug = true
|
||||||
|
[registry."docker.io"]
|
||||||
|
mirrors = ["dockerhub.dockerhub.svc.cluster.local"]
|
||||||
|
[registry."dockerhub.dockerhub.svc.cluster.local"]
|
||||||
|
http = true
|
||||||
|
insecure = true
|
||||||
|
workspaces:
|
||||||
|
- name: source
|
||||||
|
workspace: git-source
|
||||||
|
- name: dockerconfig
|
||||||
|
workspace: docker-credentials
|
||||||
|
runAfter:
|
||||||
|
- fetch-repository
|
||||||
|
#############
|
||||||
|
- name: run-image-none
|
||||||
|
taskSpec:
|
||||||
|
metadata: {}
|
||||||
|
params:
|
||||||
|
- name: docker-image
|
||||||
|
type: string
|
||||||
|
description: Docker image to run.
|
||||||
|
default: alpine:3.18
|
||||||
|
stepTemplate:
|
||||||
|
image: alpine:3.18
|
||||||
|
name: ""
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: 10m
|
||||||
|
memory: 60Mi
|
||||||
|
workingDir: /workspace/source
|
||||||
|
workspaces:
|
||||||
|
- name: source
|
||||||
|
mountPath: /source
|
||||||
|
- name: cargo-cache
|
||||||
|
mountPath: /usr/local/cargo/registry
|
||||||
|
optional: true
|
||||||
|
steps:
|
||||||
|
- name: run
|
||||||
|
image: $(params.docker-image)
|
||||||
|
workingDir: "$(workspaces.source.path)"
|
||||||
|
command: ["cargo", "build"]
|
||||||
|
args: ["--no-default-features"]
|
||||||
|
env:
|
||||||
|
- name: CARGO_TARGET_DIR
|
||||||
|
value: /target
|
||||||
|
workspaces:
|
||||||
|
- name: source
|
||||||
|
workspace: git-source
|
||||||
|
- name: cargo-cache
|
||||||
|
workspace: cargo-cache
|
||||||
|
subPath: none
|
||||||
|
runAfter:
|
||||||
|
- build-image
|
||||||
|
params:
|
||||||
|
- name: docker-image
|
||||||
|
value: "$(tasks.build-image.results.IMAGE_URL[1])"
|
||||||
|
#############
|
||||||
|
- name: run-image-tracing
|
||||||
|
taskSpec:
|
||||||
|
metadata: {}
|
||||||
|
params:
|
||||||
|
- name: docker-image
|
||||||
|
type: string
|
||||||
|
description: Docker image to run.
|
||||||
|
default: alpine:3.18
|
||||||
|
stepTemplate:
|
||||||
|
image: alpine:3.18
|
||||||
|
name: ""
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: 10m
|
||||||
|
memory: 60Mi
|
||||||
|
workingDir: /workspace/source
|
||||||
|
workspaces:
|
||||||
|
- name: source
|
||||||
|
mountPath: /source
|
||||||
|
- name: cargo-cache
|
||||||
|
mountPath: /usr/local/cargo/registry
|
||||||
|
optional: true
|
||||||
|
steps:
|
||||||
|
- name: run
|
||||||
|
image: $(params.docker-image)
|
||||||
|
workingDir: "$(workspaces.source.path)"
|
||||||
|
command: ["cargo", "build"]
|
||||||
|
args: ["--no-default-features", "--features", "tracing"]
|
||||||
|
env:
|
||||||
|
- name: CARGO_TARGET_DIR
|
||||||
|
value: /target
|
||||||
|
workspaces:
|
||||||
|
- name: source
|
||||||
|
workspace: git-source
|
||||||
|
- name: cargo-cache
|
||||||
|
workspace: cargo-cache
|
||||||
|
subPath: tracing
|
||||||
|
runAfter:
|
||||||
|
- run-image-none
|
||||||
|
params:
|
||||||
|
- name: docker-image
|
||||||
|
value: "$(tasks.build-image.results.IMAGE_URL[1])"
|
||||||
|
#############
|
||||||
|
- name: run-image-compare
|
||||||
|
taskSpec:
|
||||||
|
metadata: {}
|
||||||
|
params:
|
||||||
|
- name: docker-image
|
||||||
|
type: string
|
||||||
|
description: Docker image to run.
|
||||||
|
default: alpine:3.18
|
||||||
|
stepTemplate:
|
||||||
|
image: alpine:3.18
|
||||||
|
name: ""
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: 10m
|
||||||
|
memory: 60Mi
|
||||||
|
workingDir: /workspace/source
|
||||||
|
workspaces:
|
||||||
|
- name: source
|
||||||
|
mountPath: /source
|
||||||
|
- name: cargo-cache
|
||||||
|
mountPath: /usr/local/cargo/registry
|
||||||
|
optional: true
|
||||||
|
steps:
|
||||||
|
- name: run
|
||||||
|
image: $(params.docker-image)
|
||||||
|
workingDir: "$(workspaces.source.path)"
|
||||||
|
command: ["cargo", "build"]
|
||||||
|
args: ["--no-default-features", "--features", "compare"]
|
||||||
|
env:
|
||||||
|
- name: CARGO_TARGET_DIR
|
||||||
|
value: /target
|
||||||
|
workspaces:
|
||||||
|
- name: source
|
||||||
|
workspace: git-source
|
||||||
|
- name: cargo-cache
|
||||||
|
workspace: cargo-cache
|
||||||
|
subPath: compare
|
||||||
|
runAfter:
|
||||||
|
- run-image-tracing
|
||||||
|
params:
|
||||||
|
- name: docker-image
|
||||||
|
value: "$(tasks.build-image.results.IMAGE_URL[1])"
|
||||||
|
#############
|
||||||
|
- name: run-image-default
|
||||||
|
taskSpec:
|
||||||
|
metadata: {}
|
||||||
|
params:
|
||||||
|
- name: docker-image
|
||||||
|
type: string
|
||||||
|
description: Docker image to run.
|
||||||
|
default: alpine:3.18
|
||||||
|
stepTemplate:
|
||||||
|
image: alpine:3.18
|
||||||
|
name: ""
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: 10m
|
||||||
|
memory: 60Mi
|
||||||
|
workingDir: /workspace/source
|
||||||
|
workspaces:
|
||||||
|
- name: source
|
||||||
|
mountPath: /source
|
||||||
|
- name: cargo-cache
|
||||||
|
mountPath: /usr/local/cargo/registry
|
||||||
|
optional: true
|
||||||
|
steps:
|
||||||
|
- name: run
|
||||||
|
image: $(params.docker-image)
|
||||||
|
workingDir: "$(workspaces.source.path)"
|
||||||
|
command: ["cargo", "build"]
|
||||||
|
args: []
|
||||||
|
env:
|
||||||
|
- name: CARGO_TARGET_DIR
|
||||||
|
value: /target
|
||||||
|
workspaces:
|
||||||
|
- name: source
|
||||||
|
workspace: git-source
|
||||||
|
- name: cargo-cache
|
||||||
|
workspace: cargo-cache
|
||||||
|
subPath: default
|
||||||
|
runAfter:
|
||||||
|
- run-image-compare
|
||||||
|
params:
|
||||||
|
- name: docker-image
|
||||||
|
value: "$(tasks.build-image.results.IMAGE_URL[1])"
|
||||||
|
#############
|
||||||
|
- name: run-image-tracing-compare
|
||||||
|
taskSpec:
|
||||||
|
metadata: {}
|
||||||
|
params:
|
||||||
|
- name: docker-image
|
||||||
|
type: string
|
||||||
|
description: Docker image to run.
|
||||||
|
default: alpine:3.18
|
||||||
|
stepTemplate:
|
||||||
|
image: alpine:3.18
|
||||||
|
name: ""
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: 10m
|
||||||
|
memory: 60Mi
|
||||||
|
workingDir: /workspace/source
|
||||||
|
workspaces:
|
||||||
|
- name: source
|
||||||
|
mountPath: /source
|
||||||
|
- name: cargo-cache
|
||||||
|
mountPath: /usr/local/cargo/registry
|
||||||
|
optional: true
|
||||||
|
steps:
|
||||||
|
- name: run
|
||||||
|
image: $(params.docker-image)
|
||||||
|
workingDir: "$(workspaces.source.path)"
|
||||||
|
command: ["cargo", "build"]
|
||||||
|
args: ["--no-default-features", "--features", "tracing,compare"]
|
||||||
|
env:
|
||||||
|
- name: CARGO_TARGET_DIR
|
||||||
|
value: /target
|
||||||
|
workspaces:
|
||||||
|
- name: source
|
||||||
|
workspace: git-source
|
||||||
|
- name: cargo-cache
|
||||||
|
workspace: cargo-cache
|
||||||
|
subPath: tracing-compare
|
||||||
|
runAfter:
|
||||||
|
- run-image-default
|
||||||
|
params:
|
||||||
|
- name: docker-image
|
||||||
|
value: "$(tasks.build-image.results.IMAGE_URL[1])"
|
||||||
|
#############
|
||||||
|
- name: run-image-compare-foreign
|
||||||
|
taskSpec:
|
||||||
|
metadata: {}
|
||||||
|
params:
|
||||||
|
- name: docker-image
|
||||||
|
type: string
|
||||||
|
description: Docker image to run.
|
||||||
|
default: alpine:3.18
|
||||||
|
stepTemplate:
|
||||||
|
image: alpine:3.18
|
||||||
|
name: ""
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: 10m
|
||||||
|
memory: 60Mi
|
||||||
|
workingDir: /workspace/source
|
||||||
|
workspaces:
|
||||||
|
- name: source
|
||||||
|
mountPath: /source
|
||||||
|
- name: cargo-cache
|
||||||
|
mountPath: /usr/local/cargo/registry
|
||||||
|
optional: true
|
||||||
|
steps:
|
||||||
|
- name: run
|
||||||
|
image: $(params.docker-image)
|
||||||
|
workingDir: "$(workspaces.source.path)"
|
||||||
|
command: ["cargo", "build"]
|
||||||
|
args:
|
||||||
|
[
|
||||||
|
"--no-default-features",
|
||||||
|
"--features",
|
||||||
|
"compare,foreign_document_test",
|
||||||
|
]
|
||||||
|
env:
|
||||||
|
- name: CARGO_TARGET_DIR
|
||||||
|
value: /target
|
||||||
|
workspaces:
|
||||||
|
- name: source
|
||||||
|
workspace: git-source
|
||||||
|
- name: cargo-cache
|
||||||
|
workspace: cargo-cache
|
||||||
|
subPath: compare-foreign
|
||||||
|
runAfter:
|
||||||
|
- run-image-tracing-compare
|
||||||
|
params:
|
||||||
|
- name: docker-image
|
||||||
|
value: "$(tasks.build-image.results.IMAGE_URL[1])"
|
||||||
|
#############
|
||||||
|
- name: run-image-all
|
||||||
|
taskSpec:
|
||||||
|
metadata: {}
|
||||||
|
params:
|
||||||
|
- name: docker-image
|
||||||
|
type: string
|
||||||
|
description: Docker image to run.
|
||||||
|
default: alpine:3.18
|
||||||
|
stepTemplate:
|
||||||
|
image: alpine:3.18
|
||||||
|
name: ""
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: 10m
|
||||||
|
memory: 60Mi
|
||||||
|
workingDir: /workspace/source
|
||||||
|
workspaces:
|
||||||
|
- name: source
|
||||||
|
mountPath: /source
|
||||||
|
- name: cargo-cache
|
||||||
|
mountPath: /usr/local/cargo/registry
|
||||||
|
optional: true
|
||||||
|
steps:
|
||||||
|
- name: run
|
||||||
|
image: $(params.docker-image)
|
||||||
|
workingDir: "$(workspaces.source.path)"
|
||||||
|
command: ["cargo", "build"]
|
||||||
|
args:
|
||||||
|
[
|
||||||
|
"--no-default-features",
|
||||||
|
"--features",
|
||||||
|
"tracing,compare,foreign_document_test",
|
||||||
|
]
|
||||||
|
env:
|
||||||
|
- name: CARGO_TARGET_DIR
|
||||||
|
value: /target
|
||||||
|
workspaces:
|
||||||
|
- name: source
|
||||||
|
workspace: git-source
|
||||||
|
- name: cargo-cache
|
||||||
|
workspace: cargo-cache
|
||||||
|
subPath: all
|
||||||
|
runAfter:
|
||||||
|
- run-image-compare-foreign
|
||||||
|
params:
|
||||||
|
- name: docker-image
|
||||||
|
value: "$(tasks.build-image.results.IMAGE_URL[1])"
|
||||||
|
#############
|
||||||
|
- name: run-image-wasm
|
||||||
|
taskSpec:
|
||||||
|
metadata: {}
|
||||||
|
params:
|
||||||
|
- name: docker-image
|
||||||
|
type: string
|
||||||
|
description: Docker image to run.
|
||||||
|
default: alpine:3.18
|
||||||
|
stepTemplate:
|
||||||
|
image: alpine:3.18
|
||||||
|
name: ""
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: 10m
|
||||||
|
memory: 60Mi
|
||||||
|
workingDir: /workspace/source
|
||||||
|
workspaces:
|
||||||
|
- name: source
|
||||||
|
mountPath: /source
|
||||||
|
- name: cargo-cache
|
||||||
|
mountPath: /usr/local/cargo/registry
|
||||||
|
optional: true
|
||||||
|
steps:
|
||||||
|
- name: run
|
||||||
|
image: $(params.docker-image)
|
||||||
|
workingDir: "$(workspaces.source.path)"
|
||||||
|
command: ["cargo", "build"]
|
||||||
|
args:
|
||||||
|
[
|
||||||
|
"--target",
|
||||||
|
"wasm32-unknown-unknown",
|
||||||
|
"--profile",
|
||||||
|
"wasm",
|
||||||
|
"--bin",
|
||||||
|
"wasm",
|
||||||
|
"--no-default-features",
|
||||||
|
"--features",
|
||||||
|
"wasm",
|
||||||
|
]
|
||||||
|
env:
|
||||||
|
- name: CARGO_TARGET_DIR
|
||||||
|
value: /target
|
||||||
|
workspaces:
|
||||||
|
- name: source
|
||||||
|
workspace: git-source
|
||||||
|
- name: cargo-cache
|
||||||
|
workspace: cargo-cache
|
||||||
|
subPath: wasm
|
||||||
|
runAfter:
|
||||||
|
- run-image-all
|
||||||
|
params:
|
||||||
|
- name: docker-image
|
||||||
|
value: "$(tasks.build-image.results.IMAGE_URL[1])"
|
||||||
|
#############
|
||||||
|
- name: run-image-wasm-test
|
||||||
|
taskSpec:
|
||||||
|
metadata: {}
|
||||||
|
params:
|
||||||
|
- name: docker-image
|
||||||
|
type: string
|
||||||
|
description: Docker image to run.
|
||||||
|
default: alpine:3.18
|
||||||
|
stepTemplate:
|
||||||
|
image: alpine:3.18
|
||||||
|
name: ""
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: 10m
|
||||||
|
memory: 60Mi
|
||||||
|
workingDir: /workspace/source
|
||||||
|
workspaces:
|
||||||
|
- name: source
|
||||||
|
mountPath: /source
|
||||||
|
- name: cargo-cache
|
||||||
|
mountPath: /usr/local/cargo/registry
|
||||||
|
optional: true
|
||||||
|
steps:
|
||||||
|
- name: run
|
||||||
|
image: $(params.docker-image)
|
||||||
|
workingDir: "$(workspaces.source.path)"
|
||||||
|
command: ["cargo", "build"]
|
||||||
|
args:
|
||||||
|
[
|
||||||
|
"--bin",
|
||||||
|
"wasm_test",
|
||||||
|
"--no-default-features",
|
||||||
|
"--features",
|
||||||
|
"wasm_test",
|
||||||
|
]
|
||||||
|
env:
|
||||||
|
- name: CARGO_TARGET_DIR
|
||||||
|
value: /target
|
||||||
|
workspaces:
|
||||||
|
- name: source
|
||||||
|
workspace: git-source
|
||||||
|
- name: cargo-cache
|
||||||
|
workspace: cargo-cache
|
||||||
|
subPath: wasm-test
|
||||||
|
runAfter:
|
||||||
|
- run-image-wasm
|
||||||
|
params:
|
||||||
|
- name: docker-image
|
||||||
|
value: "$(tasks.build-image.results.IMAGE_URL[1])"
|
||||||
|
#############
|
||||||
|
finally:
|
||||||
|
- name: report-success
|
||||||
|
when:
|
||||||
|
- input: "$(tasks.status)"
|
||||||
|
operator: in
|
||||||
|
values: ["Succeeded", "Completed"]
|
||||||
|
taskRef:
|
||||||
|
resolver: git
|
||||||
|
params:
|
||||||
|
- name: url
|
||||||
|
value: https://code.fizz.buzz/mirror/catalog.git # mirror of https://github.com/tektoncd/catalog.git
|
||||||
|
- name: revision
|
||||||
|
value: df36b3853a5657fd883015cdbf07ad6466918acf
|
||||||
|
- name: pathInRepo
|
||||||
|
value: task/gitea-set-status/0.1/gitea-set-status.yaml
|
||||||
|
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:
|
||||||
|
resolver: git
|
||||||
|
params:
|
||||||
|
- name: url
|
||||||
|
value: https://code.fizz.buzz/mirror/catalog.git # mirror of https://github.com/tektoncd/catalog.git
|
||||||
|
- name: revision
|
||||||
|
value: df36b3853a5657fd883015cdbf07ad6466918acf
|
||||||
|
- name: pathInRepo
|
||||||
|
value: task/gitea-set-status/0.1/gitea-set-status.yaml
|
||||||
|
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)"
|
||||||
|
- name: cargo-cache-autoclean
|
||||||
|
taskSpec:
|
||||||
|
metadata: {}
|
||||||
|
params:
|
||||||
|
- name: docker-image
|
||||||
|
type: string
|
||||||
|
description: Docker image to run.
|
||||||
|
default: alpine:3.18
|
||||||
|
- name: cache-subdir
|
||||||
|
type: string
|
||||||
|
description: subPath used in the persistent volume for the cargo cache.
|
||||||
|
steptemplate:
|
||||||
|
image: alpine:3.18
|
||||||
|
name: ""
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: 10m
|
||||||
|
memory: 60Mi
|
||||||
|
workingDir: /workspace/source
|
||||||
|
workspaces:
|
||||||
|
- name: source
|
||||||
|
mountPath: /source
|
||||||
|
- name: cargo-cache
|
||||||
|
mountPath: /usr/local/cargo/registry
|
||||||
|
optional: true
|
||||||
|
steps:
|
||||||
|
- name: run
|
||||||
|
image: $(params.docker-image)
|
||||||
|
workingDir: "$(workspaces.source.path)"
|
||||||
|
command: ["ls", "$(workspaces.cargo-cache.path)"]
|
||||||
|
# command: [echo, $(params.cache-subdir)]
|
||||||
|
# command: [cargo, cache, --autoclean]
|
||||||
|
args: []
|
||||||
|
workspaces:
|
||||||
|
- name: source
|
||||||
|
workspace: git-source
|
||||||
|
- name: cargo-cache
|
||||||
|
workspace: cargo-cache
|
||||||
|
subPath: $(params.cache-subdir)
|
||||||
|
params:
|
||||||
|
- name: docker-image
|
||||||
|
value: "$(tasks.build-image.results.IMAGE_URL[1])"
|
||||||
|
- name: cache-subdir
|
||||||
|
value: none
|
||||||
|
# matrix:
|
||||||
|
# params:
|
||||||
|
# - name: cache-subdir
|
||||||
|
# value:
|
||||||
|
# - none
|
||||||
|
# - tracing
|
||||||
|
# - compare
|
||||||
|
# - default
|
||||||
|
# - tracing-compare
|
||||||
|
# - compare-foreign
|
||||||
|
# - all
|
||||||
|
# - wasm
|
||||||
|
# - wasm-test
|
||||||
|
workspaces:
|
||||||
|
- name: git-source
|
||||||
|
- name: docker-credentials
|
||||||
|
- name: cargo-cache
|
||||||
|
workspaces:
|
||||||
|
- name: git-source
|
||||||
|
volumeClaimTemplate:
|
||||||
|
spec:
|
||||||
|
storageClassName: "local-path"
|
||||||
|
accessModes:
|
||||||
|
- ReadWriteOnce
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
storage: 10Gi
|
||||||
|
subPath: rust-source
|
||||||
|
- name: cargo-cache
|
||||||
|
persistentVolumeClaim:
|
||||||
|
claimName: organic-cargo-cache-build
|
||||||
|
- name: docker-credentials
|
||||||
|
secret:
|
||||||
|
secretName: harbor-plain
|
||||||
|
params:
|
||||||
|
- name: image-name
|
||||||
|
value: "harbor.fizz.buzz/private/organic-development-wasm"
|
||||||
|
- name: target-name
|
||||||
|
value: "wasm"
|
||||||
|
- name: path-to-image-context
|
||||||
|
value: .
|
||||||
|
- name: path-to-dockerfile
|
||||||
|
value: docker/organic_development/
|
||||||
301
.webhook_bridge/pipeline-foreign-document-test.yaml
Normal file
301
.webhook_bridge/pipeline-foreign-document-test.yaml
Normal file
@@ -0,0 +1,301 @@
|
|||||||
|
apiVersion: tekton.dev/v1
|
||||||
|
kind: PipelineRun
|
||||||
|
metadata:
|
||||||
|
name: foreign-document-test
|
||||||
|
spec:
|
||||||
|
timeouts:
|
||||||
|
pipeline: "2h0m0s"
|
||||||
|
tasks: "1h0m40s"
|
||||||
|
finally: "0h30m0s"
|
||||||
|
taskRunTemplate:
|
||||||
|
serviceAccountName: build-bot
|
||||||
|
pipelineSpec:
|
||||||
|
params:
|
||||||
|
- name: image-name
|
||||||
|
description: The name for the built image
|
||||||
|
type: string
|
||||||
|
- name: target-name
|
||||||
|
description: The dockerfile target to build
|
||||||
|
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:
|
||||||
|
resolver: git
|
||||||
|
params:
|
||||||
|
- name: url
|
||||||
|
value: https://code.fizz.buzz/mirror/catalog.git # mirror of https://github.com/tektoncd/catalog.git
|
||||||
|
- name: revision
|
||||||
|
value: df36b3853a5657fd883015cdbf07ad6466918acf
|
||||||
|
- name: pathInRepo
|
||||||
|
value: task/gitea-set-status/0.1/gitea-set-status.yaml
|
||||||
|
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:
|
||||||
|
resolver: git
|
||||||
|
params:
|
||||||
|
- name: url
|
||||||
|
value: https://code.fizz.buzz/mirror/catalog.git # mirror of https://github.com/tektoncd/catalog.git
|
||||||
|
- name: revision
|
||||||
|
value: df36b3853a5657fd883015cdbf07ad6466918acf
|
||||||
|
- name: pathInRepo
|
||||||
|
value: task/git-clone/0.9/git-clone.yaml
|
||||||
|
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: get-git-commit-time
|
||||||
|
taskSpec:
|
||||||
|
metadata: {}
|
||||||
|
stepTemplate:
|
||||||
|
image: alpine:3.20
|
||||||
|
computeResources:
|
||||||
|
requests:
|
||||||
|
cpu: 10m
|
||||||
|
memory: 600Mi
|
||||||
|
workingDir: "$(workspaces.repo.path)"
|
||||||
|
results:
|
||||||
|
- name: unix-time
|
||||||
|
description: The time of the git commit in unix timestamp format.
|
||||||
|
steps:
|
||||||
|
- image: alpine/git:v2.34.2
|
||||||
|
name: detect-tag-step
|
||||||
|
script: |
|
||||||
|
#!/usr/bin/env sh
|
||||||
|
set -euo pipefail
|
||||||
|
echo -n "$(git log -1 --pretty=%ct)" | tee $(results.unix-time.path)
|
||||||
|
workspaces:
|
||||||
|
- name: repo
|
||||||
|
workspace: git-source
|
||||||
|
runAfter:
|
||||||
|
- fetch-repository
|
||||||
|
- name: build-image
|
||||||
|
taskRef:
|
||||||
|
resolver: git
|
||||||
|
params:
|
||||||
|
- name: url
|
||||||
|
value: https://code.fizz.buzz/talexander/personal_tekton_catalog.git
|
||||||
|
- name: revision
|
||||||
|
value: 7ee31a185243ee6da13dcd26a592c585b64c80e5
|
||||||
|
- name: pathInRepo
|
||||||
|
value: task/buildkit-rootless-daemonless/0.1/buildkit-rootless-daemonless.yaml
|
||||||
|
params:
|
||||||
|
- name: OUTPUT
|
||||||
|
value: >-
|
||||||
|
type=image,"name=$(params.image-name):latest,$(params.image-name):$(tasks.fetch-repository.results.commit)",push=true,compression=zstd,compression-level=22,oci-mediatypes=true
|
||||||
|
- name: CONTEXT
|
||||||
|
value: $(params.path-to-image-context)
|
||||||
|
- name: DOCKERFILE
|
||||||
|
value: $(params.path-to-dockerfile)
|
||||||
|
- name: EXTRA_ARGS
|
||||||
|
value:
|
||||||
|
- "--opt"
|
||||||
|
- "target=$(params.target-name)"
|
||||||
|
- --import-cache
|
||||||
|
- "type=registry,ref=$(params.image-name):buildcache"
|
||||||
|
- --export-cache
|
||||||
|
- "type=registry,ref=$(params.image-name):buildcache,mode=max,compression=zstd,compression-level=22,rewrite-timestamp=true,image-manifest=true,oci-mediatypes=true"
|
||||||
|
- --opt
|
||||||
|
- build-arg:SOURCE_DATE_EPOCH=$(tasks.get-git-commit-time.results.unix-time)
|
||||||
|
- name: BUILDKITD_TOML
|
||||||
|
value: |
|
||||||
|
debug = true
|
||||||
|
[registry."docker.io"]
|
||||||
|
mirrors = ["dockerhub.dockerhub.svc.cluster.local"]
|
||||||
|
[registry."dockerhub.dockerhub.svc.cluster.local"]
|
||||||
|
http = true
|
||||||
|
insecure = true
|
||||||
|
workspaces:
|
||||||
|
- name: source
|
||||||
|
workspace: git-source
|
||||||
|
- name: dockerconfig
|
||||||
|
workspace: docker-credentials
|
||||||
|
runAfter:
|
||||||
|
- fetch-repository
|
||||||
|
- name: run-test
|
||||||
|
taskSpec:
|
||||||
|
metadata: {}
|
||||||
|
params:
|
||||||
|
- name: docker-image
|
||||||
|
type: string
|
||||||
|
description: Docker image to run.
|
||||||
|
default: alpine:3.20
|
||||||
|
stepTemplate:
|
||||||
|
image: alpine:3.20
|
||||||
|
computeResources:
|
||||||
|
requests:
|
||||||
|
cpu: 10m
|
||||||
|
memory: 600Mi
|
||||||
|
workingDir: /workspace/source
|
||||||
|
workspaces:
|
||||||
|
- name: source
|
||||||
|
mountPath: /source
|
||||||
|
- name: cargo-cache
|
||||||
|
mountPath: /usr/local/cargo/registry
|
||||||
|
optional: true
|
||||||
|
steps:
|
||||||
|
- name: run
|
||||||
|
image: $(params.docker-image)
|
||||||
|
workingDir: "$(workspaces.source.path)"
|
||||||
|
env:
|
||||||
|
- name: CARGO_TARGET_DIR
|
||||||
|
value: /target
|
||||||
|
workspaces:
|
||||||
|
- name: source
|
||||||
|
workspace: git-source
|
||||||
|
- name: cargo-cache
|
||||||
|
workspace: cargo-cache
|
||||||
|
runAfter:
|
||||||
|
- build-image
|
||||||
|
params:
|
||||||
|
- name: docker-image
|
||||||
|
value: "$(tasks.build-image.results.IMAGE_URL[1])"
|
||||||
|
finally:
|
||||||
|
- name: report-success
|
||||||
|
when:
|
||||||
|
- input: "$(tasks.status)"
|
||||||
|
operator: in
|
||||||
|
values: ["Succeeded", "Completed"]
|
||||||
|
taskRef:
|
||||||
|
resolver: git
|
||||||
|
params:
|
||||||
|
- name: url
|
||||||
|
value: https://code.fizz.buzz/mirror/catalog.git # mirror of https://github.com/tektoncd/catalog.git
|
||||||
|
- name: revision
|
||||||
|
value: df36b3853a5657fd883015cdbf07ad6466918acf
|
||||||
|
- name: pathInRepo
|
||||||
|
value: task/gitea-set-status/0.1/gitea-set-status.yaml
|
||||||
|
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:
|
||||||
|
resolver: git
|
||||||
|
params:
|
||||||
|
- name: url
|
||||||
|
value: https://code.fizz.buzz/mirror/catalog.git # mirror of https://github.com/tektoncd/catalog.git
|
||||||
|
- name: revision
|
||||||
|
value: df36b3853a5657fd883015cdbf07ad6466918acf
|
||||||
|
- name: pathInRepo
|
||||||
|
value: task/gitea-set-status/0.1/gitea-set-status.yaml
|
||||||
|
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)"
|
||||||
|
- name: cargo-cache-autoclean
|
||||||
|
taskSpec:
|
||||||
|
metadata: {}
|
||||||
|
params:
|
||||||
|
- name: docker-image
|
||||||
|
type: string
|
||||||
|
description: Docker image to run.
|
||||||
|
default: alpine:3.20
|
||||||
|
stepTemplate:
|
||||||
|
image: alpine:3.20
|
||||||
|
computeResources:
|
||||||
|
requests:
|
||||||
|
cpu: 10m
|
||||||
|
memory: 600Mi
|
||||||
|
workingDir: /workspace/source
|
||||||
|
workspaces:
|
||||||
|
- name: source
|
||||||
|
mountPath: /source
|
||||||
|
- name: cargo-cache
|
||||||
|
mountPath: /usr/local/cargo/registry
|
||||||
|
optional: true
|
||||||
|
steps:
|
||||||
|
- name: run
|
||||||
|
image: $(params.docker-image)
|
||||||
|
workingDir: "$(workspaces.source.path)"
|
||||||
|
command: [cargo, cache, --autoclean]
|
||||||
|
args: []
|
||||||
|
workspaces:
|
||||||
|
- name: source
|
||||||
|
workspace: git-source
|
||||||
|
- name: cargo-cache
|
||||||
|
workspace: cargo-cache
|
||||||
|
params:
|
||||||
|
- name: docker-image
|
||||||
|
value: "$(tasks.build-image.results.IMAGE_URL[1])"
|
||||||
|
workspaces:
|
||||||
|
- name: git-source
|
||||||
|
- name: docker-credentials
|
||||||
|
- name: cargo-cache
|
||||||
|
workspaces:
|
||||||
|
- name: git-source
|
||||||
|
volumeClaimTemplate:
|
||||||
|
spec:
|
||||||
|
storageClassName: "local-path"
|
||||||
|
accessModes:
|
||||||
|
- ReadWriteOnce
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
storage: 10Gi
|
||||||
|
subPath: rust-source
|
||||||
|
- name: cargo-cache
|
||||||
|
persistentVolumeClaim:
|
||||||
|
claimName: organic-cargo-cache-test-foreign-document
|
||||||
|
- name: docker-credentials
|
||||||
|
secret:
|
||||||
|
secretName: harbor-plain
|
||||||
|
params:
|
||||||
|
- name: image-name
|
||||||
|
value: "harbor.fizz.buzz/private/organic-test-foreign-document"
|
||||||
|
- name: target-name
|
||||||
|
value: "foreign-document"
|
||||||
|
- name: path-to-image-context
|
||||||
|
value: docker/organic_test/
|
||||||
|
- name: path-to-dockerfile
|
||||||
|
value: docker/organic_test/
|
||||||
334
.webhook_bridge/pipeline-format.yaml
Normal file
334
.webhook_bridge/pipeline-format.yaml
Normal file
@@ -0,0 +1,334 @@
|
|||||||
|
apiVersion: tekton.dev/v1
|
||||||
|
kind: PipelineRun
|
||||||
|
metadata:
|
||||||
|
name: rust-format
|
||||||
|
spec:
|
||||||
|
timeouts:
|
||||||
|
pipeline: "2h0m0s"
|
||||||
|
tasks: "1h0m0s"
|
||||||
|
finally: "0h30m0s"
|
||||||
|
taskRunTemplate:
|
||||||
|
serviceAccountName: build-bot
|
||||||
|
pipelineSpec:
|
||||||
|
params:
|
||||||
|
- name: image-name
|
||||||
|
description: The name for the built image
|
||||||
|
type: string
|
||||||
|
- name: target-name
|
||||||
|
description: The dockerfile target to build
|
||||||
|
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:
|
||||||
|
resolver: git
|
||||||
|
params:
|
||||||
|
- name: url
|
||||||
|
value: https://code.fizz.buzz/mirror/catalog.git # mirror of https://github.com/tektoncd/catalog.git
|
||||||
|
- name: revision
|
||||||
|
value: df36b3853a5657fd883015cdbf07ad6466918acf
|
||||||
|
- name: pathInRepo
|
||||||
|
value: task/gitea-set-status/0.1/gitea-set-status.yaml
|
||||||
|
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:
|
||||||
|
resolver: git
|
||||||
|
params:
|
||||||
|
- name: url
|
||||||
|
value: https://code.fizz.buzz/mirror/catalog.git # mirror of https://github.com/tektoncd/catalog.git
|
||||||
|
- name: revision
|
||||||
|
value: df36b3853a5657fd883015cdbf07ad6466918acf
|
||||||
|
- name: pathInRepo
|
||||||
|
value: task/git-clone/0.9/git-clone.yaml
|
||||||
|
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: get-git-commit-time
|
||||||
|
taskSpec:
|
||||||
|
metadata: {}
|
||||||
|
stepTemplate:
|
||||||
|
image: alpine:3.20
|
||||||
|
computeResources:
|
||||||
|
requests:
|
||||||
|
cpu: 10m
|
||||||
|
memory: 600Mi
|
||||||
|
workingDir: "$(workspaces.repo.path)"
|
||||||
|
results:
|
||||||
|
- name: unix-time
|
||||||
|
description: The time of the git commit in unix timestamp format.
|
||||||
|
steps:
|
||||||
|
- image: alpine/git:v2.34.2
|
||||||
|
name: detect-tag-step
|
||||||
|
script: |
|
||||||
|
#!/usr/bin/env sh
|
||||||
|
set -euo pipefail
|
||||||
|
echo -n "$(git log -1 --pretty=%ct)" | tee $(results.unix-time.path)
|
||||||
|
workspaces:
|
||||||
|
- name: repo
|
||||||
|
workspace: git-source
|
||||||
|
runAfter:
|
||||||
|
- fetch-repository
|
||||||
|
- name: build-image
|
||||||
|
taskRef:
|
||||||
|
resolver: git
|
||||||
|
params:
|
||||||
|
- name: url
|
||||||
|
value: https://code.fizz.buzz/talexander/personal_tekton_catalog.git
|
||||||
|
- name: revision
|
||||||
|
value: 7ee31a185243ee6da13dcd26a592c585b64c80e5
|
||||||
|
- name: pathInRepo
|
||||||
|
value: task/buildkit-rootless-daemonless/0.1/buildkit-rootless-daemonless.yaml
|
||||||
|
params:
|
||||||
|
- name: OUTPUT
|
||||||
|
value: >-
|
||||||
|
type=image,"name=$(params.image-name):latest,$(params.image-name):$(tasks.fetch-repository.results.commit)",push=true,compression=zstd,compression-level=22,oci-mediatypes=true
|
||||||
|
- name: CONTEXT
|
||||||
|
value: $(params.path-to-image-context)
|
||||||
|
- name: DOCKERFILE
|
||||||
|
value: $(params.path-to-dockerfile)
|
||||||
|
- name: EXTRA_ARGS
|
||||||
|
value:
|
||||||
|
- "--opt"
|
||||||
|
- "target=$(params.target-name)"
|
||||||
|
- --import-cache
|
||||||
|
- "type=registry,ref=$(params.image-name):buildcache"
|
||||||
|
- --export-cache
|
||||||
|
- "type=registry,ref=$(params.image-name):buildcache,mode=max,compression=zstd,compression-level=22,rewrite-timestamp=true,image-manifest=true,oci-mediatypes=true"
|
||||||
|
- --opt
|
||||||
|
- build-arg:SOURCE_DATE_EPOCH=$(tasks.get-git-commit-time.results.unix-time)
|
||||||
|
- name: BUILDKITD_TOML
|
||||||
|
value: |
|
||||||
|
debug = true
|
||||||
|
[registry."docker.io"]
|
||||||
|
mirrors = ["dockerhub.dockerhub.svc.cluster.local"]
|
||||||
|
[registry."dockerhub.dockerhub.svc.cluster.local"]
|
||||||
|
http = true
|
||||||
|
insecure = true
|
||||||
|
workspaces:
|
||||||
|
- name: source
|
||||||
|
workspace: git-source
|
||||||
|
- name: dockerconfig
|
||||||
|
workspace: docker-credentials
|
||||||
|
runAfter:
|
||||||
|
- fetch-repository
|
||||||
|
- name: run-cargo-fmt
|
||||||
|
taskSpec:
|
||||||
|
metadata: {}
|
||||||
|
params:
|
||||||
|
- name: docker-image
|
||||||
|
type: string
|
||||||
|
description: Docker image to run.
|
||||||
|
default: alpine:3.20
|
||||||
|
stepTemplate:
|
||||||
|
image: alpine:3.20
|
||||||
|
computeResources:
|
||||||
|
requests:
|
||||||
|
cpu: 10m
|
||||||
|
memory: 600Mi
|
||||||
|
workingDir: /workspace/source
|
||||||
|
workspaces:
|
||||||
|
- name: source
|
||||||
|
mountPath: /source
|
||||||
|
- name: cargo-cache
|
||||||
|
mountPath: /usr/local/cargo/registry
|
||||||
|
optional: true
|
||||||
|
steps:
|
||||||
|
- name: run
|
||||||
|
image: $(params.docker-image)
|
||||||
|
workingDir: "$(workspaces.source.path)"
|
||||||
|
command: ["cargo", "fmt"]
|
||||||
|
args: []
|
||||||
|
env:
|
||||||
|
- name: CARGO_TARGET_DIR
|
||||||
|
value: /target
|
||||||
|
workspaces:
|
||||||
|
- name: source
|
||||||
|
workspace: git-source
|
||||||
|
- name: cargo-cache
|
||||||
|
workspace: cargo-cache
|
||||||
|
runAfter:
|
||||||
|
- build-image
|
||||||
|
params:
|
||||||
|
- name: docker-image
|
||||||
|
value: "$(tasks.build-image.results.IMAGE_URL[1])"
|
||||||
|
- name: commit-changes
|
||||||
|
taskRef:
|
||||||
|
resolver: git
|
||||||
|
params:
|
||||||
|
- name: url
|
||||||
|
value: https://code.fizz.buzz/mirror/catalog.git # mirror of https://github.com/tektoncd/catalog.git
|
||||||
|
- name: revision
|
||||||
|
value: df36b3853a5657fd883015cdbf07ad6466918acf
|
||||||
|
- name: pathInRepo
|
||||||
|
value: task/git-cli/0.4/git-cli.yaml
|
||||||
|
params:
|
||||||
|
- name: GIT_USER_NAME
|
||||||
|
value: fluxcdbot
|
||||||
|
- name: GIT_USER_EMAIL
|
||||||
|
value: "fluxcdbot@users.noreply.github.com"
|
||||||
|
- name: GIT_SCRIPT
|
||||||
|
value: |
|
||||||
|
pwd
|
||||||
|
git config --global --add safe.directory /workspace/source
|
||||||
|
git_status=$(git status --porcelain)
|
||||||
|
if [ -n "$git_status" ]; then
|
||||||
|
git commit -a -m "CI: autofix rust code."
|
||||||
|
git push origin HEAD:$(params.PULL_BASE_REF)
|
||||||
|
else
|
||||||
|
echo "No changes to commit."
|
||||||
|
fi
|
||||||
|
workspaces:
|
||||||
|
- name: source
|
||||||
|
workspace: git-source
|
||||||
|
runAfter:
|
||||||
|
- run-cargo-fmt
|
||||||
|
finally:
|
||||||
|
- name: report-success
|
||||||
|
when:
|
||||||
|
- input: "$(tasks.status)"
|
||||||
|
operator: in
|
||||||
|
values: ["Succeeded", "Completed"]
|
||||||
|
taskRef:
|
||||||
|
resolver: git
|
||||||
|
params:
|
||||||
|
- name: url
|
||||||
|
value: https://code.fizz.buzz/mirror/catalog.git # mirror of https://github.com/tektoncd/catalog.git
|
||||||
|
- name: revision
|
||||||
|
value: df36b3853a5657fd883015cdbf07ad6466918acf
|
||||||
|
- name: pathInRepo
|
||||||
|
value: task/gitea-set-status/0.1/gitea-set-status.yaml
|
||||||
|
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:
|
||||||
|
resolver: git
|
||||||
|
params:
|
||||||
|
- name: url
|
||||||
|
value: https://code.fizz.buzz/mirror/catalog.git # mirror of https://github.com/tektoncd/catalog.git
|
||||||
|
- name: revision
|
||||||
|
value: df36b3853a5657fd883015cdbf07ad6466918acf
|
||||||
|
- name: pathInRepo
|
||||||
|
value: task/gitea-set-status/0.1/gitea-set-status.yaml
|
||||||
|
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)"
|
||||||
|
- name: cargo-cache-autoclean
|
||||||
|
taskSpec:
|
||||||
|
metadata: {}
|
||||||
|
params:
|
||||||
|
- name: docker-image
|
||||||
|
type: string
|
||||||
|
description: Docker image to run.
|
||||||
|
default: alpine:3.20
|
||||||
|
stepTemplate:
|
||||||
|
image: alpine:3.20
|
||||||
|
computeResources:
|
||||||
|
requests:
|
||||||
|
cpu: 10m
|
||||||
|
memory: 600Mi
|
||||||
|
workingDir: /workspace/source
|
||||||
|
workspaces:
|
||||||
|
- name: source
|
||||||
|
mountPath: /source
|
||||||
|
- name: cargo-cache
|
||||||
|
mountPath: /usr/local/cargo/registry
|
||||||
|
optional: true
|
||||||
|
steps:
|
||||||
|
- name: run
|
||||||
|
image: $(params.docker-image)
|
||||||
|
workingDir: "$(workspaces.source.path)"
|
||||||
|
command: [cargo, cache, --autoclean]
|
||||||
|
args: []
|
||||||
|
workspaces:
|
||||||
|
- name: source
|
||||||
|
workspace: git-source
|
||||||
|
- name: cargo-cache
|
||||||
|
workspace: cargo-cache
|
||||||
|
params:
|
||||||
|
- name: docker-image
|
||||||
|
value: "$(tasks.build-image.results.IMAGE_URL[1])"
|
||||||
|
workspaces:
|
||||||
|
- name: git-source
|
||||||
|
- name: docker-credentials
|
||||||
|
- name: cargo-cache
|
||||||
|
workspaces:
|
||||||
|
- name: git-source
|
||||||
|
volumeClaimTemplate:
|
||||||
|
spec:
|
||||||
|
storageClassName: "local-path"
|
||||||
|
accessModes:
|
||||||
|
- ReadWriteOnce
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
storage: 10Gi
|
||||||
|
subPath: rust-source
|
||||||
|
- name: cargo-cache
|
||||||
|
persistentVolumeClaim:
|
||||||
|
claimName: organic-cargo-cache-fmt
|
||||||
|
- name: docker-credentials
|
||||||
|
secret:
|
||||||
|
secretName: harbor-plain
|
||||||
|
params:
|
||||||
|
- name: image-name
|
||||||
|
value: "harbor.fizz.buzz/private/organic-development-format"
|
||||||
|
- name: target-name
|
||||||
|
value: "format"
|
||||||
|
- name: path-to-image-context
|
||||||
|
value: docker/organic_development/
|
||||||
|
- name: path-to-dockerfile
|
||||||
|
value: docker/organic_development/
|
||||||
313
.webhook_bridge/pipeline-rust-clippy.yaml
Normal file
313
.webhook_bridge/pipeline-rust-clippy.yaml
Normal file
@@ -0,0 +1,313 @@
|
|||||||
|
apiVersion: tekton.dev/v1
|
||||||
|
kind: PipelineRun
|
||||||
|
metadata:
|
||||||
|
name: rust-clippy
|
||||||
|
spec:
|
||||||
|
taskRunTemplate:
|
||||||
|
serviceAccountName: build-bot
|
||||||
|
timeouts:
|
||||||
|
pipeline: "2h0m0s"
|
||||||
|
tasks: "1h0m40s"
|
||||||
|
finally: "0h30m0s"
|
||||||
|
pipelineSpec:
|
||||||
|
params:
|
||||||
|
- name: image-name
|
||||||
|
description: The name for the built image
|
||||||
|
type: string
|
||||||
|
- name: target-name
|
||||||
|
description: The dockerfile target to build
|
||||||
|
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:
|
||||||
|
resolver: git
|
||||||
|
params:
|
||||||
|
- name: url
|
||||||
|
value: https://code.fizz.buzz/mirror/catalog.git # mirror of https://github.com/tektoncd/catalog.git
|
||||||
|
- name: revision
|
||||||
|
value: df36b3853a5657fd883015cdbf07ad6466918acf
|
||||||
|
- name: pathInRepo
|
||||||
|
value: task/gitea-set-status/0.1/gitea-set-status.yaml
|
||||||
|
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:
|
||||||
|
resolver: git
|
||||||
|
params:
|
||||||
|
- name: url
|
||||||
|
value: https://code.fizz.buzz/mirror/catalog.git # mirror of https://github.com/tektoncd/catalog.git
|
||||||
|
- name: revision
|
||||||
|
value: df36b3853a5657fd883015cdbf07ad6466918acf
|
||||||
|
- name: pathInRepo
|
||||||
|
value: task/git-clone/0.9/git-clone.yaml
|
||||||
|
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: get-git-commit-time
|
||||||
|
taskSpec:
|
||||||
|
metadata: {}
|
||||||
|
stepTemplate:
|
||||||
|
image: alpine:3.20
|
||||||
|
computeResources:
|
||||||
|
requests:
|
||||||
|
cpu: 10m
|
||||||
|
memory: 600Mi
|
||||||
|
workingDir: "$(workspaces.repo.path)"
|
||||||
|
results:
|
||||||
|
- name: unix-time
|
||||||
|
description: The time of the git commit in unix timestamp format.
|
||||||
|
steps:
|
||||||
|
- image: alpine/git:v2.34.2
|
||||||
|
name: detect-tag-step
|
||||||
|
script: |
|
||||||
|
#!/usr/bin/env sh
|
||||||
|
set -euo pipefail
|
||||||
|
echo -n "$(git log -1 --pretty=%ct)" | tee $(results.unix-time.path)
|
||||||
|
workspaces:
|
||||||
|
- name: repo
|
||||||
|
workspace: git-source
|
||||||
|
runAfter:
|
||||||
|
- fetch-repository
|
||||||
|
- name: build-image
|
||||||
|
taskRef:
|
||||||
|
resolver: git
|
||||||
|
params:
|
||||||
|
- name: url
|
||||||
|
value: https://code.fizz.buzz/talexander/personal_tekton_catalog.git
|
||||||
|
- name: revision
|
||||||
|
value: 7ee31a185243ee6da13dcd26a592c585b64c80e5
|
||||||
|
- name: pathInRepo
|
||||||
|
value: task/buildkit-rootless-daemonless/0.1/buildkit-rootless-daemonless.yaml
|
||||||
|
params:
|
||||||
|
- name: OUTPUT
|
||||||
|
value: >-
|
||||||
|
type=image,"name=$(params.image-name):latest,$(params.image-name):$(tasks.fetch-repository.results.commit)",push=true,compression=zstd,compression-level=22,oci-mediatypes=true
|
||||||
|
- name: CONTEXT
|
||||||
|
value: $(params.path-to-image-context)
|
||||||
|
- name: DOCKERFILE
|
||||||
|
value: $(params.path-to-dockerfile)
|
||||||
|
- name: EXTRA_ARGS
|
||||||
|
value:
|
||||||
|
- "--opt"
|
||||||
|
- "target=$(params.target-name)"
|
||||||
|
- --import-cache
|
||||||
|
- "type=registry,ref=$(params.image-name):buildcache"
|
||||||
|
- --export-cache
|
||||||
|
- "type=registry,ref=$(params.image-name):buildcache,mode=max,compression=zstd,compression-level=22,rewrite-timestamp=true,image-manifest=true,oci-mediatypes=true"
|
||||||
|
- --opt
|
||||||
|
- build-arg:SOURCE_DATE_EPOCH=$(tasks.get-git-commit-time.results.unix-time)
|
||||||
|
- name: BUILDKITD_TOML
|
||||||
|
value: |
|
||||||
|
debug = true
|
||||||
|
[registry."docker.io"]
|
||||||
|
mirrors = ["dockerhub.dockerhub.svc.cluster.local"]
|
||||||
|
[registry."dockerhub.dockerhub.svc.cluster.local"]
|
||||||
|
http = true
|
||||||
|
insecure = true
|
||||||
|
workspaces:
|
||||||
|
- name: source
|
||||||
|
workspace: git-source
|
||||||
|
- name: dockerconfig
|
||||||
|
workspace: docker-credentials
|
||||||
|
runAfter:
|
||||||
|
- fetch-repository
|
||||||
|
- name: run-cargo-clippy
|
||||||
|
taskSpec:
|
||||||
|
metadata: {}
|
||||||
|
params:
|
||||||
|
- name: docker-image
|
||||||
|
type: string
|
||||||
|
description: Docker image to run.
|
||||||
|
default: alpine:3.20
|
||||||
|
stepTemplate:
|
||||||
|
image: alpine:3.20
|
||||||
|
computeResources:
|
||||||
|
requests:
|
||||||
|
cpu: 10m
|
||||||
|
memory: 600Mi
|
||||||
|
workingDir: /workspace/source
|
||||||
|
workspaces:
|
||||||
|
- name: source
|
||||||
|
mountPath: /source
|
||||||
|
- name: cargo-cache
|
||||||
|
mountPath: /usr/local/cargo/registry
|
||||||
|
optional: true
|
||||||
|
steps:
|
||||||
|
- name: run
|
||||||
|
image: $(params.docker-image)
|
||||||
|
workingDir: "$(workspaces.source.path)"
|
||||||
|
command:
|
||||||
|
[
|
||||||
|
"cargo",
|
||||||
|
"clippy",
|
||||||
|
"--no-deps",
|
||||||
|
"--all-targets",
|
||||||
|
"--all-features",
|
||||||
|
"--",
|
||||||
|
"-D",
|
||||||
|
"warnings",
|
||||||
|
]
|
||||||
|
args: []
|
||||||
|
env:
|
||||||
|
- name: CARGO_TARGET_DIR
|
||||||
|
value: /target
|
||||||
|
workspaces:
|
||||||
|
- name: source
|
||||||
|
workspace: git-source
|
||||||
|
- name: cargo-cache
|
||||||
|
workspace: cargo-cache
|
||||||
|
runAfter:
|
||||||
|
- build-image
|
||||||
|
params:
|
||||||
|
- name: docker-image
|
||||||
|
value: "$(tasks.build-image.results.IMAGE_URL[1])"
|
||||||
|
finally:
|
||||||
|
- name: report-success
|
||||||
|
when:
|
||||||
|
- input: "$(tasks.status)"
|
||||||
|
operator: in
|
||||||
|
values: ["Succeeded", "Completed"]
|
||||||
|
taskRef:
|
||||||
|
resolver: git
|
||||||
|
params:
|
||||||
|
- name: url
|
||||||
|
value: https://code.fizz.buzz/mirror/catalog.git # mirror of https://github.com/tektoncd/catalog.git
|
||||||
|
- name: revision
|
||||||
|
value: df36b3853a5657fd883015cdbf07ad6466918acf
|
||||||
|
- name: pathInRepo
|
||||||
|
value: task/gitea-set-status/0.1/gitea-set-status.yaml
|
||||||
|
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:
|
||||||
|
resolver: git
|
||||||
|
params:
|
||||||
|
- name: url
|
||||||
|
value: https://code.fizz.buzz/mirror/catalog.git # mirror of https://github.com/tektoncd/catalog.git
|
||||||
|
- name: revision
|
||||||
|
value: df36b3853a5657fd883015cdbf07ad6466918acf
|
||||||
|
- name: pathInRepo
|
||||||
|
value: task/gitea-set-status/0.1/gitea-set-status.yaml
|
||||||
|
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)"
|
||||||
|
- name: cargo-cache-autoclean
|
||||||
|
taskSpec:
|
||||||
|
metadata: {}
|
||||||
|
params:
|
||||||
|
- name: docker-image
|
||||||
|
type: string
|
||||||
|
description: Docker image to run.
|
||||||
|
default: alpine:3.20
|
||||||
|
stepTemplate:
|
||||||
|
image: alpine:3.20
|
||||||
|
computeResources:
|
||||||
|
requests:
|
||||||
|
cpu: 10m
|
||||||
|
memory: 600Mi
|
||||||
|
workingDir: /workspace/source
|
||||||
|
workspaces:
|
||||||
|
- name: source
|
||||||
|
mountPath: /source
|
||||||
|
- name: cargo-cache
|
||||||
|
mountPath: /usr/local/cargo/registry
|
||||||
|
optional: true
|
||||||
|
steps:
|
||||||
|
- name: run
|
||||||
|
image: $(params.docker-image)
|
||||||
|
workingDir: "$(workspaces.source.path)"
|
||||||
|
command: [cargo, cache, --autoclean]
|
||||||
|
args: []
|
||||||
|
workspaces:
|
||||||
|
- name: source
|
||||||
|
workspace: git-source
|
||||||
|
- name: cargo-cache
|
||||||
|
workspace: cargo-cache
|
||||||
|
params:
|
||||||
|
- name: docker-image
|
||||||
|
value: "$(tasks.build-image.results.IMAGE_URL[1])"
|
||||||
|
workspaces:
|
||||||
|
- name: git-source
|
||||||
|
- name: docker-credentials
|
||||||
|
- name: cargo-cache
|
||||||
|
workspaces:
|
||||||
|
- name: git-source
|
||||||
|
volumeClaimTemplate:
|
||||||
|
spec:
|
||||||
|
storageClassName: "local-path"
|
||||||
|
accessModes:
|
||||||
|
- ReadWriteOnce
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
storage: 10Gi
|
||||||
|
subPath: rust-source
|
||||||
|
- name: cargo-cache
|
||||||
|
persistentVolumeClaim:
|
||||||
|
claimName: organic-cargo-cache-clippy
|
||||||
|
- name: docker-credentials
|
||||||
|
secret:
|
||||||
|
secretName: harbor-plain
|
||||||
|
params:
|
||||||
|
- name: image-name
|
||||||
|
value: "harbor.fizz.buzz/private/organic-development-clippy"
|
||||||
|
- name: target-name
|
||||||
|
value: "clippy"
|
||||||
|
- name: path-to-image-context
|
||||||
|
value: docker/organic_development/
|
||||||
|
- name: path-to-dockerfile
|
||||||
|
value: docker/organic_development/
|
||||||
312
.webhook_bridge/pipeline-rust-test.yaml
Normal file
312
.webhook_bridge/pipeline-rust-test.yaml
Normal file
@@ -0,0 +1,312 @@
|
|||||||
|
apiVersion: tekton.dev/v1
|
||||||
|
kind: PipelineRun
|
||||||
|
metadata:
|
||||||
|
name: rust-test
|
||||||
|
spec:
|
||||||
|
timeouts:
|
||||||
|
pipeline: "2h0m0s"
|
||||||
|
tasks: "1h0m40s"
|
||||||
|
finally: "0h30m0s"
|
||||||
|
taskRunTemplate:
|
||||||
|
serviceAccountName: build-bot
|
||||||
|
pipelineSpec:
|
||||||
|
params:
|
||||||
|
- name: image-name
|
||||||
|
description: The name for the built image
|
||||||
|
type: string
|
||||||
|
- name: target-name
|
||||||
|
description: The dockerfile target to build
|
||||||
|
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:
|
||||||
|
resolver: git
|
||||||
|
params:
|
||||||
|
- name: url
|
||||||
|
value: https://code.fizz.buzz/mirror/catalog.git # mirror of https://github.com/tektoncd/catalog.git
|
||||||
|
- name: revision
|
||||||
|
value: df36b3853a5657fd883015cdbf07ad6466918acf
|
||||||
|
- name: pathInRepo
|
||||||
|
value: task/gitea-set-status/0.1/gitea-set-status.yaml
|
||||||
|
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:
|
||||||
|
resolver: git
|
||||||
|
params:
|
||||||
|
- name: url
|
||||||
|
value: https://code.fizz.buzz/mirror/catalog.git # mirror of https://github.com/tektoncd/catalog.git
|
||||||
|
- name: revision
|
||||||
|
value: df36b3853a5657fd883015cdbf07ad6466918acf
|
||||||
|
- name: pathInRepo
|
||||||
|
value: task/git-clone/0.9/git-clone.yaml
|
||||||
|
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: get-git-commit-time
|
||||||
|
taskSpec:
|
||||||
|
metadata: {}
|
||||||
|
stepTemplate:
|
||||||
|
image: alpine:3.20
|
||||||
|
computeResources:
|
||||||
|
requests:
|
||||||
|
cpu: 10m
|
||||||
|
memory: 600Mi
|
||||||
|
workingDir: "$(workspaces.repo.path)"
|
||||||
|
results:
|
||||||
|
- name: unix-time
|
||||||
|
description: The time of the git commit in unix timestamp format.
|
||||||
|
steps:
|
||||||
|
- image: alpine/git:v2.34.2
|
||||||
|
name: detect-tag-step
|
||||||
|
script: |
|
||||||
|
#!/usr/bin/env sh
|
||||||
|
set -euo pipefail
|
||||||
|
echo -n "$(git log -1 --pretty=%ct)" | tee $(results.unix-time.path)
|
||||||
|
workspaces:
|
||||||
|
- name: repo
|
||||||
|
workspace: git-source
|
||||||
|
runAfter:
|
||||||
|
- fetch-repository
|
||||||
|
- name: build-image
|
||||||
|
taskRef:
|
||||||
|
resolver: git
|
||||||
|
params:
|
||||||
|
- name: url
|
||||||
|
value: https://code.fizz.buzz/talexander/personal_tekton_catalog.git
|
||||||
|
- name: revision
|
||||||
|
value: 7ee31a185243ee6da13dcd26a592c585b64c80e5
|
||||||
|
- name: pathInRepo
|
||||||
|
value: task/buildkit-rootless-daemonless/0.1/buildkit-rootless-daemonless.yaml
|
||||||
|
params:
|
||||||
|
- name: OUTPUT
|
||||||
|
value: >-
|
||||||
|
type=image,"name=$(params.image-name):latest,$(params.image-name):$(tasks.fetch-repository.results.commit)",push=true,compression=zstd,compression-level=22,oci-mediatypes=true
|
||||||
|
- name: CONTEXT
|
||||||
|
value: $(params.path-to-image-context)
|
||||||
|
- name: DOCKERFILE
|
||||||
|
value: $(params.path-to-dockerfile)
|
||||||
|
- name: EXTRA_ARGS
|
||||||
|
value:
|
||||||
|
- "--opt"
|
||||||
|
- "target=$(params.target-name)"
|
||||||
|
- --import-cache
|
||||||
|
- "type=registry,ref=$(params.image-name):buildcache"
|
||||||
|
- --export-cache
|
||||||
|
- "type=registry,ref=$(params.image-name):buildcache,mode=max,compression=zstd,compression-level=22,rewrite-timestamp=true,image-manifest=true,oci-mediatypes=true"
|
||||||
|
- --opt
|
||||||
|
- build-arg:SOURCE_DATE_EPOCH=$(tasks.get-git-commit-time.results.unix-time)
|
||||||
|
- name: BUILDKITD_TOML
|
||||||
|
value: |
|
||||||
|
debug = true
|
||||||
|
[registry."docker.io"]
|
||||||
|
mirrors = ["dockerhub.dockerhub.svc.cluster.local"]
|
||||||
|
[registry."dockerhub.dockerhub.svc.cluster.local"]
|
||||||
|
http = true
|
||||||
|
insecure = true
|
||||||
|
workspaces:
|
||||||
|
- name: source
|
||||||
|
workspace: git-source
|
||||||
|
- name: dockerconfig
|
||||||
|
workspace: docker-credentials
|
||||||
|
runAfter:
|
||||||
|
- fetch-repository
|
||||||
|
- name: run-cargo-test
|
||||||
|
taskSpec:
|
||||||
|
metadata: {}
|
||||||
|
params:
|
||||||
|
- name: docker-image
|
||||||
|
type: string
|
||||||
|
description: Docker image to run.
|
||||||
|
default: alpine:3.20
|
||||||
|
stepTemplate:
|
||||||
|
image: alpine:3.20
|
||||||
|
computeResources:
|
||||||
|
requests:
|
||||||
|
cpu: 10m
|
||||||
|
memory: 600Mi
|
||||||
|
workingDir: /workspace/source
|
||||||
|
workspaces:
|
||||||
|
- name: source
|
||||||
|
mountPath: /source
|
||||||
|
- name: cargo-cache
|
||||||
|
mountPath: /usr/local/cargo/registry
|
||||||
|
optional: true
|
||||||
|
steps:
|
||||||
|
- name: run
|
||||||
|
image: $(params.docker-image)
|
||||||
|
workingDir: "$(workspaces.source.path)"
|
||||||
|
command: [cargo, test]
|
||||||
|
args:
|
||||||
|
[
|
||||||
|
--no-default-features,
|
||||||
|
--features,
|
||||||
|
"compare,wasm_test",
|
||||||
|
--no-fail-fast,
|
||||||
|
--lib,
|
||||||
|
--test,
|
||||||
|
test_loader,
|
||||||
|
]
|
||||||
|
env:
|
||||||
|
- name: CARGO_TARGET_DIR
|
||||||
|
value: /target
|
||||||
|
workspaces:
|
||||||
|
- name: source
|
||||||
|
workspace: git-source
|
||||||
|
- name: cargo-cache
|
||||||
|
workspace: cargo-cache
|
||||||
|
runAfter:
|
||||||
|
- build-image
|
||||||
|
params:
|
||||||
|
- name: docker-image
|
||||||
|
value: "$(tasks.build-image.results.IMAGE_URL[1])"
|
||||||
|
finally:
|
||||||
|
- name: report-success
|
||||||
|
when:
|
||||||
|
- input: "$(tasks.status)"
|
||||||
|
operator: in
|
||||||
|
values: ["Succeeded", "Completed"]
|
||||||
|
taskRef:
|
||||||
|
resolver: git
|
||||||
|
params:
|
||||||
|
- name: url
|
||||||
|
value: https://code.fizz.buzz/mirror/catalog.git # mirror of https://github.com/tektoncd/catalog.git
|
||||||
|
- name: revision
|
||||||
|
value: df36b3853a5657fd883015cdbf07ad6466918acf
|
||||||
|
- name: pathInRepo
|
||||||
|
value: task/gitea-set-status/0.1/gitea-set-status.yaml
|
||||||
|
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:
|
||||||
|
resolver: git
|
||||||
|
params:
|
||||||
|
- name: url
|
||||||
|
value: https://code.fizz.buzz/mirror/catalog.git # mirror of https://github.com/tektoncd/catalog.git
|
||||||
|
- name: revision
|
||||||
|
value: df36b3853a5657fd883015cdbf07ad6466918acf
|
||||||
|
- name: pathInRepo
|
||||||
|
value: task/gitea-set-status/0.1/gitea-set-status.yaml
|
||||||
|
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)"
|
||||||
|
- name: cargo-cache-autoclean
|
||||||
|
taskSpec:
|
||||||
|
metadata: {}
|
||||||
|
params:
|
||||||
|
- name: docker-image
|
||||||
|
type: string
|
||||||
|
description: Docker image to run.
|
||||||
|
default: alpine:3.20
|
||||||
|
stepTemplate:
|
||||||
|
image: alpine:3.20
|
||||||
|
computeResources:
|
||||||
|
requests:
|
||||||
|
cpu: 10m
|
||||||
|
memory: 600Mi
|
||||||
|
workingDir: /workspace/source
|
||||||
|
workspaces:
|
||||||
|
- name: source
|
||||||
|
mountPath: /source
|
||||||
|
- name: cargo-cache
|
||||||
|
mountPath: /usr/local/cargo/registry
|
||||||
|
optional: true
|
||||||
|
steps:
|
||||||
|
- name: run
|
||||||
|
image: $(params.docker-image)
|
||||||
|
workingDir: "$(workspaces.source.path)"
|
||||||
|
command: [cargo, cache, --autoclean]
|
||||||
|
args: []
|
||||||
|
workspaces:
|
||||||
|
- name: source
|
||||||
|
workspace: git-source
|
||||||
|
- name: cargo-cache
|
||||||
|
workspace: cargo-cache
|
||||||
|
params:
|
||||||
|
- name: docker-image
|
||||||
|
value: "$(tasks.build-image.results.IMAGE_URL[1])"
|
||||||
|
workspaces:
|
||||||
|
- name: git-source
|
||||||
|
- name: docker-credentials
|
||||||
|
- name: cargo-cache
|
||||||
|
workspaces:
|
||||||
|
- name: git-source
|
||||||
|
volumeClaimTemplate:
|
||||||
|
spec:
|
||||||
|
storageClassName: "local-path"
|
||||||
|
accessModes:
|
||||||
|
- ReadWriteOnce
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
storage: 10Gi
|
||||||
|
subPath: rust-source
|
||||||
|
- name: cargo-cache
|
||||||
|
persistentVolumeClaim:
|
||||||
|
claimName: organic-cargo-cache-test
|
||||||
|
- name: docker-credentials
|
||||||
|
secret:
|
||||||
|
secretName: harbor-plain
|
||||||
|
params:
|
||||||
|
- name: image-name
|
||||||
|
value: "harbor.fizz.buzz/private/organic-test"
|
||||||
|
- name: target-name
|
||||||
|
value: "tester"
|
||||||
|
- name: path-to-image-context
|
||||||
|
value: docker/organic_test/
|
||||||
|
- name: path-to-dockerfile
|
||||||
|
value: docker/organic_test/
|
||||||
31
.webhook_bridge/webhook_bridge.toml
Normal file
31
.webhook_bridge/webhook_bridge.toml
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
version = "0.0.1"
|
||||||
|
|
||||||
|
[[push]]
|
||||||
|
name = "rust-test"
|
||||||
|
source = "pipeline-rust-test.yaml"
|
||||||
|
clone_uri = "git@code.fizz.buzz:talexander/organic.git"
|
||||||
|
skip_branches = [ "^v[0-9]+\\.[0-9]+\\.[0-9]+$" ]
|
||||||
|
|
||||||
|
[[push]]
|
||||||
|
name = "foreign-document-test"
|
||||||
|
source = "pipeline-foreign-document-test.yaml"
|
||||||
|
clone_uri = "git@code.fizz.buzz:talexander/organic.git"
|
||||||
|
branches = [ "^main$", "^master$" ]
|
||||||
|
|
||||||
|
[[push]]
|
||||||
|
name = "clippy"
|
||||||
|
source = "pipeline-rust-clippy.yaml"
|
||||||
|
clone_uri = "git@code.fizz.buzz:talexander/organic.git"
|
||||||
|
skip_branches = [ "^v[0-9]+\\.[0-9]+\\.[0-9]+$" ]
|
||||||
|
|
||||||
|
[[push]]
|
||||||
|
name = "format"
|
||||||
|
source = "pipeline-format.yaml"
|
||||||
|
clone_uri = "git@code.fizz.buzz:talexander/organic.git"
|
||||||
|
skip_branches = [ "^v[0-9]+\\.[0-9]+\\.[0-9]+$" ]
|
||||||
|
|
||||||
|
[[push]]
|
||||||
|
name = "build"
|
||||||
|
source = "pipeline-build-hash.yaml"
|
||||||
|
clone_uri = "git@code.fizz.buzz:talexander/organic.git"
|
||||||
|
branches = [ "^main$", "^master$" ]
|
||||||
33
Cargo.toml
33
Cargo.toml
@@ -1,8 +1,9 @@
|
|||||||
# cargo-features = ["profile-rustflags"]
|
# cargo-features = ["profile-rustflags"]
|
||||||
|
cargo-features = ["codegen-backend"]
|
||||||
|
|
||||||
[package]
|
[package]
|
||||||
name = "organic"
|
name = "organic"
|
||||||
version = "0.1.12"
|
version = "0.1.16"
|
||||||
authors = ["Tom Alexander <tom@fizz.buzz>"]
|
authors = ["Tom Alexander <tom@fizz.buzz>"]
|
||||||
description = "An org-mode parser."
|
description = "An org-mode parser."
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
@@ -39,17 +40,33 @@ path = "src/lib.rs"
|
|||||||
path = "src/bin_foreign_document_test.rs"
|
path = "src/bin_foreign_document_test.rs"
|
||||||
required-features = ["foreign_document_test"]
|
required-features = ["foreign_document_test"]
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "wasm"
|
||||||
|
path = "src/bin_wasm.rs"
|
||||||
|
required-features = ["wasm"]
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
# This bin exists for development purposes only. The real target of this crate is the library.
|
||||||
|
name = "wasm_test"
|
||||||
|
path = "src/bin_wasm_test.rs"
|
||||||
|
required-features = ["wasm_test"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
futures = { version = "0.3.28", optional = true }
|
futures = { version = "0.3.28", optional = true }
|
||||||
|
gloo-utils = "0.2.0"
|
||||||
nom = "7.1.1"
|
nom = "7.1.1"
|
||||||
opentelemetry = { version = "0.20.0", optional = true, default-features = false, features = ["trace", "rt-tokio"] }
|
opentelemetry = { version = "0.20.0", optional = true, default-features = false, features = ["trace", "rt-tokio"] }
|
||||||
opentelemetry-otlp = { version = "0.13.0", optional = true }
|
opentelemetry-otlp = { version = "0.13.0", optional = true }
|
||||||
opentelemetry-semantic-conventions = { version = "0.12.0", optional = true }
|
opentelemetry-semantic-conventions = { version = "0.12.0", optional = true }
|
||||||
|
serde = { version = "1.0.193", optional = true, features = ["derive"] }
|
||||||
|
serde-wasm-bindgen = { version = "0.6.3", optional = true }
|
||||||
|
serde_json = { version = "1.0.108", optional = true }
|
||||||
tokio = { version = "1.30.0", optional = true, default-features = false, features = ["rt", "rt-multi-thread"] }
|
tokio = { version = "1.30.0", optional = true, default-features = false, features = ["rt", "rt-multi-thread"] }
|
||||||
tracing = { version = "0.1.37", optional = true }
|
tracing = { version = "0.1.37", optional = true }
|
||||||
tracing-opentelemetry = { version = "0.20.0", optional = true }
|
tracing-opentelemetry = { version = "0.20.0", optional = true }
|
||||||
tracing-subscriber = { version = "0.3.17", optional = true, features = ["env-filter"] }
|
tracing-subscriber = { version = "0.3.17", optional = true, features = ["env-filter"] }
|
||||||
walkdir = { version = "2.3.3", optional = true }
|
walkdir = { version = "2.3.3", optional = true }
|
||||||
|
wasm-bindgen = { version = "0.2.89", optional = true }
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
walkdir = "2.3.3"
|
walkdir = "2.3.3"
|
||||||
@@ -60,6 +77,8 @@ compare = ["tokio/process", "tokio/macros"]
|
|||||||
foreign_document_test = ["compare", "dep:futures", "tokio/sync", "dep:walkdir", "tokio/process"]
|
foreign_document_test = ["compare", "dep:futures", "tokio/sync", "dep:walkdir", "tokio/process"]
|
||||||
tracing = ["dep:opentelemetry", "dep:opentelemetry-otlp", "dep:opentelemetry-semantic-conventions", "dep:tokio", "dep:tracing", "dep:tracing-opentelemetry", "dep:tracing-subscriber"]
|
tracing = ["dep:opentelemetry", "dep:opentelemetry-otlp", "dep:opentelemetry-semantic-conventions", "dep:tokio", "dep:tracing", "dep:tracing-opentelemetry", "dep:tracing-subscriber"]
|
||||||
event_count = []
|
event_count = []
|
||||||
|
wasm = ["dep:serde", "dep:wasm-bindgen", "dep:serde-wasm-bindgen"]
|
||||||
|
wasm_test = ["wasm", "dep:serde_json", "tokio/process", "tokio/macros"]
|
||||||
|
|
||||||
# Optimized build for any sort of release.
|
# Optimized build for any sort of release.
|
||||||
[profile.release-lto]
|
[profile.release-lto]
|
||||||
@@ -79,3 +98,15 @@ strip = "symbols"
|
|||||||
inherits = "release"
|
inherits = "release"
|
||||||
lto = true
|
lto = true
|
||||||
debug = true
|
debug = true
|
||||||
|
|
||||||
|
[profile.wasm]
|
||||||
|
inherits = "release"
|
||||||
|
lto = true
|
||||||
|
strip = true
|
||||||
|
|
||||||
|
[profile.dev]
|
||||||
|
codegen-backend = "cranelift"
|
||||||
|
|
||||||
|
[profile.dev.package."*"]
|
||||||
|
codegen-backend = "llvm"
|
||||||
|
opt-level = 3
|
||||||
|
|||||||
65
Makefile
65
Makefile
@@ -7,6 +7,7 @@ MAKEFLAGS += --no-builtin-rules
|
|||||||
TESTJOBS := 4
|
TESTJOBS := 4
|
||||||
OS:=$(shell uname -s)
|
OS:=$(shell uname -s)
|
||||||
RELEASEFLAGS :=
|
RELEASEFLAGS :=
|
||||||
|
WASMTARGET := bundler # or web
|
||||||
|
|
||||||
ifeq ($(OS),Linux)
|
ifeq ($(OS),Linux)
|
||||||
TESTJOBS:=$(shell nproc)
|
TESTJOBS:=$(shell nproc)
|
||||||
@@ -21,51 +22,83 @@ ifeq ($(origin .RECIPEPREFIX), undefined)
|
|||||||
endif
|
endif
|
||||||
.RECIPEPREFIX = >
|
.RECIPEPREFIX = >
|
||||||
|
|
||||||
|
.PHONY: help
|
||||||
|
help: ## List the available make targets.
|
||||||
|
> @grep -h "##" $(MAKEFILE_LIST) | grep -v grep | sed -E 's/^([^:]*): *## */\1: /'
|
||||||
|
|
||||||
.PHONY: build
|
.PHONY: build
|
||||||
build:
|
build: ## Make a debug build of the project.
|
||||||
> cargo build
|
> cargo build
|
||||||
|
|
||||||
.PHONY: release
|
.PHONY: release
|
||||||
release:
|
release: ## Make an optimized build of the project.
|
||||||
> cargo build --release $(RELEASEFLAGS)
|
> cargo build --release $(RELEASEFLAGS)
|
||||||
|
|
||||||
|
.PHONY: wasm
|
||||||
|
wasm: ## Build the parser as wasm.
|
||||||
|
> cargo build --target=wasm32-unknown-unknown --profile wasm --bin wasm --features wasm
|
||||||
|
> wasm-bindgen --target $(WASMTARGET) --out-dir target/wasm32-unknown-unknown/js target/wasm32-unknown-unknown/wasm/wasm.wasm
|
||||||
|
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
clean:
|
clean: ## Delete the built binaries.
|
||||||
> cargo clean
|
> cargo clean
|
||||||
|
> $(MAKE) -C docker/organic_development TARGET=builder clean
|
||||||
|
> $(MAKE) -C docker/organic_development TARGET=format clean
|
||||||
|
> $(MAKE) -C docker/organic_development TARGET=clippy clean
|
||||||
|
> $(MAKE) -C docker/organic_development TARGET=wasm clean
|
||||||
|
> $(MAKE) -C docker/organic_test TARGET=tester build
|
||||||
|
|
||||||
.PHONY: format
|
.PHONY: format
|
||||||
format:
|
format: ## Format the code.
|
||||||
> $(MAKE) -C docker/cargo_fmt run
|
> cargo fmt
|
||||||
|
|
||||||
.PHONY: dockerclippy
|
.PHONY: docker_format
|
||||||
dockerclippy:
|
docker_format: ## Format the code using docker.
|
||||||
> $(MAKE) -C docker/organic_clippy run
|
> $(MAKE) -C docker/organic_development TARGET=format build
|
||||||
|
> docker run --rm -i -t --mount type=tmpfs,destination=/tmp -v "$(shell readlink -f .):/source" --workdir=/source --env CARGO_TARGET_DIR=/target -v "organic-cargo-registry:/usr/local/cargo/registry" organic-development-format cargo fmt
|
||||||
|
|
||||||
|
.PHONY: docker_clippy
|
||||||
|
docker_clippy: ## Lint the code using docker.
|
||||||
|
> $(MAKE) -C docker/organic_development TARGET=clippy build
|
||||||
|
> docker run --rm -i -t --mount type=tmpfs,destination=/tmp -v "$(shell readlink -f .):/source" --workdir=/source --env CARGO_TARGET_DIR=/target -v "organic-cargo-registry:/usr/local/cargo/registry" organic-development-clippy cargo clippy --no-deps --all-targets --all-features -- -D warnings
|
||||||
|
|
||||||
.PHONY: clippy
|
.PHONY: clippy
|
||||||
clippy:
|
clippy: ## Lint the code.
|
||||||
> cargo clippy --no-deps --all-targets --all-features -- -D warnings
|
> cargo clippy --no-deps --all-targets --all-features -- -D warnings
|
||||||
|
|
||||||
.PHONY: test
|
.PHONY: test
|
||||||
test:
|
test: ## Run the test suite.
|
||||||
> cargo test --no-default-features --features compare --no-fail-fast --lib --test test_loader -- --test-threads $(TESTJOBS)
|
> cargo test --no-default-features --features compare --no-fail-fast --lib --test test_loader -- --test-threads $(TESTJOBS)
|
||||||
|
|
||||||
.PHONY: dockertest
|
.PHONY: doc
|
||||||
dockertest:
|
doc: ## Generate documentation.
|
||||||
> $(MAKE) -C docker/organic_test
|
> cargo doc --no-deps --open --lib --release --all-features
|
||||||
|
|
||||||
|
.PHONY: docker_test
|
||||||
|
docker_test: ## Run the test suite using docker.
|
||||||
|
> $(MAKE) -C docker/organic_test TARGET=tester build
|
||||||
> docker run --init --rm -i -t --read-only -v "$$(readlink -f ./):/source:ro" --mount type=tmpfs,destination=/tmp --mount source=cargo-cache,target=/usr/local/cargo/registry --mount source=rust-cache,target=/target --env CARGO_TARGET_DIR=/target -w /source organic-test --no-default-features --features compare --no-fail-fast --lib --test test_loader -- --test-threads $(TESTJOBS)
|
> docker run --init --rm -i -t --read-only -v "$$(readlink -f ./):/source:ro" --mount type=tmpfs,destination=/tmp --mount source=cargo-cache,target=/usr/local/cargo/registry --mount source=rust-cache,target=/target --env CARGO_TARGET_DIR=/target -w /source organic-test --no-default-features --features compare --no-fail-fast --lib --test test_loader -- --test-threads $(TESTJOBS)
|
||||||
|
|
||||||
.PHONY: buildtest
|
.PHONY: docker_wasm_test
|
||||||
buildtest:
|
docker_wasm_test: ## Run the test suite with wasm tests.
|
||||||
|
> $(MAKE) -C docker/organic_test TARGET=tester build
|
||||||
|
> docker run --init --rm -i -t --read-only -v "$$(readlink -f ./):/source:ro" --mount type=tmpfs,destination=/tmp --mount source=cargo-cache,target=/usr/local/cargo/registry --mount source=rust-cache,target=/target --env CARGO_TARGET_DIR=/target -w /source organic-test --no-default-features --features compare,wasm_test --no-fail-fast --lib --test test_loader autogen_wasm_ -- --test-threads $(TESTJOBS)
|
||||||
|
|
||||||
|
.PHONY: build_test
|
||||||
|
build_test:
|
||||||
> cargo build --no-default-features
|
> cargo build --no-default-features
|
||||||
> cargo build --no-default-features --features compare
|
> cargo build --no-default-features --features compare
|
||||||
> cargo build --no-default-features --features tracing
|
> cargo build --no-default-features --features tracing
|
||||||
> cargo build --no-default-features --features compare,tracing
|
> cargo build --no-default-features --features compare,tracing
|
||||||
> cargo build --no-default-features --features compare,foreign_document_test
|
> cargo build --no-default-features --features compare,foreign_document_test
|
||||||
> cargo build --no-default-features --features compare,tracing,foreign_document_test
|
> cargo build --no-default-features --features compare,tracing,foreign_document_test
|
||||||
|
> cargo build --target wasm32-unknown-unknown --profile wasm --bin wasm --no-default-features --features wasm
|
||||||
|
> cargo build --bin wasm_test --no-default-features --features wasm_test
|
||||||
|
|
||||||
.PHONY: foreign_document_test
|
.PHONY: foreign_document_test
|
||||||
foreign_document_test:
|
foreign_document_test:
|
||||||
> $(MAKE) -C docker/organic_test run_foreign_document_test
|
> $(MAKE) -C docker/organic_test TARGET=foreign-document build
|
||||||
|
> docker run --init --rm -i -t --read-only -v "$$(readlink -f ./):/source:ro" --mount type=tmpfs,destination=/tmp --mount source=cargo-cache,target=/usr/local/cargo/registry --mount source=rust-cache,target=/target --env CARGO_TARGET_DIR=/target -w /source organic-test-foreign-document
|
||||||
|
|
||||||
.PHONY: dockerclean
|
.PHONY: dockerclean
|
||||||
dockerclean:
|
dockerclean:
|
||||||
|
|||||||
@@ -10,17 +10,16 @@ Currently, Organic parses most documents the same as the official org-mode parse
|
|||||||
|
|
||||||
### Project Goals
|
### Project Goals
|
||||||
- We aim to provide perfect parity with the emacs org-mode parser. In that regard, any document that parses differently between Emacs and Organic is considered a bug.
|
- We aim to provide perfect parity with the emacs org-mode parser. In that regard, any document that parses differently between Emacs and Organic is considered a bug.
|
||||||
- The parser should have minimal dependencies. This should reduce effort w.r.t.: security audits, legal compliance, portability.
|
- The parser should have minimal dependencies.
|
||||||
- The parser should be usable everywhere. In the interest of getting org-mode used in as many places as possible, this parser should be usable by everyone everywhere. This means:
|
- The parser should be usable everywhere. In the interest of getting org used in as many places as possible, this parser should be usable by everyone everywhere. This means:
|
||||||
- It must have a permissive license.
|
- It must have a permissive license.
|
||||||
- We will investigate compiling to WASM. This is an important goal of the project and will definitely happen, but only after the parser has a more stable API.
|
- It compiles to both natively and to wasm.
|
||||||
- We will investigate compiling to a C library for native linking to other code. This is more of a maybe-goal for the project.
|
- We will investigate compiling to a C library for native linking to other code. This is more of a maybe-goal for the project.
|
||||||
### Project Non-Goals
|
### Project Non-Goals
|
||||||
- This project will not include an elisp engine since that would drastically increase the complexity of the code. Any features requiring an elisp engine will not be implemented (for example, Emacs supports embedded eval expressions in documents but this parser will never support that).
|
- This project will not include an elisp engine since that would drastically increase the complexity of the code. Any features requiring an elisp engine will not be implemented (for example, Emacs supports embedded eval expressions in documents but this parser will never support that).
|
||||||
- This project is exclusively an org-mode **parser**. This limits its scope to roughly the output of `(org-element-parse-buffer)`. It will not render org-mode documents in other formats like HTML or LaTeX.
|
- This project is exclusively an org-mode **parser**. This limits its scope to roughly the output of `(org-element-parse-buffer)`. It will not render org-mode documents in other formats like HTML or LaTeX.
|
||||||
### Project Maybe-Goals
|
### Project Maybe-Goals
|
||||||
- table.el support. Currently we support org-mode tables but org-mode also allows table.el tables. So far, their use in org-mode documents seems rather uncommon so this is a low-priority feature.
|
- table.el support. Currently we support org-mode tables but org-mode also allows table.el tables. So far, their use in org-mode documents seems rather uncommon so this is a low-priority feature.
|
||||||
- Document editing support. I do not anticipate any advanced editing features to make editing ergonomic, but it should be relatively easy to be able to parse an org-mode document and serialize it back into org-mode. This would enable cool features to be built on top of the library like auto-formatters. To accomplish this feature, We'd have to capture all of the various separators and whitespace that we are currently simply throwing away. This would add many additional fields to the parsed structs and it would add more noise to the parsers themselves, so I do not want to approach this feature until the parser is more complete since it would make modifications and refactoring more difficult.
|
|
||||||
### Supported Versions
|
### Supported Versions
|
||||||
This project targets the version of Emacs and Org-mode that are built into the [organic-test docker image](docker/organic_test/Dockerfile). This is newer than the version of Org-mode that shipped with Emacs 29.1. The parser itself does not depend on Emacs or Org-mode though, so this only matters for development purposes when running the automated tests that compare against upstream Org-mode.
|
This project targets the version of Emacs and Org-mode that are built into the [organic-test docker image](docker/organic_test/Dockerfile). This is newer than the version of Org-mode that shipped with Emacs 29.1. The parser itself does not depend on Emacs or Org-mode though, so this only matters for development purposes when running the automated tests that compare against upstream Org-mode.
|
||||||
|
|
||||||
|
|||||||
2
build.rs
2
build.rs
@@ -26,7 +26,7 @@ fn main() {
|
|||||||
dir_entry.file_type().is_file()
|
dir_entry.file_type().is_file()
|
||||||
&& Path::new(dir_entry.file_name())
|
&& Path::new(dir_entry.file_name())
|
||||||
.extension()
|
.extension()
|
||||||
.map(|ext| ext.to_ascii_lowercase() == "org")
|
.map(|ext| ext.eq_ignore_ascii_case("org"))
|
||||||
.unwrap_or(false)
|
.unwrap_or(false)
|
||||||
}
|
}
|
||||||
Err(_) => true,
|
Err(_) => true,
|
||||||
|
|||||||
@@ -1,6 +0,0 @@
|
|||||||
FROM rustlang/rust:nightly-alpine3.17
|
|
||||||
|
|
||||||
RUN apk add --no-cache musl-dev
|
|
||||||
RUN rustup component add rustfmt
|
|
||||||
|
|
||||||
ENTRYPOINT ["cargo", "fmt"]
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
IMAGE_NAME:=cargo-fmt
|
|
||||||
# REMOTE_REPO:=harbor.fizz.buzz/private
|
|
||||||
|
|
||||||
.PHONY: all
|
|
||||||
all: build push
|
|
||||||
|
|
||||||
.PHONY: build
|
|
||||||
build:
|
|
||||||
docker build -t $(IMAGE_NAME) -f Dockerfile .
|
|
||||||
|
|
||||||
.PHONY: push
|
|
||||||
push:
|
|
||||||
ifdef REMOTE_REPO
|
|
||||||
docker tag $(IMAGE_NAME) $(REMOTE_REPO)/$(IMAGE_NAME)
|
|
||||||
docker push $(REMOTE_REPO)/$(IMAGE_NAME)
|
|
||||||
else
|
|
||||||
@echo "REMOTE_REPO not defined, not pushing to a remote repo."
|
|
||||||
endif
|
|
||||||
|
|
||||||
.PHONY: clean
|
|
||||||
clean:
|
|
||||||
docker rmi $(IMAGE_NAME)
|
|
||||||
ifdef REMOTE_REPO
|
|
||||||
docker rmi $(REMOTE_REPO)/$(IMAGE_NAME)
|
|
||||||
else
|
|
||||||
@echo "REMOTE_REPO not defined, not removing from remote repo."
|
|
||||||
endif
|
|
||||||
|
|
||||||
# NOTE: This target will write to folders underneath the git-root
|
|
||||||
.PHONY: run
|
|
||||||
run: build
|
|
||||||
docker run --rm --init --read-only --mount type=tmpfs,destination=/tmp -v "$$(readlink -f ../../):/source" --workdir=/source $(IMAGE_NAME)
|
|
||||||
|
|
||||||
.PHONY: shell
|
|
||||||
shell: build
|
|
||||||
docker run --rm -i -t --entrypoint /bin/sh --mount type=tmpfs,destination=/tmp -v "$$(readlink -f ../../):/source" --workdir=/source $(IMAGE_NAME)
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
FROM rustlang/rust:nightly-alpine3.17
|
|
||||||
|
|
||||||
RUN apk add --no-cache musl-dev
|
|
||||||
RUN cargo install --locked --no-default-features --features ci-autoclean cargo-cache
|
|
||||||
|
|
||||||
ENTRYPOINT ["cargo", "build"]
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
IMAGE_NAME:=organic-build
|
|
||||||
# REMOTE_REPO:=harbor.fizz.buzz/private
|
|
||||||
|
|
||||||
.PHONY: all
|
|
||||||
all: build push
|
|
||||||
|
|
||||||
.PHONY: build
|
|
||||||
build:
|
|
||||||
docker build -t $(IMAGE_NAME) -f Dockerfile .
|
|
||||||
|
|
||||||
.PHONY: push
|
|
||||||
push:
|
|
||||||
ifdef REMOTE_REPO
|
|
||||||
docker tag $(IMAGE_NAME) $(REMOTE_REPO)/$(IMAGE_NAME)
|
|
||||||
docker push $(REMOTE_REPO)/$(IMAGE_NAME)
|
|
||||||
else
|
|
||||||
@echo "REMOTE_REPO not defined, not pushing to a remote repo."
|
|
||||||
endif
|
|
||||||
|
|
||||||
.PHONY: clean
|
|
||||||
clean:
|
|
||||||
docker rmi $(IMAGE_NAME)
|
|
||||||
ifdef REMOTE_REPO
|
|
||||||
docker rmi $(REMOTE_REPO)/$(IMAGE_NAME)
|
|
||||||
else
|
|
||||||
@echo "REMOTE_REPO not defined, not removing from remote repo."
|
|
||||||
endif
|
|
||||||
docker volume rm cargo-cache
|
|
||||||
|
|
||||||
# NOTE: This target will write to folders underneath the git-root
|
|
||||||
.PHONY: run
|
|
||||||
run: build
|
|
||||||
docker run --rm --init --read-only --mount type=tmpfs,destination=/tmp -v "$$(readlink -f ../../):/source" --workdir=/source --mount source=cargo-cache,target=/usr/local/cargo/registry $(IMAGE_NAME)
|
|
||||||
|
|
||||||
.PHONY: shell
|
|
||||||
shell: build
|
|
||||||
docker run --rm -i -t --entrypoint /bin/sh --mount type=tmpfs,destination=/tmp -v "$$(readlink -f ../../):/source" --workdir=/source --mount source=cargo-cache,target=/usr/local/cargo/registry $(IMAGE_NAME)
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
FROM rustlang/rust:nightly-alpine3.17
|
|
||||||
|
|
||||||
RUN apk add --no-cache musl-dev
|
|
||||||
|
|
||||||
ENTRYPOINT ["cargo", "clippy", "--no-deps", "--all-targets", "--all-features", "--", "-D", "warnings"]
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
IMAGE_NAME:=organic-clippy
|
|
||||||
# REMOTE_REPO:=harbor.fizz.buzz/private
|
|
||||||
|
|
||||||
.PHONY: all
|
|
||||||
all: build push
|
|
||||||
|
|
||||||
.PHONY: build
|
|
||||||
build:
|
|
||||||
docker build -t $(IMAGE_NAME) -f Dockerfile .
|
|
||||||
|
|
||||||
.PHONY: push
|
|
||||||
push:
|
|
||||||
ifdef REMOTE_REPO
|
|
||||||
docker tag $(IMAGE_NAME) $(REMOTE_REPO)/$(IMAGE_NAME)
|
|
||||||
docker push $(REMOTE_REPO)/$(IMAGE_NAME)
|
|
||||||
else
|
|
||||||
@echo "REMOTE_REPO not defined, not pushing to a remote repo."
|
|
||||||
endif
|
|
||||||
|
|
||||||
.PHONY: clean
|
|
||||||
clean:
|
|
||||||
docker rmi $(IMAGE_NAME)
|
|
||||||
ifdef REMOTE_REPO
|
|
||||||
docker rmi $(REMOTE_REPO)/$(IMAGE_NAME)
|
|
||||||
else
|
|
||||||
@echo "REMOTE_REPO not defined, not removing from remote repo."
|
|
||||||
endif
|
|
||||||
docker volume rm rust-cache cargo-cache
|
|
||||||
|
|
||||||
# NOTE: This target will write to folders underneath the git-root
|
|
||||||
.PHONY: run
|
|
||||||
run: build
|
|
||||||
docker run --rm --init --read-only --mount type=tmpfs,destination=/tmp -v "$$(readlink -f ../../):/source:ro" --workdir=/source --mount source=cargo-cache,target=/usr/local/cargo/registry --mount source=rust-cache,target=/target --env CARGO_TARGET_DIR=/target $(IMAGE_NAME)
|
|
||||||
|
|
||||||
.PHONY: shell
|
|
||||||
shell: build
|
|
||||||
docker run --rm -i -t --entrypoint /bin/sh --mount type=tmpfs,destination=/tmp -v "$$(readlink -f ../../):/source:ro" --workdir=/source --mount source=cargo-cache,target=/usr/local/cargo/registry --mount source=rust-cache,target=/target --env CARGO_TARGET_DIR=/target $(IMAGE_NAME)
|
|
||||||
20
docker/organic_development/Dockerfile
Normal file
20
docker/organic_development/Dockerfile
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
# syntax=docker/dockerfile:1
|
||||||
|
ARG ALPINE_VERSION="3.20"
|
||||||
|
|
||||||
|
FROM rustlang/rust:nightly-alpine$ALPINE_VERSION AS builder
|
||||||
|
|
||||||
|
RUN apk add --no-cache musl-dev
|
||||||
|
RUN --mount=type=tmpfs,target=/tmp --mount=type=cache,target=/usr/local/cargo/registry,sharing=locked cargo install --locked --no-default-features --features ci-autoclean cargo-cache
|
||||||
|
RUN rustup component add rustc-codegen-cranelift
|
||||||
|
|
||||||
|
FROM builder AS format
|
||||||
|
|
||||||
|
RUN rustup component add rustfmt
|
||||||
|
|
||||||
|
FROM builder AS clippy
|
||||||
|
|
||||||
|
RUN rustup component add clippy
|
||||||
|
|
||||||
|
FROM builder AS wasm
|
||||||
|
|
||||||
|
RUN rustup target add wasm32-unknown-unknown
|
||||||
36
docker/organic_development/Makefile
Normal file
36
docker/organic_development/Makefile
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
SHELL := bash
|
||||||
|
.ONESHELL:
|
||||||
|
.SHELLFLAGS := -eu -o pipefail -c
|
||||||
|
.DELETE_ON_ERROR:
|
||||||
|
MAKEFLAGS += --warn-undefined-variables
|
||||||
|
MAKEFLAGS += --no-builtin-rules
|
||||||
|
|
||||||
|
ifeq ($(origin .RECIPEPREFIX), undefined)
|
||||||
|
$(error This Make does not support .RECIPEPREFIX. Please use GNU Make 4.0 or later)
|
||||||
|
endif
|
||||||
|
.RECIPEPREFIX = >
|
||||||
|
|
||||||
|
TARGET := builder
|
||||||
|
IMAGE_NAME := organic-development
|
||||||
|
ifneq ($(TARGET),builder)
|
||||||
|
IMAGE_NAME := $(IMAGE_NAME)-$(TARGET)
|
||||||
|
endif
|
||||||
|
|
||||||
|
.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 .
|
||||||
|
> docker volume create organic-cargo-registry
|
||||||
|
|
||||||
|
.PHONY: shell
|
||||||
|
shell: ## Launch an interactive shell inside the docker image with the source repository mounted at /source.
|
||||||
|
shell: build
|
||||||
|
> docker run --rm -i -t --entrypoint /bin/sh --mount type=tmpfs,destination=/tmp -v "$$(readlink -f ../../):/source" --workdir=/source --env CARGO_TARGET_DIR=/target -v "organic-cargo-registry:/usr/local/cargo/registry" $(IMAGE_NAME)
|
||||||
|
|
||||||
|
.PHONY: clean
|
||||||
|
clean: ## Remove the docker image and volume.
|
||||||
|
> docker rmi $(IMAGE_NAME)
|
||||||
|
> docker volume rm organic-cargo-registry
|
||||||
@@ -1,10 +1,25 @@
|
|||||||
FROM alpine:3.17 AS build
|
# syntax=docker/dockerfile:1
|
||||||
|
ARG ALPINE_VERSION="3.20"
|
||||||
|
|
||||||
|
# ARG EMACS_REPO=https://git.savannah.gnu.org/git/emacs.git
|
||||||
|
ARG EMACS_REPO=https://code.fizz.buzz/mirror/emacs.git
|
||||||
|
|
||||||
|
ARG EMACS_VERSION=emacs-29.1
|
||||||
|
|
||||||
|
# ARG ORG_MODE_REPO=https://git.savannah.gnu.org/git/emacs/org-mode.git
|
||||||
|
ARG ORG_MODE_REPO=https://code.fizz.buzz/mirror/org-mode.git
|
||||||
|
|
||||||
|
ARG ORG_VERSION=abf5156096c06ee5aa05795c3dc5a065f76ada97
|
||||||
|
|
||||||
|
|
||||||
|
FROM alpine:$ALPINE_VERSION AS build
|
||||||
RUN apk add --no-cache build-base musl-dev git autoconf make texinfo gnutls-dev ncurses-dev gawk libgccjit-dev
|
RUN apk add --no-cache build-base musl-dev git autoconf make texinfo gnutls-dev ncurses-dev gawk libgccjit-dev
|
||||||
|
|
||||||
|
|
||||||
FROM build AS build-emacs
|
FROM build AS build-emacs
|
||||||
ARG EMACS_VERSION=emacs-29.1
|
ARG EMACS_VERSION
|
||||||
RUN git clone --depth 1 --branch $EMACS_VERSION https://git.savannah.gnu.org/git/emacs.git /root/emacs
|
ARG EMACS_REPO
|
||||||
|
RUN git clone --depth 1 --branch $EMACS_VERSION $EMACS_REPO /root/emacs
|
||||||
WORKDIR /root/emacs
|
WORKDIR /root/emacs
|
||||||
RUN mkdir /root/dist
|
RUN mkdir /root/dist
|
||||||
RUN ./autogen.sh
|
RUN ./autogen.sh
|
||||||
@@ -14,23 +29,25 @@ RUN make DESTDIR="/root/dist" install
|
|||||||
|
|
||||||
|
|
||||||
FROM build AS build-org-mode
|
FROM build AS build-org-mode
|
||||||
ARG ORG_VERSION=abf5156096c06ee5aa05795c3dc5a065f76ada97
|
ARG ORG_VERSION
|
||||||
COPY --from=build-emacs /root/dist/ /
|
ARG ORG_MODE_REPO
|
||||||
|
COPY --link --from=build-emacs /root/dist/ /
|
||||||
RUN mkdir /root/dist
|
RUN mkdir /root/dist
|
||||||
# Savannah does not allow fetching specific revisions, so we're going to have to put unnecessary load on their server by cloning main and then checking out the revision we want.
|
# Savannah does not allow fetching specific revisions, so we're going to have to put unnecessary load on their server by cloning main and then checking out the revision we want.
|
||||||
RUN git clone https://git.savannah.gnu.org/git/emacs/org-mode.git /root/org-mode && git -C /root/org-mode checkout $ORG_VERSION
|
RUN git clone $ORG_MODE_REPO /root/org-mode && git -C /root/org-mode checkout $ORG_VERSION
|
||||||
# RUN mkdir /root/org-mode && git -C /root/org-mode init --initial-branch=main && git -C /root/org-mode remote add origin https://git.savannah.gnu.org/git/emacs/org-mode.git && git -C /root/org-mode fetch origin $ORG_VERSION && git -C /root/org-mode checkout FETCH_HEAD
|
# RUN mkdir /root/org-mode && git -C /root/org-mode init --initial-branch=main && git -C /root/org-mode remote add origin $ORG_REPO && git -C /root/org-mode fetch origin $ORG_VERSION && git -C /root/org-mode checkout FETCH_HEAD
|
||||||
WORKDIR /root/org-mode
|
WORKDIR /root/org-mode
|
||||||
RUN make compile
|
RUN make compile
|
||||||
RUN make DESTDIR="/root/dist" install
|
RUN make DESTDIR="/root/dist" install
|
||||||
|
|
||||||
|
|
||||||
FROM rustlang/rust:nightly-alpine3.17 AS tester
|
FROM rustlang/rust:nightly-alpine$ALPINE_VERSION AS tester
|
||||||
ENV LANG=en_US.UTF-8
|
ENV LANG=en_US.UTF-8
|
||||||
RUN apk add --no-cache musl-dev ncurses gnutls libgccjit
|
RUN apk add --no-cache musl-dev ncurses gnutls libgccjit
|
||||||
RUN cargo install --locked --no-default-features --features ci-autoclean cargo-cache
|
RUN --mount=type=tmpfs,target=/tmp --mount=type=cache,target=/usr/local/cargo/registry,sharing=locked cargo install --locked --no-default-features --features ci-autoclean cargo-cache
|
||||||
COPY --from=build-emacs /root/dist/ /
|
RUN rustup component add rustc-codegen-cranelift
|
||||||
COPY --from=build-org-mode /root/dist/ /
|
COPY --link --from=build-emacs /root/dist/ /
|
||||||
|
COPY --link --from=build-org-mode /root/dist/ /
|
||||||
|
|
||||||
ENTRYPOINT ["cargo", "test"]
|
ENTRYPOINT ["cargo", "test"]
|
||||||
|
|
||||||
@@ -100,13 +117,13 @@ RUN mkdir -p $LITERATE_BUILD_EMACS_PATH && git -C $LITERATE_BUILD_EMACS_PATH ini
|
|||||||
# unused/aws.org contains invalid paths for setupfile which causes both upstream org-mode and Organic to error out.
|
# unused/aws.org contains invalid paths for setupfile which causes both upstream org-mode and Organic to error out.
|
||||||
RUN rm $LITERATE_BUILD_EMACS_PATH/unused/aws.org
|
RUN rm $LITERATE_BUILD_EMACS_PATH/unused/aws.org
|
||||||
|
|
||||||
FROM tester as foreign-document-test
|
FROM tester as foreign-document
|
||||||
RUN apk add --no-cache bash coreutils
|
RUN apk add --no-cache bash coreutils
|
||||||
RUN mkdir /foreign_documents
|
RUN mkdir /foreign_documents
|
||||||
COPY --from=foreign-document-gather /foreign_documents/howardabrams /foreign_documents/howardabrams
|
COPY --link --from=foreign-document-gather /foreign_documents/howardabrams /foreign_documents/howardabrams
|
||||||
COPY --from=foreign-document-gather /foreign_documents/doomemacs /foreign_documents/doomemacs
|
COPY --link --from=foreign-document-gather /foreign_documents/doomemacs /foreign_documents/doomemacs
|
||||||
COPY --from=foreign-document-gather /foreign_documents/worg /foreign_documents/worg
|
COPY --link --from=foreign-document-gather /foreign_documents/worg /foreign_documents/worg
|
||||||
COPY --from=foreign-document-gather /foreign_documents/literate_build_emacs /foreign_documents/literate_build_emacs
|
COPY --link --from=foreign-document-gather /foreign_documents/literate_build_emacs /foreign_documents/literate_build_emacs
|
||||||
COPY --from=build-org-mode /root/org-mode /foreign_documents/org-mode
|
COPY --link --from=build-org-mode /root/org-mode /foreign_documents/org-mode
|
||||||
COPY --from=build-emacs /root/emacs /foreign_documents/emacs
|
COPY --link --from=build-emacs /root/emacs /foreign_documents/emacs
|
||||||
ENTRYPOINT ["cargo", "run", "--bin", "foreign_document_test", "--features", "compare,foreign_document_test", "--profile", "release-lto"]
|
ENTRYPOINT ["cargo", "run", "--bin", "foreign_document_test", "--features", "compare,foreign_document_test", "--profile", "release-lto"]
|
||||||
|
|||||||
@@ -1,44 +1,36 @@
|
|||||||
IMAGE_NAME:=organic-test
|
SHELL := bash
|
||||||
# REMOTE_REPO:=harbor.fizz.buzz/private
|
.ONESHELL:
|
||||||
|
.SHELLFLAGS := -eu -o pipefail -c
|
||||||
|
.DELETE_ON_ERROR:
|
||||||
|
MAKEFLAGS += --warn-undefined-variables
|
||||||
|
MAKEFLAGS += --no-builtin-rules
|
||||||
|
|
||||||
.PHONY: all
|
ifeq ($(origin .RECIPEPREFIX), undefined)
|
||||||
all: build push
|
$(error This Make does not support .RECIPEPREFIX. Please use GNU Make 4.0 or later)
|
||||||
|
endif
|
||||||
|
.RECIPEPREFIX = >
|
||||||
|
|
||||||
|
TARGET := tester
|
||||||
|
IMAGE_NAME := organic-test
|
||||||
|
ifneq ($(TARGET),tester)
|
||||||
|
IMAGE_NAME := $(IMAGE_NAME)-$(TARGET)
|
||||||
|
endif
|
||||||
|
|
||||||
|
.PHONY: help
|
||||||
|
help:
|
||||||
|
> @grep -h "##" $(MAKEFILE_LIST) | grep -v grep | sed -E 's/^([^:]*): *## */\1: /'
|
||||||
|
|
||||||
.PHONY: build
|
.PHONY: build
|
||||||
build:
|
build: ## Build the docker image.
|
||||||
docker build -t $(IMAGE_NAME) -f Dockerfile --target tester .
|
> docker build --tag $(IMAGE_NAME) --target=$(TARGET) --file Dockerfile .
|
||||||
|
> docker volume create organic-cargo-registry
|
||||||
.PHONY: build_foreign_document_test
|
|
||||||
build_foreign_document_test:
|
|
||||||
docker build -t $(IMAGE_NAME)-foreign-document -f Dockerfile --target foreign-document-test .
|
|
||||||
|
|
||||||
.PHONY: push
|
|
||||||
push:
|
|
||||||
ifdef REMOTE_REPO
|
|
||||||
docker tag $(IMAGE_NAME) $(REMOTE_REPO)/$(IMAGE_NAME)
|
|
||||||
docker push $(REMOTE_REPO)/$(IMAGE_NAME)
|
|
||||||
else
|
|
||||||
@echo "REMOTE_REPO not defined, not pushing to a remote repo."
|
|
||||||
endif
|
|
||||||
|
|
||||||
.PHONY: clean
|
|
||||||
clean:
|
|
||||||
docker rmi $(IMAGE_NAME)
|
|
||||||
ifdef REMOTE_REPO
|
|
||||||
docker rmi $(REMOTE_REPO)/$(IMAGE_NAME)
|
|
||||||
else
|
|
||||||
@echo "REMOTE_REPO not defined, not removing from remote repo."
|
|
||||||
endif
|
|
||||||
docker volume rm rust-cache cargo-cache
|
|
||||||
|
|
||||||
.PHONY: run
|
|
||||||
run: build
|
|
||||||
docker run --rm --init --read-only --mount type=tmpfs,destination=/tmp -v "$$(readlink -f ../../):/source:ro" --workdir=/source --mount source=cargo-cache,target=/usr/local/cargo/registry --mount source=rust-cache,target=/target --env CARGO_TARGET_DIR=/target $(IMAGE_NAME) --no-default-features --features compare --no-fail-fast --lib --test test_loader
|
|
||||||
|
|
||||||
.PHONY: shell
|
.PHONY: shell
|
||||||
|
shell: ## Launch an interactive shell inside the docker image with the source repository mounted at /source.
|
||||||
shell: build
|
shell: build
|
||||||
docker run --rm -i -t --entrypoint /bin/sh --mount type=tmpfs,destination=/tmp -v "$$(readlink -f ../../):/source:ro" --workdir=/source --mount source=cargo-cache,target=/usr/local/cargo/registry --mount source=rust-cache,target=/target --env CARGO_TARGET_DIR=/target $(IMAGE_NAME)
|
> docker run --rm -i -t --entrypoint /bin/sh --mount type=tmpfs,destination=/tmp -v "$$(readlink -f ../../):/source" --workdir=/source --env CARGO_TARGET_DIR=/target -v "organic-cargo-registry:/usr/local/cargo/registry" $(IMAGE_NAME)
|
||||||
|
|
||||||
.PHONY: run_foreign_document_test
|
.PHONY: clean
|
||||||
run_foreign_document_test: build_foreign_document_test
|
clean: ## Remove the docker image and volume.
|
||||||
docker run --rm --init --read-only --mount type=tmpfs,destination=/tmp -v "$$(readlink -f ../../):/source:ro" --workdir=/source --mount source=cargo-cache,target=/usr/local/cargo/registry --mount source=rust-cache,target=/target --env CARGO_TARGET_DIR=/target $(IMAGE_NAME)-foreign-document
|
> docker rmi $(IMAGE_NAME)
|
||||||
|
> docker volume rm organic-cargo-registry
|
||||||
|
|||||||
0
org_mode_samples/document/empty.org
Normal file
0
org_mode_samples/document/empty.org
Normal file
4
org_mode_samples/document/only_line_breaks.org
Normal file
4
org_mode_samples/document/only_line_breaks.org
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
5
org_mode_samples/document/post_blank.org
Normal file
5
org_mode_samples/document/post_blank.org
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
* foo
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,3 +1,32 @@
|
|||||||
|
* Empty
|
||||||
|
:PROPERTIES:
|
||||||
|
:END:
|
||||||
|
* Single new line
|
||||||
:PROPERTIES:
|
:PROPERTIES:
|
||||||
|
|
||||||
|
:END:
|
||||||
|
* Single line with spaces
|
||||||
|
:PROPERTIES:
|
||||||
|
|
||||||
|
:END:
|
||||||
|
* Many lines, first line without spaces
|
||||||
|
:PROPERTIES:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
:END:
|
||||||
|
* Many lines, first line with spaces
|
||||||
|
:PROPERTIES:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
:END:
|
||||||
|
* Many lines, first line with spaces, later line with spaces
|
||||||
|
:PROPERTIES:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
:END:
|
:END:
|
||||||
|
|||||||
@@ -5,3 +5,5 @@
|
|||||||
#+call: dolar cat(dog)
|
#+call: dolar cat(dog)
|
||||||
|
|
||||||
#+call: (bat)
|
#+call: (bat)
|
||||||
|
|
||||||
|
#+call:
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
: foo
|
||||||
|
:
|
||||||
|
: bar
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
1. foo
|
||||||
|
#+begin_src text
|
||||||
|
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
2. baz
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
[[file:simple.org::2]]
|
||||||
1
org_mode_samples/object/regular_link/tramp_link.org
Normal file
1
org_mode_samples/object/regular_link/tramp_link.org
Normal file
@@ -0,0 +1 @@
|
|||||||
|
[[/ssh:admin@test.example:important/file.pdf]]
|
||||||
3
org_mode_samples/object/target/simple.org
Normal file
3
org_mode_samples/object/target/simple.org
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<<FOO>> bar
|
||||||
|
|
||||||
|
[[FOO][baz]]
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
* foo
|
||||||
|
|
||||||
|
** bar
|
||||||
|
|
||||||
|
* baz
|
||||||
76
scripts/build_all_feature_flag_combinations.bash
Executable file
76
scripts/build_all_feature_flag_combinations.bash
Executable file
@@ -0,0 +1,76 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
#
|
||||||
|
# Time running a single parse without invoking a compare with emacs.
|
||||||
|
set -euo pipefail
|
||||||
|
IFS=$'\n\t'
|
||||||
|
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||||
|
|
||||||
|
: ${PROFILE:="debug"}
|
||||||
|
|
||||||
|
############## Setup #########################
|
||||||
|
|
||||||
|
function cleanup {
|
||||||
|
for f in "${folders[@]}"; do
|
||||||
|
log "Deleting $f"
|
||||||
|
rm -rf "$f"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
folders=()
|
||||||
|
for sig in EXIT INT QUIT HUP TERM; do
|
||||||
|
trap "set +e; cleanup" "$sig"
|
||||||
|
done
|
||||||
|
|
||||||
|
function die {
|
||||||
|
local status_code="$1"
|
||||||
|
shift
|
||||||
|
(>&2 echo "${@}")
|
||||||
|
exit "$status_code"
|
||||||
|
}
|
||||||
|
|
||||||
|
function log {
|
||||||
|
(>&2 echo "${@}")
|
||||||
|
}
|
||||||
|
|
||||||
|
############## Program #########################
|
||||||
|
|
||||||
|
function main {
|
||||||
|
if [ "$#" -gt 0 ]; then
|
||||||
|
export CARGO_TARGET_DIR="$1"
|
||||||
|
else
|
||||||
|
local work_directory=$(mktemp -d -t 'organic.XXXXXX')
|
||||||
|
folders+=("$work_directory")
|
||||||
|
export CARGO_TARGET_DIR="$work_directory"
|
||||||
|
fi
|
||||||
|
local features=(compare foreign_document_test tracing event_count wasm wasm_test)
|
||||||
|
ENABLED_FEATURES= for_each_combination "${features[@]}"
|
||||||
|
}
|
||||||
|
|
||||||
|
function for_each_combination {
|
||||||
|
local additional_flags=()
|
||||||
|
if [ "$PROFILE" = "dev" ] || [ "$PROFILE" = "debug" ]; then
|
||||||
|
PROFILE="debug"
|
||||||
|
else
|
||||||
|
additional_flags+=(--profile "$PROFILE")
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
local flag=$1
|
||||||
|
shift
|
||||||
|
|
||||||
|
if [ "$#" -gt 0 ]; then
|
||||||
|
ENABLED_FEATURES="$ENABLED_FEATURES" for_each_combination "${@}"
|
||||||
|
elif [ -z "$ENABLED_FEATURES" ]; then
|
||||||
|
(cd "$DIR/../" && printf "\n\n\n========== no features ==========\n\n\n" && set -x && cargo build "${additional_flags[@]}" --no-default-features)
|
||||||
|
else
|
||||||
|
(cd "$DIR/../" && printf "\n\n\n========== %s ==========\n\n\n" "${ENABLED_FEATURES:1}" && set -x && cargo build "${additional_flags[@]}" --no-default-features --features "${ENABLED_FEATURES:1}")
|
||||||
|
fi
|
||||||
|
|
||||||
|
ENABLED_FEATURES="$ENABLED_FEATURES,$flag"
|
||||||
|
if [ "$#" -gt 0 ]; then
|
||||||
|
ENABLED_FEATURES="$ENABLED_FEATURES" for_each_combination "${@}"
|
||||||
|
else
|
||||||
|
(cd "$DIR/../" && printf "\n\n\n========== %s ==========\n\n\n" "${ENABLED_FEATURES:1}" && set -x && cargo build "${additional_flags[@]}" --no-default-features --features "${ENABLED_FEATURES:1}")
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
main "${@}"
|
||||||
111
scripts/run_docker_wasm_compare.bash
Executable file
111
scripts/run_docker_wasm_compare.bash
Executable file
@@ -0,0 +1,111 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
#
|
||||||
|
set -euo pipefail
|
||||||
|
IFS=$'\n\t'
|
||||||
|
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||||
|
|
||||||
|
: ${SHELL:="NO"} # or YES to launch a shell instead of running the test
|
||||||
|
: ${TRACE:="NO"} # or YES to send traces to jaeger
|
||||||
|
: ${BACKTRACE:="NO"} # or YES to print a rust backtrace when panicking
|
||||||
|
: ${NO_COLOR:=""} # Set to anything to disable color output
|
||||||
|
: ${PROFILE:="debug"}
|
||||||
|
|
||||||
|
REALPATH=$(command -v uu-realpath || command -v realpath)
|
||||||
|
MAKE=$(command -v gmake || command -v make)
|
||||||
|
|
||||||
|
############## Setup #########################
|
||||||
|
|
||||||
|
function die {
|
||||||
|
local status_code="$1"
|
||||||
|
shift
|
||||||
|
(>&2 echo "${@}")
|
||||||
|
exit "$status_code"
|
||||||
|
}
|
||||||
|
|
||||||
|
function log {
|
||||||
|
(>&2 echo "${@}")
|
||||||
|
}
|
||||||
|
|
||||||
|
############## Program #########################
|
||||||
|
|
||||||
|
function main {
|
||||||
|
build_container
|
||||||
|
launch_container "${@}"
|
||||||
|
}
|
||||||
|
|
||||||
|
function build_container {
|
||||||
|
$MAKE -C "$DIR/../docker/organic_test"
|
||||||
|
}
|
||||||
|
|
||||||
|
function launch_container {
|
||||||
|
local additional_flags=()
|
||||||
|
local features=(wasm_test)
|
||||||
|
|
||||||
|
if [ "$NO_COLOR" != "" ]; then
|
||||||
|
additional_flags+=(--env "NO_COLOR=$NO_COLOR")
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$TRACE" = "YES" ]; then
|
||||||
|
# We use the host network so it can talk to jaeger hosted at 127.0.0.1
|
||||||
|
additional_flags+=(--network=host --env RUST_LOG=debug)
|
||||||
|
features+=(tracing)
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$SHELL" != "YES" ]; then
|
||||||
|
additional_flags+=(--read-only)
|
||||||
|
else
|
||||||
|
additional_flags+=(-t)
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$BACKTRACE" = "YES" ]; then
|
||||||
|
additional_flags+=(--env RUST_BACKTRACE=full)
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$SHELL" = "YES" ]; then
|
||||||
|
exec docker run "${additional_flags[@]}" --init --rm -i --mount type=tmpfs,destination=/tmp -v "/:/input:ro" -v "$($REALPATH "$DIR/../"):/source:ro" --mount source=cargo-cache,target=/usr/local/cargo/registry --mount source=rust-cache,target=/target --env CARGO_TARGET_DIR=/target -w /source --entrypoint "" organic-test /bin/sh
|
||||||
|
fi
|
||||||
|
|
||||||
|
local features_joined
|
||||||
|
features_joined=$(IFS=","; echo "${features[*]}")
|
||||||
|
|
||||||
|
local build_flags=()
|
||||||
|
if [ "$PROFILE" = "dev" ] || [ "$PROFILE" = "debug" ]; then
|
||||||
|
PROFILE="debug"
|
||||||
|
else
|
||||||
|
build_flags+=(--profile "$PROFILE")
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
if [ $# -gt 0 ]; then
|
||||||
|
# If we passed in args, we need to forward them along
|
||||||
|
for path in "${@}"; do
|
||||||
|
local full_path
|
||||||
|
full_path=$($REALPATH "$path")
|
||||||
|
init_script=$(cat <<EOF
|
||||||
|
set -euo pipefail
|
||||||
|
IFS=\$'\n\t'
|
||||||
|
|
||||||
|
cargo build --bin wasm_test --no-default-features --features "$features_joined" ${build_flags[@]}
|
||||||
|
exec /target/${PROFILE}/wasm_test "/input${full_path}"
|
||||||
|
EOF
|
||||||
|
)
|
||||||
|
docker run "${additional_flags[@]}" --init --rm -i --mount type=tmpfs,destination=/tmp -v "/:/input:ro" -v "$($REALPATH "$DIR/../"):/source:ro" --mount source=cargo-cache,target=/usr/local/cargo/registry --mount source=rust-cache,target=/target --env CARGO_TARGET_DIR=/target -w /source --entrypoint "" organic-test sh -c "$init_script"
|
||||||
|
done
|
||||||
|
else
|
||||||
|
local current_directory init_script
|
||||||
|
current_directory=$(pwd)
|
||||||
|
init_script=$(cat <<EOF
|
||||||
|
set -euo pipefail
|
||||||
|
IFS=\$'\n\t'
|
||||||
|
|
||||||
|
cargo build --bin wasm_test --no-default-features --features "$features_joined" ${build_flags[@]}
|
||||||
|
cd /input${current_directory}
|
||||||
|
exec /target/${PROFILE}/wasm_test
|
||||||
|
EOF
|
||||||
|
)
|
||||||
|
|
||||||
|
docker run "${additional_flags[@]}" --init --rm -i --mount type=tmpfs,destination=/tmp -v "/:/input:ro" -v "$($REALPATH "$DIR/../"):/source:ro" --mount source=cargo-cache,target=/usr/local/cargo/registry --mount source=rust-cache,target=/target --env CARGO_TARGET_DIR=/target -w /source --entrypoint "" organic-test sh -c "$init_script"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
main "${@}"
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#![feature(exit_status_error)]
|
||||||
#![feature(round_char_boundary)]
|
#![feature(round_char_boundary)]
|
||||||
#![feature(exact_size_is_empty)]
|
#![feature(exact_size_is_empty)]
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
|
|||||||
10
src/bin_wasm.rs
Normal file
10
src/bin_wasm.rs
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
use wasm_bindgen::prelude::wasm_bindgen;
|
||||||
|
|
||||||
|
#[wasm_bindgen]
|
||||||
|
pub fn parse_org(org_contents: &str) -> wasm_bindgen::JsValue {
|
||||||
|
organic::wasm_cli::parse_org(org_contents)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
62
src/bin_wasm_test.rs
Normal file
62
src/bin_wasm_test.rs
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
#![feature(exact_size_is_empty)]
|
||||||
|
#![feature(exit_status_error)]
|
||||||
|
use std::io::Read;
|
||||||
|
|
||||||
|
use organic::wasm_test::wasm_run_anonymous_compare;
|
||||||
|
use organic::wasm_test::wasm_run_compare_on_file;
|
||||||
|
|
||||||
|
#[cfg(feature = "tracing")]
|
||||||
|
use crate::init_tracing::init_telemetry;
|
||||||
|
#[cfg(feature = "tracing")]
|
||||||
|
use crate::init_tracing::shutdown_telemetry;
|
||||||
|
#[cfg(feature = "tracing")]
|
||||||
|
mod init_tracing;
|
||||||
|
|
||||||
|
#[cfg(not(feature = "tracing"))]
|
||||||
|
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
let rt = tokio::runtime::Runtime::new()?;
|
||||||
|
rt.block_on(async {
|
||||||
|
let main_body_result = main_body().await;
|
||||||
|
main_body_result
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "tracing")]
|
||||||
|
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
let rt = tokio::runtime::Runtime::new()?;
|
||||||
|
rt.block_on(async {
|
||||||
|
init_telemetry()?;
|
||||||
|
let main_body_result = main_body().await;
|
||||||
|
shutdown_telemetry()?;
|
||||||
|
main_body_result
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
|
async fn main_body() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
let args = std::env::args().skip(1);
|
||||||
|
if args.is_empty() {
|
||||||
|
let org_contents = read_stdin_to_string()?;
|
||||||
|
if wasm_run_anonymous_compare(org_contents).await? {
|
||||||
|
} else {
|
||||||
|
Err("Diff results do not match.")?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
for arg in args {
|
||||||
|
if wasm_run_compare_on_file(arg).await? {
|
||||||
|
} else {
|
||||||
|
Err("Diff results do not match.")?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_stdin_to_string() -> Result<String, Box<dyn std::error::Error>> {
|
||||||
|
let mut stdin_contents = String::new();
|
||||||
|
std::io::stdin()
|
||||||
|
.lock()
|
||||||
|
.read_to_string(&mut stdin_contents)?;
|
||||||
|
Ok(stdin_contents)
|
||||||
|
}
|
||||||
@@ -1,16 +1,16 @@
|
|||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
use crate::compare::diff::compare_document;
|
use crate::compare::diff::compare_document;
|
||||||
use crate::compare::diff::DiffResult;
|
|
||||||
use crate::compare::parse::emacs_parse_anonymous_org_document;
|
|
||||||
use crate::compare::parse::emacs_parse_file_org_document;
|
|
||||||
use crate::compare::parse::get_emacs_version;
|
|
||||||
use crate::compare::parse::get_org_mode_version;
|
|
||||||
use crate::compare::sexp::sexp;
|
|
||||||
use crate::context::GlobalSettings;
|
use crate::context::GlobalSettings;
|
||||||
use crate::context::LocalFileAccessInterface;
|
use crate::context::LocalFileAccessInterface;
|
||||||
use crate::parser::parse_file_with_settings;
|
use crate::parser::parse_file_with_settings;
|
||||||
use crate::parser::parse_with_settings;
|
use crate::parser::parse_with_settings;
|
||||||
|
use crate::util::cli::emacs_parse_anonymous_org_document;
|
||||||
|
use crate::util::cli::emacs_parse_file_org_document;
|
||||||
|
use crate::util::cli::print_versions;
|
||||||
|
use crate::util::elisp::sexp;
|
||||||
|
use crate::util::terminal::foreground_color;
|
||||||
|
use crate::util::terminal::reset_color;
|
||||||
|
|
||||||
pub async fn run_anonymous_compare<P: AsRef<str>>(
|
pub async fn run_anonymous_compare<P: AsRef<str>>(
|
||||||
org_contents: P,
|
org_contents: P,
|
||||||
@@ -68,8 +68,8 @@ pub async fn run_anonymous_compare_with_settings<'g, 's, P: AsRef<str>>(
|
|||||||
} else if !silent {
|
} else if !silent {
|
||||||
println!(
|
println!(
|
||||||
"{color}Entire document passes.{reset}",
|
"{color}Entire document passes.{reset}",
|
||||||
color = DiffResult::foreground_color(0, 255, 0),
|
color = foreground_color(0, 255, 0),
|
||||||
reset = DiffResult::reset_color(),
|
reset = reset_color(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -121,19 +121,10 @@ pub async fn run_compare_on_file_with_settings<'g, 's, P: AsRef<Path>>(
|
|||||||
} else if !silent {
|
} else if !silent {
|
||||||
println!(
|
println!(
|
||||||
"{color}Entire document passes.{reset}",
|
"{color}Entire document passes.{reset}",
|
||||||
color = DiffResult::foreground_color(0, 255, 0),
|
color = foreground_color(0, 255, 0),
|
||||||
reset = DiffResult::reset_color(),
|
reset = reset_color(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn print_versions() -> Result<(), Box<dyn std::error::Error>> {
|
|
||||||
eprintln!("Using emacs version: {}", get_emacs_version().await?.trim());
|
|
||||||
eprintln!(
|
|
||||||
"Using org-mode version: {}",
|
|
||||||
get_org_mode_version().await?.trim()
|
|
||||||
);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -9,8 +9,6 @@ use super::diff::artificial_owned_diff_scope;
|
|||||||
use super::diff::compare_ast_node;
|
use super::diff::compare_ast_node;
|
||||||
use super::diff::DiffEntry;
|
use super::diff::DiffEntry;
|
||||||
use super::diff::DiffStatus;
|
use super::diff::DiffStatus;
|
||||||
use super::sexp::unquote;
|
|
||||||
use super::sexp::Token;
|
|
||||||
use super::util::get_property;
|
use super::util::get_property;
|
||||||
use super::util::get_property_numeric;
|
use super::util::get_property_numeric;
|
||||||
use super::util::get_property_quoted_string;
|
use super::util::get_property_quoted_string;
|
||||||
@@ -20,6 +18,8 @@ use crate::types::CharOffsetInLine;
|
|||||||
use crate::types::LineNumber;
|
use crate::types::LineNumber;
|
||||||
use crate::types::RetainLabels;
|
use crate::types::RetainLabels;
|
||||||
use crate::types::SwitchNumberLines;
|
use crate::types::SwitchNumberLines;
|
||||||
|
use crate::util::elisp::unquote;
|
||||||
|
use crate::util::elisp::Token;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(crate) enum EmacsField<'s> {
|
pub(crate) enum EmacsField<'s> {
|
||||||
|
|||||||
@@ -16,10 +16,6 @@ use super::compare_field::compare_property_retain_labels;
|
|||||||
use super::compare_field::compare_property_set_of_quoted_string;
|
use super::compare_field::compare_property_set_of_quoted_string;
|
||||||
use super::compare_field::compare_property_single_ast_node;
|
use super::compare_field::compare_property_single_ast_node;
|
||||||
use super::compare_field::compare_property_unquoted_atom;
|
use super::compare_field::compare_property_unquoted_atom;
|
||||||
use super::elisp_fact::ElispFact;
|
|
||||||
use super::elisp_fact::GetElispFact;
|
|
||||||
use super::sexp::unquote;
|
|
||||||
use super::sexp::Token;
|
|
||||||
use super::util::affiliated_keywords_names;
|
use super::util::affiliated_keywords_names;
|
||||||
use super::util::assert_no_children;
|
use super::util::assert_no_children;
|
||||||
use super::util::compare_additional_properties;
|
use super::util::compare_additional_properties;
|
||||||
@@ -109,6 +105,12 @@ use crate::types::Verbatim;
|
|||||||
use crate::types::VerseBlock;
|
use crate::types::VerseBlock;
|
||||||
use crate::types::WarningDelayType;
|
use crate::types::WarningDelayType;
|
||||||
use crate::types::Year;
|
use crate::types::Year;
|
||||||
|
use crate::util::elisp::unquote;
|
||||||
|
use crate::util::elisp::Token;
|
||||||
|
use crate::util::elisp_fact::ElispFact;
|
||||||
|
use crate::util::elisp_fact::GetElispFact;
|
||||||
|
use crate::util::terminal::foreground_color;
|
||||||
|
use crate::util::terminal::reset_color;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum DiffEntry<'b, 's> {
|
pub enum DiffEntry<'b, 's> {
|
||||||
@@ -200,21 +202,21 @@ impl<'b, 's> DiffResult<'b, 's> {
|
|||||||
if self.has_bad_children() {
|
if self.has_bad_children() {
|
||||||
format!(
|
format!(
|
||||||
"{color}BADCHILD{reset}",
|
"{color}BADCHILD{reset}",
|
||||||
color = DiffResult::foreground_color(255, 255, 0),
|
color = foreground_color(255, 255, 0),
|
||||||
reset = DiffResult::reset_color(),
|
reset = reset_color(),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
format!(
|
format!(
|
||||||
"{color}GOOD{reset}",
|
"{color}GOOD{reset}",
|
||||||
color = DiffResult::foreground_color(0, 255, 0),
|
color = foreground_color(0, 255, 0),
|
||||||
reset = DiffResult::reset_color(),
|
reset = reset_color(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DiffStatus::Bad => format!(
|
DiffStatus::Bad => format!(
|
||||||
"{color}BAD{reset}",
|
"{color}BAD{reset}",
|
||||||
color = DiffResult::foreground_color(255, 0, 0),
|
color = foreground_color(255, 0, 0),
|
||||||
reset = DiffResult::reset_color(),
|
reset = reset_color(),
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -239,45 +241,6 @@ impl<'b, 's> DiffResult<'b, 's> {
|
|||||||
.iter()
|
.iter()
|
||||||
.any(|child| child.is_immediately_bad() || child.has_bad_children())
|
.any(|child| child.is_immediately_bad() || child.has_bad_children())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn foreground_color(red: u8, green: u8, blue: u8) -> String {
|
|
||||||
if DiffResult::should_use_color() {
|
|
||||||
format!(
|
|
||||||
"\x1b[38;2;{red};{green};{blue}m",
|
|
||||||
red = red,
|
|
||||||
green = green,
|
|
||||||
blue = blue
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
String::new()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
pub(crate) fn background_color(red: u8, green: u8, blue: u8) -> String {
|
|
||||||
if DiffResult::should_use_color() {
|
|
||||||
format!(
|
|
||||||
"\x1b[48;2;{red};{green};{blue}m",
|
|
||||||
red = red,
|
|
||||||
green = green,
|
|
||||||
blue = blue
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
String::new()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn reset_color() -> &'static str {
|
|
||||||
if DiffResult::should_use_color() {
|
|
||||||
"\x1b[0m"
|
|
||||||
} else {
|
|
||||||
""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn should_use_color() -> bool {
|
|
||||||
!std::env::var("NO_COLOR").is_ok_and(|val| !val.is_empty())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'b, 's> DiffLayer<'b, 's> {
|
impl<'b, 's> DiffLayer<'b, 's> {
|
||||||
@@ -295,14 +258,14 @@ impl<'b, 's> DiffLayer<'b, 's> {
|
|||||||
let status_text = if self.has_bad_children() {
|
let status_text = if self.has_bad_children() {
|
||||||
format!(
|
format!(
|
||||||
"{color}BADCHILD{reset}",
|
"{color}BADCHILD{reset}",
|
||||||
color = DiffResult::foreground_color(255, 255, 0),
|
color = foreground_color(255, 255, 0),
|
||||||
reset = DiffResult::reset_color(),
|
reset = reset_color(),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
format!(
|
format!(
|
||||||
"{color}GOOD{reset}",
|
"{color}GOOD{reset}",
|
||||||
color = DiffResult::foreground_color(0, 255, 0),
|
color = foreground_color(0, 255, 0),
|
||||||
reset = DiffResult::reset_color(),
|
reset = reset_color(),
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
println!(
|
println!(
|
||||||
|
|||||||
@@ -2,10 +2,7 @@
|
|||||||
mod compare;
|
mod compare;
|
||||||
mod compare_field;
|
mod compare_field;
|
||||||
mod diff;
|
mod diff;
|
||||||
mod elisp_fact;
|
|
||||||
mod macros;
|
mod macros;
|
||||||
mod parse;
|
|
||||||
mod sexp;
|
|
||||||
mod util;
|
mod util;
|
||||||
pub use compare::run_anonymous_compare;
|
pub use compare::run_anonymous_compare;
|
||||||
pub use compare::run_anonymous_compare_with_settings;
|
pub use compare::run_anonymous_compare_with_settings;
|
||||||
|
|||||||
@@ -8,14 +8,15 @@ use super::compare_field::compare_property_quoted_string;
|
|||||||
use super::compare_field::ComparePropertiesResult;
|
use super::compare_field::ComparePropertiesResult;
|
||||||
use super::diff::DiffEntry;
|
use super::diff::DiffEntry;
|
||||||
use super::diff::DiffStatus;
|
use super::diff::DiffStatus;
|
||||||
use super::elisp_fact::GetElispFact;
|
|
||||||
use super::sexp::Token;
|
|
||||||
use crate::compare::diff::compare_ast_node;
|
use crate::compare::diff::compare_ast_node;
|
||||||
use crate::compare::sexp::unquote;
|
|
||||||
use crate::types::AffiliatedKeywordValue;
|
use crate::types::AffiliatedKeywordValue;
|
||||||
use crate::types::AstNode;
|
use crate::types::AstNode;
|
||||||
use crate::types::GetAffiliatedKeywords;
|
use crate::types::GetAffiliatedKeywords;
|
||||||
use crate::types::StandardProperties;
|
use crate::types::StandardProperties;
|
||||||
|
use crate::util::elisp::get_emacs_standard_properties;
|
||||||
|
use crate::util::elisp::unquote;
|
||||||
|
use crate::util::elisp::Token;
|
||||||
|
use crate::util::elisp_fact::GetElispFact;
|
||||||
|
|
||||||
/// Check if the child string slice is a slice of the parent string slice.
|
/// Check if the child string slice is a slice of the parent string slice.
|
||||||
fn is_slice_of(parent: &str, child: &str) -> bool {
|
fn is_slice_of(parent: &str, child: &str) -> bool {
|
||||||
@@ -139,86 +140,12 @@ fn assert_post_blank<'b, 's, S: StandardProperties<'s> + ?Sized>(
|
|||||||
.post_blank
|
.post_blank
|
||||||
.ok_or("Token should have a post-blank.")?;
|
.ok_or("Token should have a post-blank.")?;
|
||||||
if rust_post_blank as usize != emacs_post_blank {
|
if rust_post_blank as usize != emacs_post_blank {
|
||||||
Err(format!("Rust post-blank (in chars) {rust_post_blank} does not match emacs post-blank ({emacs_post_blank})", rust_post_blank = rust_post_blank, emacs_post_blank = emacs_post_blank))?;
|
Err(format!("Rust post-blank {rust_post_blank} does not match emacs post-blank ({emacs_post_blank})", rust_post_blank = rust_post_blank, emacs_post_blank = emacs_post_blank))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
struct EmacsStandardProperties {
|
|
||||||
begin: Option<usize>,
|
|
||||||
#[allow(dead_code)]
|
|
||||||
post_affiliated: Option<usize>,
|
|
||||||
#[allow(dead_code)]
|
|
||||||
contents_begin: Option<usize>,
|
|
||||||
#[allow(dead_code)]
|
|
||||||
contents_end: Option<usize>,
|
|
||||||
end: Option<usize>,
|
|
||||||
#[allow(dead_code)]
|
|
||||||
post_blank: Option<usize>,
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_emacs_standard_properties(
|
|
||||||
emacs: &Token<'_>,
|
|
||||||
) -> Result<EmacsStandardProperties, Box<dyn std::error::Error>> {
|
|
||||||
let children = emacs.as_list()?;
|
|
||||||
let attributes_child = children.get(1).ok_or("Should have an attributes child.")?;
|
|
||||||
let attributes_map = attributes_child.as_map()?;
|
|
||||||
let standard_properties = attributes_map.get(":standard-properties");
|
|
||||||
Ok(if standard_properties.is_some() {
|
|
||||||
let mut std_props = standard_properties
|
|
||||||
.expect("if statement proves its Some")
|
|
||||||
.as_vector()?
|
|
||||||
.iter();
|
|
||||||
let begin = maybe_token_to_usize(std_props.next())?;
|
|
||||||
let post_affiliated = maybe_token_to_usize(std_props.next())?;
|
|
||||||
let contents_begin = maybe_token_to_usize(std_props.next())?;
|
|
||||||
let contents_end = maybe_token_to_usize(std_props.next())?;
|
|
||||||
let end = maybe_token_to_usize(std_props.next())?;
|
|
||||||
let post_blank = maybe_token_to_usize(std_props.next())?;
|
|
||||||
EmacsStandardProperties {
|
|
||||||
begin,
|
|
||||||
post_affiliated,
|
|
||||||
contents_begin,
|
|
||||||
contents_end,
|
|
||||||
end,
|
|
||||||
post_blank,
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
let begin = maybe_token_to_usize(attributes_map.get(":begin").copied())?;
|
|
||||||
let end = maybe_token_to_usize(attributes_map.get(":end").copied())?;
|
|
||||||
let contents_begin = maybe_token_to_usize(attributes_map.get(":contents-begin").copied())?;
|
|
||||||
let contents_end = maybe_token_to_usize(attributes_map.get(":contents-end").copied())?;
|
|
||||||
let post_blank = maybe_token_to_usize(attributes_map.get(":post-blank").copied())?;
|
|
||||||
let post_affiliated =
|
|
||||||
maybe_token_to_usize(attributes_map.get(":post-affiliated").copied())?;
|
|
||||||
EmacsStandardProperties {
|
|
||||||
begin,
|
|
||||||
post_affiliated,
|
|
||||||
contents_begin,
|
|
||||||
contents_end,
|
|
||||||
end,
|
|
||||||
post_blank,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn maybe_token_to_usize(
|
|
||||||
token: Option<&Token<'_>>,
|
|
||||||
) -> Result<Option<usize>, Box<dyn std::error::Error>> {
|
|
||||||
Ok(token
|
|
||||||
.map(|token| token.as_atom())
|
|
||||||
.map_or(Ok(None), |r| r.map(Some))?
|
|
||||||
.and_then(|val| {
|
|
||||||
if val == "nil" {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some(val.parse::<usize>())
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.map_or(Ok(None), |r| r.map(Some))?)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get a named property from the emacs token.
|
/// Get a named property from the emacs token.
|
||||||
///
|
///
|
||||||
/// Returns Ok(None) if value is nil or absent.
|
/// Returns Ok(None) if value is nil or absent.
|
||||||
@@ -285,7 +212,7 @@ where
|
|||||||
pub(crate) fn compare_children<'b, 's, 'x, RC>(
|
pub(crate) fn compare_children<'b, 's, 'x, RC>(
|
||||||
source: &'s str,
|
source: &'s str,
|
||||||
emacs: &'b Token<'s>,
|
emacs: &'b Token<'s>,
|
||||||
rust_children: &'x Vec<RC>,
|
rust_children: &'x [RC],
|
||||||
child_status: &mut Vec<DiffEntry<'b, 's>>,
|
child_status: &mut Vec<DiffEntry<'b, 's>>,
|
||||||
this_status: &mut DiffStatus,
|
this_status: &mut DiffStatus,
|
||||||
message: &mut Option<String>,
|
message: &mut Option<String>,
|
||||||
|
|||||||
@@ -71,9 +71,7 @@ pub struct EntityDefinition<'a> {
|
|||||||
|
|
||||||
impl<'g, 's> GlobalSettings<'g, 's> {
|
impl<'g, 's> GlobalSettings<'g, 's> {
|
||||||
fn new() -> GlobalSettings<'g, 's> {
|
fn new() -> GlobalSettings<'g, 's> {
|
||||||
debug_assert!(
|
debug_assert!(DEFAULT_ORG_ENTITIES.is_sorted_by(|a, b| a.name.len() >= b.name.len()));
|
||||||
DEFAULT_ORG_ENTITIES.is_sorted_by(|a, b| b.name.len().partial_cmp(&a.name.len()))
|
|
||||||
);
|
|
||||||
GlobalSettings {
|
GlobalSettings {
|
||||||
radio_targets: Vec::new(),
|
radio_targets: Vec::new(),
|
||||||
file_access: &LocalFileAccessInterface {
|
file_access: &LocalFileAccessInterface {
|
||||||
|
|||||||
@@ -6,9 +6,9 @@ pub(crate) type Res<T, U> = IResult<T, U, CustomError>;
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum CustomError {
|
pub enum CustomError {
|
||||||
Static(&'static str),
|
Static(#[allow(dead_code)] &'static str),
|
||||||
IO(std::io::Error),
|
IO(#[allow(dead_code)] std::io::Error),
|
||||||
Parser(ErrorKind),
|
Parser(#[allow(dead_code)] ErrorKind),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I: std::fmt::Debug> ParseError<I> for CustomError {
|
impl<I: std::fmt::Debug> ParseError<I> for CustomError {
|
||||||
|
|||||||
@@ -24,10 +24,10 @@ pub(crate) fn record_event(event_type: EventType, input: OrgSource<'_>) {
|
|||||||
*db.entry(key).or_insert(0) += 1;
|
*db.entry(key).or_insert(0) += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn report(original_document: &str) {
|
pub(crate) fn report(original_document: &str) {
|
||||||
let mut db = GLOBAL_DATA.lock().unwrap();
|
let mut db = GLOBAL_DATA.lock().unwrap();
|
||||||
let db = db.get_or_insert_with(HashMap::new);
|
let db = db.get_or_insert_with(HashMap::new);
|
||||||
let mut results: Vec<_> = db.iter().map(|(k, v)| (k, v)).collect();
|
let mut results: Vec<_> = db.iter().collect();
|
||||||
results.sort_by_key(|(_k, v)| *v);
|
results.sort_by_key(|(_k, v)| *v);
|
||||||
// This would put the most common at the top, but that is a pain when there is already a lot of output from the parser.
|
// This would put the most common at the top, but that is a pain when there is already a lot of output from the parser.
|
||||||
// results.sort_by(|(_ak, av), (_bk, bv)| bv.cmp(av));
|
// results.sort_by(|(_ak, av), (_bk, bv)| bv.cmp(av));
|
||||||
|
|||||||
@@ -2,5 +2,5 @@ mod database;
|
|||||||
mod event_type;
|
mod event_type;
|
||||||
|
|
||||||
pub(crate) use database::record_event;
|
pub(crate) use database::record_event;
|
||||||
pub use database::report;
|
pub(crate) use database::report;
|
||||||
pub(crate) use event_type::EventType;
|
pub(crate) use event_type::EventType;
|
||||||
|
|||||||
14
src/lib.rs
14
src/lib.rs
@@ -1,8 +1,9 @@
|
|||||||
#![feature(exit_status_error)]
|
#![feature(exit_status_error)]
|
||||||
#![feature(trait_alias)]
|
#![feature(trait_alias)]
|
||||||
#![feature(path_file_prefix)]
|
#![feature(path_file_prefix)]
|
||||||
#![feature(is_sorted)]
|
|
||||||
#![feature(test)]
|
#![feature(test)]
|
||||||
|
#![feature(iter_intersperse)]
|
||||||
|
#![feature(exact_size_is_empty)]
|
||||||
// TODO: #![warn(missing_docs)]
|
// TODO: #![warn(missing_docs)]
|
||||||
#![allow(clippy::bool_assert_comparison)] // Sometimes you want the long form because its easier to see at a glance.
|
#![allow(clippy::bool_assert_comparison)] // Sometimes you want the long form because its easier to see at a glance.
|
||||||
|
|
||||||
@@ -10,11 +11,20 @@ extern crate test;
|
|||||||
|
|
||||||
#[cfg(feature = "compare")]
|
#[cfg(feature = "compare")]
|
||||||
pub mod compare;
|
pub mod compare;
|
||||||
|
pub mod parse_cli;
|
||||||
|
#[cfg(any(feature = "compare", feature = "wasm", feature = "wasm_test"))]
|
||||||
|
mod util;
|
||||||
|
#[cfg(any(feature = "wasm", feature = "wasm_test"))]
|
||||||
|
mod wasm;
|
||||||
|
#[cfg(any(feature = "wasm", feature = "wasm_test"))]
|
||||||
|
pub mod wasm_cli;
|
||||||
|
#[cfg(feature = "wasm_test")]
|
||||||
|
pub mod wasm_test;
|
||||||
|
|
||||||
mod context;
|
mod context;
|
||||||
mod error;
|
mod error;
|
||||||
#[cfg(feature = "event_count")]
|
#[cfg(feature = "event_count")]
|
||||||
pub mod event_count;
|
mod event_count;
|
||||||
mod iter;
|
mod iter;
|
||||||
pub mod parser;
|
pub mod parser;
|
||||||
pub mod types;
|
pub mod types;
|
||||||
|
|||||||
62
src/main.rs
62
src/main.rs
@@ -1,12 +1,4 @@
|
|||||||
#![feature(round_char_boundary)]
|
use organic::parse_cli::main_body;
|
||||||
#![feature(exact_size_is_empty)]
|
|
||||||
use std::io::Read;
|
|
||||||
use std::path::Path;
|
|
||||||
|
|
||||||
use ::organic::parser::parse;
|
|
||||||
use organic::parser::parse_with_settings;
|
|
||||||
use organic::settings::GlobalSettings;
|
|
||||||
use organic::settings::LocalFileAccessInterface;
|
|
||||||
|
|
||||||
#[cfg(feature = "tracing")]
|
#[cfg(feature = "tracing")]
|
||||||
use crate::init_tracing::init_telemetry;
|
use crate::init_tracing::init_telemetry;
|
||||||
@@ -30,55 +22,3 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
main_body_result
|
main_body_result
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
|
||||||
fn main_body() -> Result<(), Box<dyn std::error::Error>> {
|
|
||||||
let args = std::env::args().skip(1);
|
|
||||||
if args.is_empty() {
|
|
||||||
let org_contents = read_stdin_to_string()?;
|
|
||||||
run_anonymous_parse(org_contents)
|
|
||||||
} else {
|
|
||||||
for arg in args {
|
|
||||||
run_parse_on_file(arg)?
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn read_stdin_to_string() -> Result<String, Box<dyn std::error::Error>> {
|
|
||||||
let mut stdin_contents = String::new();
|
|
||||||
std::io::stdin()
|
|
||||||
.lock()
|
|
||||||
.read_to_string(&mut stdin_contents)?;
|
|
||||||
Ok(stdin_contents)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn run_anonymous_parse<P: AsRef<str>>(org_contents: P) -> Result<(), Box<dyn std::error::Error>> {
|
|
||||||
let org_contents = org_contents.as_ref();
|
|
||||||
let rust_parsed = parse(org_contents)?;
|
|
||||||
println!("{:#?}", rust_parsed);
|
|
||||||
#[cfg(feature = "event_count")]
|
|
||||||
organic::event_count::report(org_contents);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn run_parse_on_file<P: AsRef<Path>>(org_path: P) -> Result<(), Box<dyn std::error::Error>> {
|
|
||||||
let org_path = org_path.as_ref();
|
|
||||||
let parent_directory = org_path
|
|
||||||
.parent()
|
|
||||||
.ok_or("Should be contained inside a directory.")?;
|
|
||||||
let org_contents = std::fs::read_to_string(org_path)?;
|
|
||||||
let org_contents = org_contents.as_str();
|
|
||||||
let file_access_interface = LocalFileAccessInterface {
|
|
||||||
working_directory: Some(parent_directory.to_path_buf()),
|
|
||||||
};
|
|
||||||
let global_settings = GlobalSettings {
|
|
||||||
file_access: &file_access_interface,
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
let rust_parsed = parse_with_settings(org_contents, &global_settings)?;
|
|
||||||
println!("{:#?}", rust_parsed);
|
|
||||||
#[cfg(feature = "event_count")]
|
|
||||||
organic::event_count::report(org_contents);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|||||||
59
src/parse_cli/mod.rs
Normal file
59
src/parse_cli/mod.rs
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
use std::io::Read;
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
|
use crate::parser::parse;
|
||||||
|
use crate::parser::parse_with_settings;
|
||||||
|
use crate::settings::GlobalSettings;
|
||||||
|
use crate::settings::LocalFileAccessInterface;
|
||||||
|
|
||||||
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
|
pub fn main_body() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
let args = std::env::args().skip(1);
|
||||||
|
if args.is_empty() {
|
||||||
|
let org_contents = read_stdin_to_string()?;
|
||||||
|
run_anonymous_parse(org_contents)
|
||||||
|
} else {
|
||||||
|
for arg in args {
|
||||||
|
run_parse_on_file(arg)?
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_stdin_to_string() -> Result<String, Box<dyn std::error::Error>> {
|
||||||
|
let mut stdin_contents = String::new();
|
||||||
|
std::io::stdin()
|
||||||
|
.lock()
|
||||||
|
.read_to_string(&mut stdin_contents)?;
|
||||||
|
Ok(stdin_contents)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn run_anonymous_parse<P: AsRef<str>>(org_contents: P) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
let org_contents = org_contents.as_ref();
|
||||||
|
let rust_parsed = parse(org_contents)?;
|
||||||
|
println!("{:#?}", rust_parsed);
|
||||||
|
#[cfg(feature = "event_count")]
|
||||||
|
crate::event_count::report(org_contents);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn run_parse_on_file<P: AsRef<Path>>(org_path: P) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
let org_path = org_path.as_ref();
|
||||||
|
let parent_directory = org_path
|
||||||
|
.parent()
|
||||||
|
.ok_or("Should be contained inside a directory.")?;
|
||||||
|
let org_contents = std::fs::read_to_string(org_path)?;
|
||||||
|
let org_contents = org_contents.as_str();
|
||||||
|
let file_access_interface = LocalFileAccessInterface {
|
||||||
|
working_directory: Some(parent_directory.to_path_buf()),
|
||||||
|
};
|
||||||
|
let global_settings = GlobalSettings {
|
||||||
|
file_access: &file_access_interface,
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
let rust_parsed = parse_with_settings(org_contents, &global_settings)?;
|
||||||
|
println!("{:#?}", rust_parsed);
|
||||||
|
#[cfg(feature = "event_count")]
|
||||||
|
crate::event_count::report(org_contents);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
@@ -4,7 +4,6 @@ use nom::bytes::complete::tag_no_case;
|
|||||||
use nom::character::complete::anychar;
|
use nom::character::complete::anychar;
|
||||||
use nom::character::complete::one_of;
|
use nom::character::complete::one_of;
|
||||||
use nom::character::complete::space0;
|
use nom::character::complete::space0;
|
||||||
use nom::combinator::consumed;
|
|
||||||
use nom::combinator::opt;
|
use nom::combinator::opt;
|
||||||
use nom::combinator::peek;
|
use nom::combinator::peek;
|
||||||
use nom::combinator::recognize;
|
use nom::combinator::recognize;
|
||||||
@@ -43,32 +42,10 @@ where
|
|||||||
start_of_line(remaining)?;
|
start_of_line(remaining)?;
|
||||||
let (remaining, _) = tuple((space0, tag("#+"), tag_no_case("call"), tag(":")))(remaining)?;
|
let (remaining, _) = tuple((space0, tag("#+"), tag_no_case("call"), tag(":")))(remaining)?;
|
||||||
|
|
||||||
if let Ok((remaining, (_, line_break))) = tuple((space0, org_line_ending))(remaining) {
|
|
||||||
let (remaining, _trailing_ws) =
|
|
||||||
maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?;
|
|
||||||
let source = get_consumed(input, remaining);
|
|
||||||
return Ok((
|
|
||||||
remaining,
|
|
||||||
BabelCall {
|
|
||||||
source: Into::<&str>::into(source),
|
|
||||||
affiliated_keywords: parse_affiliated_keywords(
|
|
||||||
context.get_global_settings(),
|
|
||||||
affiliated_keywords,
|
|
||||||
),
|
|
||||||
value: Into::<&str>::into(line_break.take(0)),
|
|
||||||
call: None,
|
|
||||||
inside_header: None,
|
|
||||||
arguments: None,
|
|
||||||
end_header: None,
|
|
||||||
},
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
let (remaining, _ws) = space0(remaining)?;
|
let (remaining, _ws) = space0(remaining)?;
|
||||||
let (remaining, (value, babel_call_value)) = consumed(babel_call_value)(remaining)?;
|
let (remaining, babel_call_value) = babel_call_value(remaining)?;
|
||||||
let (remaining, _ws) = tuple((space0, org_line_ending))(remaining)?;
|
|
||||||
|
|
||||||
let (remaining, _trailing_ws) =
|
let (remaining, post_blank) =
|
||||||
maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?;
|
maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?;
|
||||||
let source = get_consumed(input, remaining);
|
let source = get_consumed(input, remaining);
|
||||||
|
|
||||||
@@ -80,17 +57,22 @@ where
|
|||||||
context.get_global_settings(),
|
context.get_global_settings(),
|
||||||
affiliated_keywords,
|
affiliated_keywords,
|
||||||
),
|
),
|
||||||
value: Into::<&str>::into(value).trim_end(),
|
value: Into::<&str>::into(babel_call_value.value),
|
||||||
call: babel_call_value.call.map(Into::<&str>::into),
|
call: babel_call_value.call.map(Into::<&str>::into),
|
||||||
inside_header: babel_call_value.inside_header.map(Into::<&str>::into),
|
inside_header: babel_call_value.inside_header.map(Into::<&str>::into),
|
||||||
arguments: babel_call_value.arguments.map(Into::<&str>::into),
|
arguments: babel_call_value.arguments.map(Into::<&str>::into),
|
||||||
end_header: babel_call_value.end_header.map(Into::<&str>::into),
|
end_header: babel_call_value.end_header.map(Into::<&str>::into),
|
||||||
|
post_blank: post_blank.map(Into::<&str>::into),
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct BabelCallValue<'s> {
|
struct BabelCallValue<'s> {
|
||||||
|
/// The entire string to the right of "#+call: " without the trailing line break.
|
||||||
|
value: OrgSource<'s>,
|
||||||
|
|
||||||
|
/// The function name which may contain a line break if there are no headers/arguments.
|
||||||
call: Option<OrgSource<'s>>,
|
call: Option<OrgSource<'s>>,
|
||||||
inside_header: Option<OrgSource<'s>>,
|
inside_header: Option<OrgSource<'s>>,
|
||||||
arguments: Option<OrgSource<'s>>,
|
arguments: Option<OrgSource<'s>>,
|
||||||
@@ -99,13 +81,45 @@ struct BabelCallValue<'s> {
|
|||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
fn babel_call_value<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, BabelCallValue<'s>> {
|
fn babel_call_value<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, BabelCallValue<'s>> {
|
||||||
let (remaining, call) = opt(babel_call_call)(input)?;
|
alt((
|
||||||
let (remaining, inside_header) = opt(inside_header)(remaining)?;
|
babel_call_value_without_headers,
|
||||||
let (remaining, arguments) = opt(arguments)(remaining)?;
|
babel_call_value_with_headers,
|
||||||
let (remaining, end_header) = opt(end_header)(remaining)?;
|
))(input)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
|
fn babel_call_value_without_headers<'s>(
|
||||||
|
input: OrgSource<'s>,
|
||||||
|
) -> Res<OrgSource<'s>, BabelCallValue<'s>> {
|
||||||
|
let (remaining, value) = babel_call_call_with_headers(input)?;
|
||||||
|
let (remaining, _ws) = tuple((space0, org_line_ending))(remaining)?;
|
||||||
|
let call = get_consumed(input, remaining);
|
||||||
Ok((
|
Ok((
|
||||||
remaining,
|
remaining,
|
||||||
BabelCallValue {
|
BabelCallValue {
|
||||||
|
value,
|
||||||
|
call: Some(call),
|
||||||
|
inside_header: None,
|
||||||
|
arguments: None,
|
||||||
|
end_header: None,
|
||||||
|
},
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
|
fn babel_call_value_with_headers<'s>(
|
||||||
|
input: OrgSource<'s>,
|
||||||
|
) -> Res<OrgSource<'s>, BabelCallValue<'s>> {
|
||||||
|
let (remaining, call) = opt(babel_call_call_with_headers)(input)?;
|
||||||
|
let (remaining, inside_header) = opt(inside_header)(remaining)?;
|
||||||
|
let (remaining, arguments) = opt(arguments)(remaining)?;
|
||||||
|
let (remaining, end_header) = opt(end_header)(remaining)?;
|
||||||
|
let value = get_consumed(input, remaining);
|
||||||
|
let (remaining, _ws) = tuple((space0, org_line_ending))(remaining)?;
|
||||||
|
Ok((
|
||||||
|
remaining,
|
||||||
|
BabelCallValue {
|
||||||
|
value,
|
||||||
call,
|
call,
|
||||||
inside_header,
|
inside_header,
|
||||||
arguments: arguments.flatten(),
|
arguments: arguments.flatten(),
|
||||||
@@ -115,14 +129,15 @@ fn babel_call_value<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, BabelCallVal
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
fn babel_call_call<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
fn babel_call_call_with_headers<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||||
|
// When babel call contains no arguments or headers (for example: "#+call: lorem ipsum\n") then the trailing line break is part of the call. Otherwise, it is not.
|
||||||
verify(
|
verify(
|
||||||
recognize(many_till(
|
recognize(many_till(
|
||||||
anychar,
|
anychar,
|
||||||
alt((
|
peek(alt((
|
||||||
peek(recognize(one_of("[("))),
|
recognize(one_of("[(")),
|
||||||
recognize(tuple((space0, org_line_ending))),
|
recognize(tuple((space0, org_line_ending))),
|
||||||
)),
|
))),
|
||||||
)),
|
)),
|
||||||
|s| s.len() > 0,
|
|s| s.len() > 0,
|
||||||
)(input)
|
)(input)
|
||||||
@@ -232,19 +247,3 @@ fn impl_balanced_bracket<
|
|||||||
};
|
};
|
||||||
Ok((remaining, contents))
|
Ok((remaining, contents))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use nom::combinator::opt;
|
|
||||||
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn simple_call() -> Result<(), Box<dyn std::error::Error>> {
|
|
||||||
let input = OrgSource::new("()");
|
|
||||||
let (remaining, call) = opt(babel_call_call)(input)?;
|
|
||||||
assert_eq!(Into::<&str>::into(remaining), "()");
|
|
||||||
assert!(call.is_none());
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -63,6 +63,7 @@ pub(crate) fn broken_end<'b, 'g, 'r, 's>(
|
|||||||
match paragraph.children.first_mut() {
|
match paragraph.children.first_mut() {
|
||||||
Some(Object::PlainText(plain_text)) => {
|
Some(Object::PlainText(plain_text)) => {
|
||||||
plain_text.source = input.get_until_end_of_str(plain_text.source).into();
|
plain_text.source = input.get_until_end_of_str(plain_text.source).into();
|
||||||
|
paragraph.contents = Some(input.get_until_end_of_str(plain_text.source).into());
|
||||||
}
|
}
|
||||||
Some(obj) => {
|
Some(obj) => {
|
||||||
panic!("Unhandled first object type inside bullshitium {:?}", obj);
|
panic!("Unhandled first object type inside bullshitium {:?}", obj);
|
||||||
@@ -73,14 +74,18 @@ pub(crate) fn broken_end<'b, 'g, 'r, 's>(
|
|||||||
};
|
};
|
||||||
Ok((remaining, paragraph))
|
Ok((remaining, paragraph))
|
||||||
} else {
|
} else {
|
||||||
let (remaining, _trailing_ws) =
|
let (remaining, post_blank) =
|
||||||
maybe_consume_trailing_whitespace_if_not_exiting(context, lead_in_remaining)?;
|
maybe_consume_trailing_whitespace_if_not_exiting(context, lead_in_remaining)?;
|
||||||
|
|
||||||
|
let body = Into::<&str>::into(input.get_until(lead_in_remaining));
|
||||||
|
|
||||||
Ok((
|
Ok((
|
||||||
remaining,
|
remaining,
|
||||||
Paragraph::of_text(
|
Paragraph::of_text(
|
||||||
input.get_until(remaining).into(),
|
input.get_until(remaining).into(),
|
||||||
input.get_until(lead_in_remaining).into(),
|
body,
|
||||||
|
if !body.is_empty() { Some(body) } else { None },
|
||||||
|
post_blank.map(Into::<&str>::into),
|
||||||
),
|
),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
@@ -119,6 +124,7 @@ pub(crate) fn broken_dynamic_block<'b, 'g, 'r, 's>(
|
|||||||
match paragraph.children.first_mut() {
|
match paragraph.children.first_mut() {
|
||||||
Some(Object::PlainText(plain_text)) => {
|
Some(Object::PlainText(plain_text)) => {
|
||||||
plain_text.source = input.get_until_end_of_str(plain_text.source).into();
|
plain_text.source = input.get_until_end_of_str(plain_text.source).into();
|
||||||
|
paragraph.contents = Some(input.get_until_end_of_str(plain_text.source).into());
|
||||||
}
|
}
|
||||||
Some(obj) => {
|
Some(obj) => {
|
||||||
panic!("Unhandled first object type inside bullshitium {:?}", obj);
|
panic!("Unhandled first object type inside bullshitium {:?}", obj);
|
||||||
@@ -129,14 +135,18 @@ pub(crate) fn broken_dynamic_block<'b, 'g, 'r, 's>(
|
|||||||
};
|
};
|
||||||
Ok((remaining, paragraph))
|
Ok((remaining, paragraph))
|
||||||
} else {
|
} else {
|
||||||
let (remaining, _trailing_ws) =
|
let (remaining, post_blank) =
|
||||||
maybe_consume_trailing_whitespace_if_not_exiting(context, lead_in_remaining)?;
|
maybe_consume_trailing_whitespace_if_not_exiting(context, lead_in_remaining)?;
|
||||||
|
|
||||||
|
let body = Into::<&str>::into(input.get_until(lead_in_remaining));
|
||||||
|
|
||||||
Ok((
|
Ok((
|
||||||
remaining,
|
remaining,
|
||||||
Paragraph::of_text(
|
Paragraph::of_text(
|
||||||
input.get_until(remaining).into(),
|
input.get_until(remaining).into(),
|
||||||
input.get_until(lead_in_remaining).into(),
|
body,
|
||||||
|
if !body.is_empty() { Some(body) } else { None },
|
||||||
|
post_blank.map(Into::<&str>::into),
|
||||||
),
|
),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ pub(crate) fn clock<'b, 'g, 'r, 's>(
|
|||||||
let (remaining, (timestamp, duration)) = clock_timestamp(context, remaining)?;
|
let (remaining, (timestamp, duration)) = clock_timestamp(context, remaining)?;
|
||||||
let (remaining, _) = tuple((space0, org_line_ending))(remaining)?;
|
let (remaining, _) = tuple((space0, org_line_ending))(remaining)?;
|
||||||
|
|
||||||
let (remaining, _trailing_ws) =
|
let (remaining, post_blank) =
|
||||||
maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?;
|
maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?;
|
||||||
let source = get_consumed(input, remaining);
|
let source = get_consumed(input, remaining);
|
||||||
Ok((
|
Ok((
|
||||||
@@ -54,6 +54,7 @@ pub(crate) fn clock<'b, 'g, 'r, 's>(
|
|||||||
} else {
|
} else {
|
||||||
ClockStatus::Running
|
ClockStatus::Running
|
||||||
},
|
},
|
||||||
|
post_blank: post_blank.map(Into::<&str>::into),
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
@@ -81,7 +82,7 @@ fn clock_timestamp<'b, 'g, 'r, 's>(
|
|||||||
|(timestamp, duration)| (timestamp, duration.map(Into::<&str>::into)),
|
|(timestamp, duration)| (timestamp, duration.map(Into::<&str>::into)),
|
||||||
),
|
),
|
||||||
map(
|
map(
|
||||||
parser_with_context!(inactive_timestamp)(context),
|
parser_with_context!(inactive_timestamp(true))(context),
|
||||||
|timestamp| (timestamp, None),
|
|timestamp| (timestamp, None),
|
||||||
),
|
),
|
||||||
))(input)
|
))(input)
|
||||||
|
|||||||
@@ -106,7 +106,6 @@ mod tests {
|
|||||||
use super::*;
|
use super::*;
|
||||||
use crate::context::bind_context;
|
use crate::context::bind_context;
|
||||||
use crate::context::Context;
|
use crate::context::Context;
|
||||||
use crate::context::ContextElement;
|
|
||||||
use crate::context::GlobalSettings;
|
use crate::context::GlobalSettings;
|
||||||
use crate::context::List;
|
use crate::context::List;
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ where
|
|||||||
let (remaining, value) = recognize(tuple((tag("%%("), is_not("\r\n"))))(remaining)?;
|
let (remaining, value) = recognize(tuple((tag("%%("), is_not("\r\n"))))(remaining)?;
|
||||||
let (remaining, _eol) = org_line_ending(remaining)?;
|
let (remaining, _eol) = org_line_ending(remaining)?;
|
||||||
|
|
||||||
let (remaining, _trailing_ws) =
|
let (remaining, post_blank) =
|
||||||
maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?;
|
maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?;
|
||||||
let source = get_consumed(input, remaining);
|
let source = get_consumed(input, remaining);
|
||||||
Ok((
|
Ok((
|
||||||
@@ -43,6 +43,7 @@ where
|
|||||||
affiliated_keywords,
|
affiliated_keywords,
|
||||||
),
|
),
|
||||||
value: Into::<&str>::into(value),
|
value: Into::<&str>::into(value),
|
||||||
|
post_blank: post_blank.map(Into::<&str>::into),
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ use std::path::Path;
|
|||||||
use nom::combinator::all_consuming;
|
use nom::combinator::all_consuming;
|
||||||
use nom::combinator::opt;
|
use nom::combinator::opt;
|
||||||
use nom::multi::many0;
|
use nom::multi::many0;
|
||||||
|
use nom::InputTake;
|
||||||
|
|
||||||
use super::headline::heading;
|
use super::headline::heading;
|
||||||
use super::in_buffer_settings::apply_in_buffer_settings;
|
use super::in_buffer_settings::apply_in_buffer_settings;
|
||||||
@@ -181,8 +182,10 @@ fn _document<'b, 'g, 'r, 's>(
|
|||||||
let zeroth_section_matcher = parser_with_context!(zeroth_section)(context);
|
let zeroth_section_matcher = parser_with_context!(zeroth_section)(context);
|
||||||
let heading_matcher = parser_with_context!(heading(0))(context);
|
let heading_matcher = parser_with_context!(heading(0))(context);
|
||||||
let (remaining, _blank_lines) = many0(blank_line)(input)?;
|
let (remaining, _blank_lines) = many0(blank_line)(input)?;
|
||||||
|
let contents_begin = remaining;
|
||||||
let (remaining, zeroth_section) = opt(zeroth_section_matcher)(remaining)?;
|
let (remaining, zeroth_section) = opt(zeroth_section_matcher)(remaining)?;
|
||||||
let (remaining, children) = many0(heading_matcher)(remaining)?;
|
let (remaining, children) = many0(heading_matcher)(remaining)?;
|
||||||
|
let contents = get_consumed(contents_begin, remaining);
|
||||||
let source = get_consumed(input, remaining);
|
let source = get_consumed(input, remaining);
|
||||||
Ok((
|
Ok((
|
||||||
remaining,
|
remaining,
|
||||||
@@ -192,6 +195,11 @@ fn _document<'b, 'g, 'r, 's>(
|
|||||||
path: None,
|
path: None,
|
||||||
zeroth_section,
|
zeroth_section,
|
||||||
children,
|
children,
|
||||||
|
contents: if contents.len() > 0 {
|
||||||
|
Into::<&str>::into(contents)
|
||||||
|
} else {
|
||||||
|
Into::<&str>::into(remaining.take(0))
|
||||||
|
},
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ use nom::bytes::complete::tag_no_case;
|
|||||||
use nom::bytes::complete::take_while;
|
use nom::bytes::complete::take_while;
|
||||||
use nom::character::complete::line_ending;
|
use nom::character::complete::line_ending;
|
||||||
use nom::character::complete::space0;
|
use nom::character::complete::space0;
|
||||||
|
use nom::combinator::consumed;
|
||||||
use nom::combinator::eof;
|
use nom::combinator::eof;
|
||||||
use nom::combinator::not;
|
use nom::combinator::not;
|
||||||
use nom::combinator::recognize;
|
use nom::combinator::recognize;
|
||||||
@@ -12,7 +13,9 @@ use nom::sequence::tuple;
|
|||||||
|
|
||||||
use super::affiliated_keyword::parse_affiliated_keywords;
|
use super::affiliated_keyword::parse_affiliated_keywords;
|
||||||
use super::org_source::OrgSource;
|
use super::org_source::OrgSource;
|
||||||
|
use super::paragraph::empty_paragraph;
|
||||||
use super::util::maybe_consume_trailing_whitespace_if_not_exiting;
|
use super::util::maybe_consume_trailing_whitespace_if_not_exiting;
|
||||||
|
use crate::context::bind_context;
|
||||||
use crate::context::parser_with_context;
|
use crate::context::parser_with_context;
|
||||||
use crate::context::ContextElement;
|
use crate::context::ContextElement;
|
||||||
use crate::context::ExitClass;
|
use crate::context::ExitClass;
|
||||||
@@ -21,7 +24,6 @@ use crate::context::RefContext;
|
|||||||
use crate::error::CustomError;
|
use crate::error::CustomError;
|
||||||
use crate::error::Res;
|
use crate::error::Res;
|
||||||
use crate::parser::element_parser::element;
|
use crate::parser::element_parser::element;
|
||||||
use crate::parser::util::blank_line;
|
|
||||||
use crate::parser::util::exit_matcher_parser;
|
use crate::parser::util::exit_matcher_parser;
|
||||||
use crate::parser::util::get_consumed;
|
use crate::parser::util::get_consumed;
|
||||||
use crate::parser::util::immediate_in_section;
|
use crate::parser::util::immediate_in_section;
|
||||||
@@ -30,7 +32,6 @@ use crate::parser::util::WORD_CONSTITUENT_CHARACTERS;
|
|||||||
use crate::types::Drawer;
|
use crate::types::Drawer;
|
||||||
use crate::types::Element;
|
use crate::types::Element;
|
||||||
use crate::types::Keyword;
|
use crate::types::Keyword;
|
||||||
use crate::types::Paragraph;
|
|
||||||
|
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
feature = "tracing",
|
feature = "tracing",
|
||||||
@@ -70,29 +71,12 @@ where
|
|||||||
let parser_context = context.with_additional_node(&contexts[0]);
|
let parser_context = context.with_additional_node(&contexts[0]);
|
||||||
let parser_context = parser_context.with_additional_node(&contexts[1]);
|
let parser_context = parser_context.with_additional_node(&contexts[1]);
|
||||||
let parser_context = parser_context.with_additional_node(&contexts[2]);
|
let parser_context = parser_context.with_additional_node(&contexts[2]);
|
||||||
|
let (remaining, (contents, children)) =
|
||||||
|
consumed(parser_with_context!(children)(&parser_context))(remaining)?;
|
||||||
|
|
||||||
let element_matcher = parser_with_context!(element(true))(&parser_context);
|
|
||||||
let exit_matcher = parser_with_context!(exit_matcher_parser)(&parser_context);
|
|
||||||
let (remaining, children) = match tuple((
|
|
||||||
not(exit_matcher),
|
|
||||||
blank_line,
|
|
||||||
many_till(blank_line, exit_matcher),
|
|
||||||
))(remaining)
|
|
||||||
{
|
|
||||||
Ok((remain, (_not_immediate_exit, first_line, (_trailing_whitespace, _exit_contents)))) => {
|
|
||||||
let source = get_consumed(remaining, remain);
|
|
||||||
let element = Element::Paragraph(Paragraph::of_text(source.into(), first_line.into()));
|
|
||||||
(remain, vec![element])
|
|
||||||
}
|
|
||||||
Err(_) => {
|
|
||||||
let (remaining, (children, _exit_contents)) =
|
|
||||||
many_till(element_matcher, exit_matcher)(remaining)?;
|
|
||||||
(remaining, children)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let (remaining, _end) = drawer_end(&parser_context, remaining)?;
|
let (remaining, _end) = drawer_end(&parser_context, remaining)?;
|
||||||
|
|
||||||
let (remaining, _trailing_ws) =
|
let (remaining, post_blank) =
|
||||||
maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?;
|
maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?;
|
||||||
let source = get_consumed(input, remaining);
|
let source = get_consumed(input, remaining);
|
||||||
|
|
||||||
@@ -106,10 +90,34 @@ where
|
|||||||
),
|
),
|
||||||
drawer_name: drawer_name.into(),
|
drawer_name: drawer_name.into(),
|
||||||
children,
|
children,
|
||||||
|
contents: Some(contents.into()),
|
||||||
|
post_blank: post_blank.map(Into::<&str>::into),
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg_attr(
|
||||||
|
feature = "tracing",
|
||||||
|
tracing::instrument(ret, level = "debug", skip(context))
|
||||||
|
)]
|
||||||
|
fn children<'b, 'g, 'r, 's>(
|
||||||
|
context: RefContext<'b, 'g, 'r, 's>,
|
||||||
|
input: OrgSource<'s>,
|
||||||
|
) -> Res<OrgSource<'s>, Vec<Element<'s>>> {
|
||||||
|
let element_matcher = parser_with_context!(element(true))(context);
|
||||||
|
let exit_matcher = parser_with_context!(exit_matcher_parser)(context);
|
||||||
|
|
||||||
|
if let Ok((remaining, (_not_exit, empty_para))) =
|
||||||
|
tuple((not(exit_matcher), bind_context!(empty_paragraph, context)))(input)
|
||||||
|
{
|
||||||
|
return Ok((remaining, vec![Element::Paragraph(empty_para)]));
|
||||||
|
}
|
||||||
|
|
||||||
|
let (remaining, (children, _exit_contents)) = many_till(element_matcher, exit_matcher)(input)?;
|
||||||
|
|
||||||
|
Ok((remaining, children))
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
fn name<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
fn name<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||||
take_while(|c| WORD_CONSTITUENT_CHARACTERS.contains(c) || "-_".contains(c))(input)
|
take_while(|c| WORD_CONSTITUENT_CHARACTERS.contains(c) || "-_".contains(c))(input)
|
||||||
|
|||||||
@@ -6,20 +6,20 @@ use nom::character::complete::anychar;
|
|||||||
use nom::character::complete::line_ending;
|
use nom::character::complete::line_ending;
|
||||||
use nom::character::complete::space0;
|
use nom::character::complete::space0;
|
||||||
use nom::character::complete::space1;
|
use nom::character::complete::space1;
|
||||||
use nom::combinator::consumed;
|
|
||||||
use nom::combinator::eof;
|
use nom::combinator::eof;
|
||||||
use nom::combinator::not;
|
use nom::combinator::not;
|
||||||
use nom::combinator::opt;
|
use nom::combinator::opt;
|
||||||
use nom::combinator::peek;
|
use nom::combinator::peek;
|
||||||
use nom::combinator::recognize;
|
use nom::combinator::recognize;
|
||||||
use nom::multi::many0;
|
|
||||||
use nom::multi::many_till;
|
use nom::multi::many_till;
|
||||||
use nom::sequence::preceded;
|
|
||||||
use nom::sequence::tuple;
|
use nom::sequence::tuple;
|
||||||
|
|
||||||
use super::affiliated_keyword::parse_affiliated_keywords;
|
use super::affiliated_keyword::parse_affiliated_keywords;
|
||||||
|
use super::greater_block::leading_blank_lines_end;
|
||||||
use super::org_source::OrgSource;
|
use super::org_source::OrgSource;
|
||||||
|
use super::paragraph::empty_paragraph;
|
||||||
use super::util::maybe_consume_trailing_whitespace_if_not_exiting;
|
use super::util::maybe_consume_trailing_whitespace_if_not_exiting;
|
||||||
|
use crate::context::bind_context;
|
||||||
use crate::context::parser_with_context;
|
use crate::context::parser_with_context;
|
||||||
use crate::context::ContextElement;
|
use crate::context::ContextElement;
|
||||||
use crate::context::ExitClass;
|
use crate::context::ExitClass;
|
||||||
@@ -28,7 +28,6 @@ use crate::context::RefContext;
|
|||||||
use crate::error::CustomError;
|
use crate::error::CustomError;
|
||||||
use crate::error::Res;
|
use crate::error::Res;
|
||||||
use crate::parser::element_parser::element;
|
use crate::parser::element_parser::element;
|
||||||
use crate::parser::util::blank_line;
|
|
||||||
use crate::parser::util::exit_matcher_parser;
|
use crate::parser::util::exit_matcher_parser;
|
||||||
use crate::parser::util::get_consumed;
|
use crate::parser::util::get_consumed;
|
||||||
use crate::parser::util::immediate_in_section;
|
use crate::parser::util::immediate_in_section;
|
||||||
@@ -36,7 +35,6 @@ use crate::parser::util::start_of_line;
|
|||||||
use crate::types::DynamicBlock;
|
use crate::types::DynamicBlock;
|
||||||
use crate::types::Element;
|
use crate::types::Element;
|
||||||
use crate::types::Keyword;
|
use crate::types::Keyword;
|
||||||
use crate::types::Paragraph;
|
|
||||||
|
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
feature = "tracing",
|
feature = "tracing",
|
||||||
@@ -81,23 +79,25 @@ where
|
|||||||
let element_matcher = parser_with_context!(element(true))(&parser_context);
|
let element_matcher = parser_with_context!(element(true))(&parser_context);
|
||||||
let exit_matcher = parser_with_context!(exit_matcher_parser)(&parser_context);
|
let exit_matcher = parser_with_context!(exit_matcher_parser)(&parser_context);
|
||||||
not(exit_matcher)(remaining)?;
|
not(exit_matcher)(remaining)?;
|
||||||
let (remaining, leading_blank_lines) = opt(consumed(tuple((
|
let contents_begin = remaining;
|
||||||
blank_line,
|
let blank_line_context = ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||||
many0(preceded(not(exit_matcher), blank_line)),
|
class: ExitClass::Alpha,
|
||||||
))))(remaining)?;
|
exit_matcher: &leading_blank_lines_end,
|
||||||
let leading_blank_lines =
|
|
||||||
leading_blank_lines.map(|(source, (first_line, _remaining_lines))| {
|
|
||||||
Element::Paragraph(Paragraph::of_text(source.into(), first_line.into()))
|
|
||||||
});
|
});
|
||||||
|
let blank_line_context = parser_context.with_additional_node(&blank_line_context);
|
||||||
|
|
||||||
|
let (remaining, leading_blank_lines) =
|
||||||
|
opt(bind_context!(empty_paragraph, &blank_line_context))(remaining)?;
|
||||||
let (remaining, (mut children, _exit_contents)) =
|
let (remaining, (mut children, _exit_contents)) =
|
||||||
many_till(element_matcher, exit_matcher)(remaining)?;
|
many_till(element_matcher, exit_matcher)(remaining)?;
|
||||||
if let Some(lines) = leading_blank_lines {
|
if let Some(lines) = leading_blank_lines {
|
||||||
children.insert(0, lines);
|
children.insert(0, Element::Paragraph(lines));
|
||||||
}
|
}
|
||||||
|
let contents = get_consumed(contents_begin, remaining);
|
||||||
|
|
||||||
let (remaining, _end) = dynamic_block_end(&parser_context, remaining)?;
|
let (remaining, _end) = dynamic_block_end(&parser_context, remaining)?;
|
||||||
|
|
||||||
let (remaining, _trailing_ws) =
|
let (remaining, post_blank) =
|
||||||
maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?;
|
maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?;
|
||||||
let source = get_consumed(input, remaining);
|
let source = get_consumed(input, remaining);
|
||||||
Ok((
|
Ok((
|
||||||
@@ -111,6 +111,12 @@ where
|
|||||||
block_name: name.into(),
|
block_name: name.into(),
|
||||||
parameters: parameters.map(|val| val.into()),
|
parameters: parameters.map(|val| val.into()),
|
||||||
children,
|
children,
|
||||||
|
contents: if contents.len() > 0 {
|
||||||
|
Some(Into::<&str>::into(contents))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
},
|
||||||
|
post_blank: post_blank.map(Into::<&str>::into),
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,12 +2,15 @@ use nom::branch::alt;
|
|||||||
use nom::bytes::complete::tag;
|
use nom::bytes::complete::tag;
|
||||||
use nom::character::complete::anychar;
|
use nom::character::complete::anychar;
|
||||||
use nom::character::complete::space0;
|
use nom::character::complete::space0;
|
||||||
|
use nom::combinator::map;
|
||||||
use nom::combinator::not;
|
use nom::combinator::not;
|
||||||
|
use nom::combinator::peek;
|
||||||
use nom::combinator::recognize;
|
use nom::combinator::recognize;
|
||||||
use nom::multi::many0;
|
use nom::multi::many0;
|
||||||
use nom::multi::many_till;
|
use nom::multi::many_till;
|
||||||
use nom::sequence::preceded;
|
use nom::sequence::preceded;
|
||||||
use nom::sequence::tuple;
|
use nom::sequence::tuple;
|
||||||
|
use nom::InputTake;
|
||||||
|
|
||||||
use super::affiliated_keyword::parse_affiliated_keywords;
|
use super::affiliated_keyword::parse_affiliated_keywords;
|
||||||
use super::org_source::OrgSource;
|
use super::org_source::OrgSource;
|
||||||
@@ -35,28 +38,25 @@ pub(crate) fn fixed_width_area<'b, 'g, 'r, 's, AK>(
|
|||||||
where
|
where
|
||||||
AK: IntoIterator<Item = Keyword<'s>>,
|
AK: IntoIterator<Item = Keyword<'s>>,
|
||||||
{
|
{
|
||||||
let fixed_width_area_line_matcher = parser_with_context!(fixed_width_area_line)(context);
|
|
||||||
let exit_matcher = parser_with_context!(exit_matcher_parser)(context);
|
let exit_matcher = parser_with_context!(exit_matcher_parser)(context);
|
||||||
let (remaining, first_line) = fixed_width_area_line_matcher(remaining)?;
|
let (remaining, first_line) = fixed_width_area_line(remaining)?;
|
||||||
let (remaining, mut remaining_lines) =
|
let (remaining, remaining_lines) = many0(preceded(
|
||||||
many0(preceded(not(exit_matcher), fixed_width_area_line_matcher))(remaining)?;
|
not(tuple((org_line_ending, exit_matcher))),
|
||||||
|
map(
|
||||||
|
tuple((org_line_ending, fixed_width_area_line)),
|
||||||
|
|(_line_ending, line_contents)| line_contents,
|
||||||
|
),
|
||||||
|
))(remaining)?;
|
||||||
|
|
||||||
let (remaining, _trailing_ws) =
|
let post_blank_begin = remaining;
|
||||||
|
let (remaining, _first_line_break) = org_line_ending(remaining)?;
|
||||||
|
let (remaining, _additional_post_blank) =
|
||||||
maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?;
|
maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?;
|
||||||
|
let post_blank = get_consumed(post_blank_begin, remaining);
|
||||||
let source = get_consumed(input, remaining);
|
let source = get_consumed(input, remaining);
|
||||||
let mut value = Vec::with_capacity(remaining_lines.len() + 1);
|
let mut value = Vec::with_capacity(remaining_lines.len() + 1);
|
||||||
let last_line = remaining_lines.pop();
|
|
||||||
if let Some(last_line) = last_line {
|
|
||||||
value.push(Into::<&str>::into(first_line));
|
value.push(Into::<&str>::into(first_line));
|
||||||
value.extend(remaining_lines.into_iter().map(Into::<&str>::into));
|
value.extend(remaining_lines.into_iter().map(Into::<&str>::into));
|
||||||
let last_line = Into::<&str>::into(last_line);
|
|
||||||
// Trim the line ending from the final line.
|
|
||||||
value.push(&last_line[..(last_line.len() - 1)])
|
|
||||||
} else {
|
|
||||||
// Trim the line ending from the only line.
|
|
||||||
let only_line = Into::<&str>::into(first_line);
|
|
||||||
value.push(&only_line[..(only_line.len() - 1)])
|
|
||||||
}
|
|
||||||
Ok((
|
Ok((
|
||||||
remaining,
|
remaining,
|
||||||
FixedWidthArea {
|
FixedWidthArea {
|
||||||
@@ -66,25 +66,24 @@ where
|
|||||||
affiliated_keywords,
|
affiliated_keywords,
|
||||||
),
|
),
|
||||||
value,
|
value,
|
||||||
|
post_blank: if post_blank.len() > 0 {
|
||||||
|
Some(Into::<&str>::into(post_blank))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
},
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
feature = "tracing",
|
fn fixed_width_area_line<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||||
tracing::instrument(ret, level = "debug", skip(_context))
|
|
||||||
)]
|
|
||||||
fn fixed_width_area_line<'b, 'g, 'r, 's>(
|
|
||||||
_context: RefContext<'b, 'g, 'r, 's>,
|
|
||||||
input: OrgSource<'s>,
|
|
||||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
|
||||||
start_of_line(input)?;
|
start_of_line(input)?;
|
||||||
let (remaining, _) = tuple((space0, tag(":")))(input)?;
|
let (remaining, _) = tuple((space0, tag(":")))(input)?;
|
||||||
if let Ok((remaining, line_break)) = org_line_ending(remaining) {
|
if let Ok((_remain, _line_break)) = org_line_ending(remaining) {
|
||||||
return Ok((remaining, line_break));
|
return Ok((remaining, remaining.take(0)));
|
||||||
}
|
}
|
||||||
let (remaining, _) = tag(" ")(remaining)?;
|
let (remaining, _) = tag(" ")(remaining)?;
|
||||||
let (remaining, value) = recognize(many_till(anychar, org_line_ending))(remaining)?;
|
let (remaining, value) = recognize(many_till(anychar, peek(org_line_ending)))(remaining)?;
|
||||||
Ok((remaining, value))
|
Ok((remaining, value))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,22 +5,21 @@ use nom::character::complete::anychar;
|
|||||||
use nom::character::complete::line_ending;
|
use nom::character::complete::line_ending;
|
||||||
use nom::character::complete::space0;
|
use nom::character::complete::space0;
|
||||||
use nom::character::complete::space1;
|
use nom::character::complete::space1;
|
||||||
use nom::combinator::consumed;
|
|
||||||
use nom::combinator::eof;
|
use nom::combinator::eof;
|
||||||
use nom::combinator::not;
|
use nom::combinator::not;
|
||||||
use nom::combinator::opt;
|
use nom::combinator::opt;
|
||||||
use nom::combinator::peek;
|
use nom::combinator::peek;
|
||||||
use nom::combinator::recognize;
|
use nom::combinator::recognize;
|
||||||
use nom::combinator::verify;
|
use nom::combinator::verify;
|
||||||
use nom::multi::many0;
|
|
||||||
use nom::multi::many_till;
|
use nom::multi::many_till;
|
||||||
use nom::sequence::preceded;
|
|
||||||
use nom::sequence::tuple;
|
use nom::sequence::tuple;
|
||||||
|
|
||||||
use super::affiliated_keyword::parse_affiliated_keywords;
|
use super::affiliated_keyword::parse_affiliated_keywords;
|
||||||
use super::org_source::OrgSource;
|
use super::org_source::OrgSource;
|
||||||
|
use super::paragraph::empty_paragraph;
|
||||||
use super::util::in_section;
|
use super::util::in_section;
|
||||||
use super::util::maybe_consume_trailing_whitespace_if_not_exiting;
|
use super::util::maybe_consume_trailing_whitespace_if_not_exiting;
|
||||||
|
use crate::context::bind_context;
|
||||||
use crate::context::parser_with_context;
|
use crate::context::parser_with_context;
|
||||||
use crate::context::ContextElement;
|
use crate::context::ContextElement;
|
||||||
use crate::context::ContextMatcher;
|
use crate::context::ContextMatcher;
|
||||||
@@ -37,7 +36,6 @@ use crate::parser::util::start_of_line;
|
|||||||
use crate::types::CenterBlock;
|
use crate::types::CenterBlock;
|
||||||
use crate::types::Element;
|
use crate::types::Element;
|
||||||
use crate::types::Keyword;
|
use crate::types::Keyword;
|
||||||
use crate::types::Paragraph;
|
|
||||||
use crate::types::QuoteBlock;
|
use crate::types::QuoteBlock;
|
||||||
use crate::types::SpecialBlock;
|
use crate::types::SpecialBlock;
|
||||||
|
|
||||||
@@ -102,7 +100,7 @@ fn center_block<'b, 'g, 'r, 's, AK>(
|
|||||||
where
|
where
|
||||||
AK: IntoIterator<Item = Keyword<'s>>,
|
AK: IntoIterator<Item = Keyword<'s>>,
|
||||||
{
|
{
|
||||||
let (remaining, (source, children)) = greater_block_body(
|
let (remaining, body) = greater_block_body(
|
||||||
context,
|
context,
|
||||||
input,
|
input,
|
||||||
pre_affiliated_keywords_input,
|
pre_affiliated_keywords_input,
|
||||||
@@ -112,12 +110,14 @@ where
|
|||||||
Ok((
|
Ok((
|
||||||
remaining,
|
remaining,
|
||||||
Element::CenterBlock(CenterBlock {
|
Element::CenterBlock(CenterBlock {
|
||||||
source,
|
source: body.source,
|
||||||
affiliated_keywords: parse_affiliated_keywords(
|
affiliated_keywords: parse_affiliated_keywords(
|
||||||
context.get_global_settings(),
|
context.get_global_settings(),
|
||||||
affiliated_keywords,
|
affiliated_keywords,
|
||||||
),
|
),
|
||||||
children,
|
children: body.children,
|
||||||
|
contents: body.contents,
|
||||||
|
post_blank: body.post_blank,
|
||||||
}),
|
}),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
@@ -135,7 +135,7 @@ fn quote_block<'b, 'g, 'r, 's, AK>(
|
|||||||
where
|
where
|
||||||
AK: IntoIterator<Item = Keyword<'s>>,
|
AK: IntoIterator<Item = Keyword<'s>>,
|
||||||
{
|
{
|
||||||
let (remaining, (source, children)) = greater_block_body(
|
let (remaining, body) = greater_block_body(
|
||||||
context,
|
context,
|
||||||
input,
|
input,
|
||||||
pre_affiliated_keywords_input,
|
pre_affiliated_keywords_input,
|
||||||
@@ -145,12 +145,14 @@ where
|
|||||||
Ok((
|
Ok((
|
||||||
remaining,
|
remaining,
|
||||||
Element::QuoteBlock(QuoteBlock {
|
Element::QuoteBlock(QuoteBlock {
|
||||||
source,
|
source: body.source,
|
||||||
affiliated_keywords: parse_affiliated_keywords(
|
affiliated_keywords: parse_affiliated_keywords(
|
||||||
context.get_global_settings(),
|
context.get_global_settings(),
|
||||||
affiliated_keywords,
|
affiliated_keywords,
|
||||||
),
|
),
|
||||||
children,
|
children: body.children,
|
||||||
|
contents: body.contents,
|
||||||
|
post_blank: body.post_blank,
|
||||||
}),
|
}),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
@@ -196,7 +198,7 @@ where
|
|||||||
AK: IntoIterator<Item = Keyword<'s>>,
|
AK: IntoIterator<Item = Keyword<'s>>,
|
||||||
{
|
{
|
||||||
let (remaining, parameters) = opt(tuple((space1, parameters)))(input)?;
|
let (remaining, parameters) = opt(tuple((space1, parameters)))(input)?;
|
||||||
let (remaining, (source, children)) = greater_block_body(
|
let (remaining, body) = greater_block_body(
|
||||||
context,
|
context,
|
||||||
remaining,
|
remaining,
|
||||||
pre_affiliated_keywords_input,
|
pre_affiliated_keywords_input,
|
||||||
@@ -206,18 +208,28 @@ where
|
|||||||
Ok((
|
Ok((
|
||||||
remaining,
|
remaining,
|
||||||
Element::SpecialBlock(SpecialBlock {
|
Element::SpecialBlock(SpecialBlock {
|
||||||
source,
|
source: body.source,
|
||||||
affiliated_keywords: parse_affiliated_keywords(
|
affiliated_keywords: parse_affiliated_keywords(
|
||||||
context.get_global_settings(),
|
context.get_global_settings(),
|
||||||
affiliated_keywords,
|
affiliated_keywords,
|
||||||
),
|
),
|
||||||
children,
|
children: body.children,
|
||||||
block_type: name,
|
block_type: name,
|
||||||
parameters: parameters.map(|(_, parameters)| Into::<&str>::into(parameters)),
|
parameters: parameters.map(|(_, parameters)| Into::<&str>::into(parameters)),
|
||||||
|
contents: body.contents,
|
||||||
|
post_blank: body.post_blank,
|
||||||
}),
|
}),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct GreaterBlockBody<'s> {
|
||||||
|
source: &'s str,
|
||||||
|
children: Vec<Element<'s>>,
|
||||||
|
contents: Option<&'s str>,
|
||||||
|
post_blank: Option<&'s str>,
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
feature = "tracing",
|
feature = "tracing",
|
||||||
tracing::instrument(ret, level = "debug", skip(context))
|
tracing::instrument(ret, level = "debug", skip(context))
|
||||||
@@ -228,7 +240,7 @@ fn greater_block_body<'c, 'b, 'g, 'r, 's>(
|
|||||||
pre_affiliated_keywords_input: OrgSource<'s>,
|
pre_affiliated_keywords_input: OrgSource<'s>,
|
||||||
name: &'c str,
|
name: &'c str,
|
||||||
context_name: &'c str,
|
context_name: &'c str,
|
||||||
) -> Res<OrgSource<'s>, (&'s str, Vec<Element<'s>>)> {
|
) -> Res<OrgSource<'s>, GreaterBlockBody<'s>> {
|
||||||
if in_section(context, context_name) {
|
if in_section(context, context_name) {
|
||||||
return Err(nom::Err::Error(CustomError::Static(
|
return Err(nom::Err::Error(CustomError::Static(
|
||||||
"Cannot nest objects of the same element",
|
"Cannot nest objects of the same element",
|
||||||
@@ -250,28 +262,43 @@ fn greater_block_body<'c, 'b, 'g, 'r, 's>(
|
|||||||
let element_matcher = parser_with_context!(element(true))(&parser_context);
|
let element_matcher = parser_with_context!(element(true))(&parser_context);
|
||||||
let exit_matcher = parser_with_context!(exit_matcher_parser)(&parser_context);
|
let exit_matcher = parser_with_context!(exit_matcher_parser)(&parser_context);
|
||||||
not(exit_matcher)(remaining)?;
|
not(exit_matcher)(remaining)?;
|
||||||
let (remaining, leading_blank_lines) = opt(consumed(tuple((
|
let contents_begin = remaining;
|
||||||
blank_line,
|
|
||||||
many0(preceded(not(exit_matcher), blank_line)),
|
let blank_line_context = ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||||
))))(remaining)?;
|
class: ExitClass::Alpha,
|
||||||
let leading_blank_lines =
|
exit_matcher: &leading_blank_lines_end,
|
||||||
leading_blank_lines.map(|(source, (first_line, _remaining_lines))| {
|
|
||||||
Element::Paragraph(Paragraph::of_text(source.into(), first_line.into()))
|
|
||||||
});
|
});
|
||||||
|
let blank_line_context = parser_context.with_additional_node(&blank_line_context);
|
||||||
|
|
||||||
|
let (remaining, leading_blank_lines) =
|
||||||
|
opt(bind_context!(empty_paragraph, &blank_line_context))(remaining)?;
|
||||||
let (remaining, (mut children, _exit_contents)) =
|
let (remaining, (mut children, _exit_contents)) =
|
||||||
many_till(element_matcher, exit_matcher)(remaining)?;
|
many_till(element_matcher, exit_matcher)(remaining)?;
|
||||||
if let Some(lines) = leading_blank_lines {
|
if let Some(lines) = leading_blank_lines {
|
||||||
children.insert(0, lines);
|
children.insert(0, Element::Paragraph(lines));
|
||||||
}
|
}
|
||||||
|
let contents = get_consumed(contents_begin, remaining);
|
||||||
|
|
||||||
let (remaining, _end) = exit_with_name(&parser_context, remaining)?;
|
let (remaining, _end) = exit_with_name(&parser_context, remaining)?;
|
||||||
|
|
||||||
// Not checking if parent exit matcher is causing exit because the greater_block_end matcher asserts we matched a full greater block
|
// Not checking if parent exit matcher is causing exit because the greater_block_end matcher asserts we matched a full greater block
|
||||||
|
|
||||||
let (remaining, _trailing_ws) =
|
let (remaining, post_blank) =
|
||||||
maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?;
|
maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?;
|
||||||
let source = get_consumed(pre_affiliated_keywords_input, remaining);
|
let source = get_consumed(pre_affiliated_keywords_input, remaining);
|
||||||
Ok((remaining, (Into::<&str>::into(source), children)))
|
Ok((
|
||||||
|
remaining,
|
||||||
|
GreaterBlockBody {
|
||||||
|
source: Into::<&str>::into(source),
|
||||||
|
children,
|
||||||
|
contents: if contents.len() > 0 {
|
||||||
|
Some(Into::<&str>::into(contents))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
},
|
||||||
|
post_blank: post_blank.map(Into::<&str>::into),
|
||||||
|
},
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
@@ -307,3 +334,14 @@ fn _greater_block_end<'b, 'g, 'r, 's, 'c>(
|
|||||||
let source = get_consumed(input, remaining);
|
let source = get_consumed(input, remaining);
|
||||||
Ok((remaining, source))
|
Ok((remaining, source))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg_attr(
|
||||||
|
feature = "tracing",
|
||||||
|
tracing::instrument(ret, level = "debug", skip(_context))
|
||||||
|
)]
|
||||||
|
pub(crate) fn leading_blank_lines_end<'b, 'g, 'r, 's, 'c>(
|
||||||
|
_context: RefContext<'b, 'g, 'r, 's>,
|
||||||
|
input: OrgSource<'s>,
|
||||||
|
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||||
|
recognize(not(blank_line))(input)
|
||||||
|
}
|
||||||
|
|||||||
@@ -66,6 +66,8 @@ fn _heading<'b, 'g, 'r, 's>(
|
|||||||
let (remaining, pre_headline) = headline(context, input, parent_star_count)?;
|
let (remaining, pre_headline) = headline(context, input, parent_star_count)?;
|
||||||
let section_matcher = bind_context!(section, context);
|
let section_matcher = bind_context!(section, context);
|
||||||
let heading_matcher = bind_context!(heading(pre_headline.star_count), context);
|
let heading_matcher = bind_context!(heading(pre_headline.star_count), context);
|
||||||
|
let (contents_begin, _) = opt(many0(blank_line))(remaining)?;
|
||||||
|
let maybe_post_blank = get_consumed(remaining, contents_begin);
|
||||||
let (remaining, maybe_section) =
|
let (remaining, maybe_section) =
|
||||||
opt(map(section_matcher, DocumentElement::Section))(remaining)?;
|
opt(map(section_matcher, DocumentElement::Section))(remaining)?;
|
||||||
let (remaining, _ws) = opt(tuple((start_of_line, many0(blank_line))))(remaining)?;
|
let (remaining, _ws) = opt(tuple((start_of_line, many0(blank_line))))(remaining)?;
|
||||||
@@ -75,14 +77,15 @@ fn _heading<'b, 'g, 'r, 's>(
|
|||||||
// If the section has a planning then the timestamp values are copied to the heading.
|
// If the section has a planning then the timestamp values are copied to the heading.
|
||||||
if let DocumentElement::Section(inner_section) = §ion {
|
if let DocumentElement::Section(inner_section) = §ion {
|
||||||
if let Some(Element::Planning(planning)) = inner_section.children.first() {
|
if let Some(Element::Planning(planning)) = inner_section.children.first() {
|
||||||
scheduled = planning.scheduled.clone();
|
scheduled.clone_from(&planning.scheduled);
|
||||||
deadline = planning.deadline.clone();
|
deadline.clone_from(&planning.deadline);
|
||||||
closed = planning.closed.clone();
|
closed.clone_from(&planning.closed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
children.insert(0, section);
|
children.insert(0, section);
|
||||||
}
|
}
|
||||||
let remaining = if children.is_empty() {
|
let has_children = !children.is_empty();
|
||||||
|
let remaining = if !has_children {
|
||||||
// Support empty headings
|
// Support empty headings
|
||||||
let (remain, _ws) = many0(blank_line)(remaining)?;
|
let (remain, _ws) = many0(blank_line)(remaining)?;
|
||||||
remain
|
remain
|
||||||
@@ -91,6 +94,7 @@ fn _heading<'b, 'g, 'r, 's>(
|
|||||||
};
|
};
|
||||||
let is_archived = pre_headline.tags.contains(&"ARCHIVE");
|
let is_archived = pre_headline.tags.contains(&"ARCHIVE");
|
||||||
|
|
||||||
|
let contents = get_consumed(contents_begin, remaining);
|
||||||
let source = get_consumed(input, remaining);
|
let source = get_consumed(input, remaining);
|
||||||
Ok((
|
Ok((
|
||||||
remaining,
|
remaining,
|
||||||
@@ -112,6 +116,16 @@ fn _heading<'b, 'g, 'r, 's>(
|
|||||||
scheduled,
|
scheduled,
|
||||||
deadline,
|
deadline,
|
||||||
closed,
|
closed,
|
||||||
|
contents: if contents.len() > 0 {
|
||||||
|
Some(Into::<&str>::into(contents))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
},
|
||||||
|
post_blank: if has_children {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(Into::<&str>::into(maybe_post_blank))
|
||||||
|
},
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ where
|
|||||||
space0,
|
space0,
|
||||||
alt((line_ending, eof)),
|
alt((line_ending, eof)),
|
||||||
)))(remaining)?;
|
)))(remaining)?;
|
||||||
let (remaining, _trailing_ws) =
|
let (remaining, post_blank) =
|
||||||
maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?;
|
maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?;
|
||||||
let source = get_consumed(input, remaining);
|
let source = get_consumed(input, remaining);
|
||||||
Ok((
|
Ok((
|
||||||
@@ -49,6 +49,7 @@ where
|
|||||||
context.get_global_settings(),
|
context.get_global_settings(),
|
||||||
affiliated_keywords,
|
affiliated_keywords,
|
||||||
),
|
),
|
||||||
|
post_blank: post_blank.map(Into::<&str>::into),
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -224,7 +224,6 @@ mod tests {
|
|||||||
use test::Bencher;
|
use test::Bencher;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::parser::OrgSource;
|
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn bench_affiliated_keyword(b: &mut Bencher) {
|
fn bench_affiliated_keyword(b: &mut Bencher) {
|
||||||
|
|||||||
@@ -80,22 +80,28 @@ where
|
|||||||
let object_matcher = parser_with_context!(standard_set_object)(&parser_context);
|
let object_matcher = parser_with_context!(standard_set_object)(&parser_context);
|
||||||
let exit_matcher = parser_with_context!(exit_matcher_parser)(&parser_context);
|
let exit_matcher = parser_with_context!(exit_matcher_parser)(&parser_context);
|
||||||
// Check for a completely empty block
|
// Check for a completely empty block
|
||||||
let (remaining, children) = match consumed(many_till(blank_line, exit_matcher))(remaining) {
|
let (remaining, contents, children) =
|
||||||
|
match consumed(many_till(blank_line, exit_matcher))(remaining) {
|
||||||
Ok((remaining, (whitespace, (_children, _exit_contents)))) => (
|
Ok((remaining, (whitespace, (_children, _exit_contents)))) => (
|
||||||
remaining,
|
remaining,
|
||||||
|
whitespace,
|
||||||
|
if whitespace.len() > 0 {
|
||||||
vec![Object::PlainText(PlainText {
|
vec![Object::PlainText(PlainText {
|
||||||
source: whitespace.into(),
|
source: whitespace.into(),
|
||||||
})],
|
})]
|
||||||
|
} else {
|
||||||
|
Vec::new()
|
||||||
|
},
|
||||||
),
|
),
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
let (remaining, (children, _exit_contents)) =
|
let (remaining, (contents, (children, _exit_contents))) =
|
||||||
many_till(object_matcher, exit_matcher)(remaining)?;
|
consumed(many_till(object_matcher, exit_matcher))(remaining)?;
|
||||||
(remaining, children)
|
(remaining, contents, children)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let (remaining, _end) = lesser_block_end_specialized(&parser_context, remaining)?;
|
let (remaining, _end) = lesser_block_end_specialized(&parser_context, remaining)?;
|
||||||
|
|
||||||
let (remaining, _trailing_ws) =
|
let (remaining, post_blank) =
|
||||||
maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?;
|
maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?;
|
||||||
let source = get_consumed(input, remaining);
|
let source = get_consumed(input, remaining);
|
||||||
Ok((
|
Ok((
|
||||||
@@ -108,6 +114,8 @@ where
|
|||||||
),
|
),
|
||||||
data: parameters.map(Into::<&str>::into),
|
data: parameters.map(Into::<&str>::into),
|
||||||
children,
|
children,
|
||||||
|
contents: Into::<&str>::into(contents),
|
||||||
|
post_blank: post_blank.map(Into::<&str>::into),
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
@@ -144,7 +152,7 @@ where
|
|||||||
let (remaining, contents) = parser_with_context!(text_until_exit)(&parser_context)(remaining)?;
|
let (remaining, contents) = parser_with_context!(text_until_exit)(&parser_context)(remaining)?;
|
||||||
let (remaining, _end) = lesser_block_end_specialized(&parser_context, remaining)?;
|
let (remaining, _end) = lesser_block_end_specialized(&parser_context, remaining)?;
|
||||||
|
|
||||||
let (remaining, _trailing_ws) =
|
let (remaining, post_blank) =
|
||||||
maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?;
|
maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?;
|
||||||
let source = get_consumed(input, remaining);
|
let source = get_consumed(input, remaining);
|
||||||
Ok((
|
Ok((
|
||||||
@@ -156,6 +164,7 @@ where
|
|||||||
affiliated_keywords,
|
affiliated_keywords,
|
||||||
),
|
),
|
||||||
contents: contents.into(),
|
contents: contents.into(),
|
||||||
|
post_blank: post_blank.map(Into::<&str>::into),
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
@@ -205,7 +214,7 @@ where
|
|||||||
let (remaining, contents) = text_until_exit(&parser_context, remaining)?;
|
let (remaining, contents) = text_until_exit(&parser_context, remaining)?;
|
||||||
let (remaining, _end) = lesser_block_end_specialized(&parser_context, remaining)?;
|
let (remaining, _end) = lesser_block_end_specialized(&parser_context, remaining)?;
|
||||||
|
|
||||||
let (remaining, _trailing_ws) =
|
let (remaining, post_blank) =
|
||||||
maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?;
|
maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?;
|
||||||
let source = get_consumed(input, remaining);
|
let source = get_consumed(input, remaining);
|
||||||
let (switches, number_lines, preserve_indent, retain_labels, use_labels, label_format) = {
|
let (switches, number_lines, preserve_indent, retain_labels, use_labels, label_format) = {
|
||||||
@@ -237,6 +246,7 @@ where
|
|||||||
use_labels,
|
use_labels,
|
||||||
label_format,
|
label_format,
|
||||||
value: Into::<&str>::into(contents),
|
value: Into::<&str>::into(contents),
|
||||||
|
post_blank: post_blank.map(Into::<&str>::into),
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
@@ -279,7 +289,7 @@ where
|
|||||||
let (remaining, contents) = text_until_exit(&parser_context, remaining)?;
|
let (remaining, contents) = text_until_exit(&parser_context, remaining)?;
|
||||||
let (remaining, _end) = lesser_block_end_specialized(&parser_context, remaining)?;
|
let (remaining, _end) = lesser_block_end_specialized(&parser_context, remaining)?;
|
||||||
|
|
||||||
let (remaining, _trailing_ws) =
|
let (remaining, post_blank) =
|
||||||
maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?;
|
maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?;
|
||||||
let source = get_consumed(input, remaining);
|
let source = get_consumed(input, remaining);
|
||||||
Ok((
|
Ok((
|
||||||
@@ -293,6 +303,7 @@ where
|
|||||||
export_type: export_type.map(Into::<&str>::into),
|
export_type: export_type.map(Into::<&str>::into),
|
||||||
data: parameters.map(Into::<&str>::into),
|
data: parameters.map(Into::<&str>::into),
|
||||||
value: Into::<&str>::into(contents),
|
value: Into::<&str>::into(contents),
|
||||||
|
post_blank: post_blank.map(Into::<&str>::into),
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
@@ -334,7 +345,7 @@ where
|
|||||||
let (remaining, contents) = text_until_exit(&parser_context, remaining)?;
|
let (remaining, contents) = text_until_exit(&parser_context, remaining)?;
|
||||||
let (remaining, _end) = lesser_block_end_specialized(&parser_context, remaining)?;
|
let (remaining, _end) = lesser_block_end_specialized(&parser_context, remaining)?;
|
||||||
|
|
||||||
let (remaining, _trailing_ws) =
|
let (remaining, post_blank) =
|
||||||
maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?;
|
maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?;
|
||||||
let source = get_consumed(input, remaining);
|
let source = get_consumed(input, remaining);
|
||||||
let (switches, number_lines, preserve_indent, retain_labels, use_labels, label_format) = {
|
let (switches, number_lines, preserve_indent, retain_labels, use_labels, label_format) = {
|
||||||
@@ -372,6 +383,7 @@ where
|
|||||||
use_labels,
|
use_labels,
|
||||||
label_format,
|
label_format,
|
||||||
value: Into::<&str>::into(contents),
|
value: Into::<&str>::into(contents),
|
||||||
|
post_blank: post_blank.map(Into::<&str>::into),
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
use nom::branch::alt;
|
use nom::branch::alt;
|
||||||
|
use nom::character::complete::space1;
|
||||||
use nom::combinator::consumed;
|
use nom::combinator::consumed;
|
||||||
use nom::combinator::eof;
|
use nom::combinator::eof;
|
||||||
|
use nom::combinator::opt;
|
||||||
use nom::combinator::recognize;
|
use nom::combinator::recognize;
|
||||||
use nom::combinator::verify;
|
use nom::combinator::verify;
|
||||||
use nom::multi::many1;
|
use nom::multi::many1;
|
||||||
@@ -13,6 +15,7 @@ use super::org_source::OrgSource;
|
|||||||
use super::util::blank_line;
|
use super::util::blank_line;
|
||||||
use super::util::get_consumed;
|
use super::util::get_consumed;
|
||||||
use super::util::maybe_consume_trailing_whitespace_if_not_exiting;
|
use super::util::maybe_consume_trailing_whitespace_if_not_exiting;
|
||||||
|
use super::util::org_line_ending;
|
||||||
use crate::context::parser_with_context;
|
use crate::context::parser_with_context;
|
||||||
use crate::context::ContextElement;
|
use crate::context::ContextElement;
|
||||||
use crate::context::ExitClass;
|
use crate::context::ExitClass;
|
||||||
@@ -72,6 +75,57 @@ where
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg_attr(
|
||||||
|
feature = "tracing",
|
||||||
|
tracing::instrument(ret, level = "debug", skip(context))
|
||||||
|
)]
|
||||||
|
pub(crate) fn empty_paragraph<'b, 'g, 'r, 's>(
|
||||||
|
context: RefContext<'b, 'g, 'r, 's>,
|
||||||
|
input: OrgSource<'s>,
|
||||||
|
) -> Res<OrgSource<'s>, Paragraph<'s>> {
|
||||||
|
// If it is just a single newline then source, contents, and post-blank are "\n".
|
||||||
|
// If it has multiple newlines then contents is the first "\n" and post-blank is all the new lines.
|
||||||
|
// If there are any spaces on the first line then post-blank excludes the first line.
|
||||||
|
|
||||||
|
let exit_matcher = parser_with_context!(exit_matcher_parser)(context);
|
||||||
|
|
||||||
|
let (remaining, first_line_with_spaces) =
|
||||||
|
opt(recognize(tuple((space1, org_line_ending))))(input)?;
|
||||||
|
|
||||||
|
let post_blank_begin = remaining;
|
||||||
|
|
||||||
|
if let Some(first_line_with_spaces) = first_line_with_spaces {
|
||||||
|
let (remaining, _additional_lines) =
|
||||||
|
recognize(many_till(blank_line, exit_matcher))(remaining)?;
|
||||||
|
let post_blank = get_consumed(post_blank_begin, remaining);
|
||||||
|
let source = get_consumed(input, remaining);
|
||||||
|
Ok((
|
||||||
|
remaining,
|
||||||
|
Paragraph::of_text(
|
||||||
|
Into::<&str>::into(source),
|
||||||
|
Into::<&str>::into(first_line_with_spaces),
|
||||||
|
Some(Into::<&str>::into(first_line_with_spaces)),
|
||||||
|
Some(Into::<&str>::into(post_blank)),
|
||||||
|
),
|
||||||
|
))
|
||||||
|
} else {
|
||||||
|
let (remaining, first_line) = blank_line(remaining)?;
|
||||||
|
let (remaining, _additional_lines) =
|
||||||
|
recognize(many_till(blank_line, exit_matcher))(remaining)?;
|
||||||
|
let post_blank = get_consumed(post_blank_begin, remaining);
|
||||||
|
let source = get_consumed(input, remaining);
|
||||||
|
Ok((
|
||||||
|
remaining,
|
||||||
|
Paragraph::of_text(
|
||||||
|
Into::<&str>::into(source),
|
||||||
|
Into::<&str>::into(first_line),
|
||||||
|
Some(Into::<&str>::into(first_line)),
|
||||||
|
Some(Into::<&str>::into(post_blank)),
|
||||||
|
),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
feature = "tracing",
|
feature = "tracing",
|
||||||
tracing::instrument(ret, level = "debug", skip(context))
|
tracing::instrument(ret, level = "debug", skip(context))
|
||||||
@@ -99,6 +153,7 @@ mod tests {
|
|||||||
use crate::context::List;
|
use crate::context::List;
|
||||||
use crate::parser::element_parser::element;
|
use crate::parser::element_parser::element;
|
||||||
use crate::parser::org_source::OrgSource;
|
use crate::parser::org_source::OrgSource;
|
||||||
|
use crate::parser::paragraph::empty_paragraph;
|
||||||
use crate::types::StandardProperties;
|
use crate::types::StandardProperties;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -115,4 +170,17 @@ mod tests {
|
|||||||
assert_eq!(first_paragraph.get_source(), "foo bar baz\n\n");
|
assert_eq!(first_paragraph.get_source(), "foo bar baz\n\n");
|
||||||
assert_eq!(second_paragraph.get_source(), "lorem ipsum");
|
assert_eq!(second_paragraph.get_source(), "lorem ipsum");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn paragraph_whitespace() {
|
||||||
|
let input = OrgSource::new("\n");
|
||||||
|
let global_settings = GlobalSettings::default();
|
||||||
|
let initial_context = ContextElement::document_context();
|
||||||
|
let initial_context = Context::new(&global_settings, List::new(&initial_context));
|
||||||
|
let paragraph_matcher = bind_context!(empty_paragraph, &initial_context);
|
||||||
|
let (remaining, paragraph) = paragraph_matcher(input).expect("Parse paragraph");
|
||||||
|
assert_eq!(Into::<&str>::into(remaining), "");
|
||||||
|
assert_eq!(paragraph.get_source(), "\n");
|
||||||
|
assert_eq!(paragraph.get_contents(), Some("\n"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ use nom::character::complete::multispace1;
|
|||||||
use nom::character::complete::one_of;
|
use nom::character::complete::one_of;
|
||||||
use nom::character::complete::space0;
|
use nom::character::complete::space0;
|
||||||
use nom::character::complete::space1;
|
use nom::character::complete::space1;
|
||||||
|
use nom::combinator::consumed;
|
||||||
use nom::combinator::eof;
|
use nom::combinator::eof;
|
||||||
use nom::combinator::map;
|
use nom::combinator::map;
|
||||||
use nom::combinator::not;
|
use nom::combinator::not;
|
||||||
@@ -152,6 +153,7 @@ where
|
|||||||
let mut children = Vec::new();
|
let mut children = Vec::new();
|
||||||
let mut first_item_indentation: Option<IndentationLevel> = None;
|
let mut first_item_indentation: Option<IndentationLevel> = None;
|
||||||
let mut first_item_list_type: Option<PlainListType> = None;
|
let mut first_item_list_type: Option<PlainListType> = None;
|
||||||
|
let contents_begin = remaining;
|
||||||
let mut remaining = remaining;
|
let mut remaining = remaining;
|
||||||
|
|
||||||
// The final list item does not consume trailing blank lines (which instead get consumed by the list). We have three options here:
|
// The final list item does not consume trailing blank lines (which instead get consumed by the list). We have three options here:
|
||||||
@@ -195,7 +197,8 @@ where
|
|||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
let (remaining, _trailing_ws) =
|
let contents = get_consumed(contents_begin, remaining);
|
||||||
|
let (remaining, post_blank) =
|
||||||
maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?;
|
maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?;
|
||||||
let source = get_consumed(input, remaining);
|
let source = get_consumed(input, remaining);
|
||||||
Ok((
|
Ok((
|
||||||
@@ -208,6 +211,8 @@ where
|
|||||||
),
|
),
|
||||||
list_type: first_item_list_type.expect("Plain lists require at least one element."),
|
list_type: first_item_list_type.expect("Plain lists require at least one element."),
|
||||||
children: children.into_iter().map(|(_start, item)| item).collect(),
|
children: children.into_iter().map(|(_start, item)| item).collect(),
|
||||||
|
contents: Some(Into::<&str>::into(contents)),
|
||||||
|
post_blank: post_blank.map(Into::<&str>::into),
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
@@ -265,7 +270,7 @@ fn plain_list_item<'b, 'g, 'r, 's>(
|
|||||||
let maybe_contentless_item: Res<OrgSource<'_>, ()> =
|
let maybe_contentless_item: Res<OrgSource<'_>, ()> =
|
||||||
detect_contentless_item_contents(&parser_context, remaining);
|
detect_contentless_item_contents(&parser_context, remaining);
|
||||||
if let Ok((_rem, _ws)) = maybe_contentless_item {
|
if let Ok((_rem, _ws)) = maybe_contentless_item {
|
||||||
let (remaining, _trailing_ws) = if tuple((
|
let (remaining, post_blank) = if tuple((
|
||||||
blank_line,
|
blank_line,
|
||||||
bind_context!(final_item_whitespace_cutoff, context),
|
bind_context!(final_item_whitespace_cutoff, context),
|
||||||
))(remaining)
|
))(remaining)
|
||||||
@@ -291,6 +296,12 @@ fn plain_list_item<'b, 'g, 'r, 's>(
|
|||||||
.unwrap_or(Vec::new()),
|
.unwrap_or(Vec::new()),
|
||||||
pre_blank: 0,
|
pre_blank: 0,
|
||||||
children: Vec::new(),
|
children: Vec::new(),
|
||||||
|
contents: None,
|
||||||
|
post_blank: if post_blank.len() > 0 {
|
||||||
|
Some(Into::<&str>::into(post_blank))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
},
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
@@ -301,13 +312,13 @@ fn plain_list_item<'b, 'g, 'r, 's>(
|
|||||||
.filter(|b| *b == b'\n')
|
.filter(|b| *b == b'\n')
|
||||||
.count();
|
.count();
|
||||||
|
|
||||||
let (remaining, (children, _exit_contents)) = many_till(
|
let (remaining, (contents, (children, _exit_contents))) = consumed(many_till(
|
||||||
include_input(bind_context!(element(true), &parser_context)),
|
include_input(bind_context!(element(true), &parser_context)),
|
||||||
bind_context!(exit_matcher_parser, &parser_context),
|
bind_context!(exit_matcher_parser, &parser_context),
|
||||||
)(remaining)?;
|
))(remaining)?;
|
||||||
|
|
||||||
// We have to use the parser_context here to include the whitespace cut-off
|
// We have to use the parser_context here to include the whitespace cut-off
|
||||||
let (remaining, _trailing_ws) =
|
let (remaining, post_blank) =
|
||||||
maybe_consume_trailing_whitespace_if_not_exiting(&final_whitespace_context, remaining)?;
|
maybe_consume_trailing_whitespace_if_not_exiting(&final_whitespace_context, remaining)?;
|
||||||
|
|
||||||
let source = get_consumed(input, remaining);
|
let source = get_consumed(input, remaining);
|
||||||
@@ -329,6 +340,12 @@ fn plain_list_item<'b, 'g, 'r, 's>(
|
|||||||
pre_blank: PlainListItemPreBlank::try_from(pre_blank)
|
pre_blank: PlainListItemPreBlank::try_from(pre_blank)
|
||||||
.expect("pre-blank cannot be larger than 2."),
|
.expect("pre-blank cannot be larger than 2."),
|
||||||
children: children.into_iter().map(|(_start, item)| item).collect(),
|
children: children.into_iter().map(|(_start, item)| item).collect(),
|
||||||
|
contents: if contents.len() > 0 {
|
||||||
|
Some(contents.into())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
},
|
||||||
|
post_blank: post_blank.map(Into::<&str>::into),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ pub(crate) fn planning<'b, 'g, 'r, 's>(
|
|||||||
many1(parser_with_context!(planning_parameter)(context))(remaining)?;
|
many1(parser_with_context!(planning_parameter)(context))(remaining)?;
|
||||||
let (remaining, _trailing_ws) = tuple((space0, org_line_ending))(remaining)?;
|
let (remaining, _trailing_ws) = tuple((space0, org_line_ending))(remaining)?;
|
||||||
|
|
||||||
let (remaining, _trailing_ws) =
|
let (remaining, post_blank) =
|
||||||
maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?;
|
maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?;
|
||||||
let source = get_consumed(input, remaining);
|
let source = get_consumed(input, remaining);
|
||||||
|
|
||||||
@@ -62,6 +62,7 @@ pub(crate) fn planning<'b, 'g, 'r, 's>(
|
|||||||
scheduled,
|
scheduled,
|
||||||
deadline,
|
deadline,
|
||||||
closed,
|
closed,
|
||||||
|
post_blank: post_blank.map(Into::<&str>::into),
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ use nom::character::complete::anychar;
|
|||||||
use nom::character::complete::line_ending;
|
use nom::character::complete::line_ending;
|
||||||
use nom::character::complete::space0;
|
use nom::character::complete::space0;
|
||||||
use nom::character::complete::space1;
|
use nom::character::complete::space1;
|
||||||
|
use nom::combinator::consumed;
|
||||||
use nom::combinator::eof;
|
use nom::combinator::eof;
|
||||||
use nom::combinator::opt;
|
use nom::combinator::opt;
|
||||||
use nom::combinator::recognize;
|
use nom::combinator::recognize;
|
||||||
@@ -64,14 +65,11 @@ pub(crate) fn property_drawer<'b, 'g, 'r, 's>(
|
|||||||
let parser_context = context.with_additional_node(&contexts[0]);
|
let parser_context = context.with_additional_node(&contexts[0]);
|
||||||
let parser_context = parser_context.with_additional_node(&contexts[1]);
|
let parser_context = parser_context.with_additional_node(&contexts[1]);
|
||||||
let parser_context = parser_context.with_additional_node(&contexts[2]);
|
let parser_context = parser_context.with_additional_node(&contexts[2]);
|
||||||
|
let (remaining, (contents, children)) =
|
||||||
let node_property_matcher = parser_with_context!(node_property)(&parser_context);
|
consumed(parser_with_context!(children)(&parser_context))(remaining)?;
|
||||||
let exit_matcher = parser_with_context!(exit_matcher_parser)(&parser_context);
|
|
||||||
let (remaining, (children, _exit_contents)) =
|
|
||||||
many_till(node_property_matcher, exit_matcher)(remaining)?;
|
|
||||||
let (remaining, _end) = property_drawer_end(&parser_context, remaining)?;
|
let (remaining, _end) = property_drawer_end(&parser_context, remaining)?;
|
||||||
|
|
||||||
let (remaining, _trailing_ws) =
|
let (remaining, post_blank) =
|
||||||
maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?;
|
maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?;
|
||||||
let source = get_consumed(input, remaining);
|
let source = get_consumed(input, remaining);
|
||||||
|
|
||||||
@@ -80,10 +78,31 @@ pub(crate) fn property_drawer<'b, 'g, 'r, 's>(
|
|||||||
PropertyDrawer {
|
PropertyDrawer {
|
||||||
source: source.into(),
|
source: source.into(),
|
||||||
children,
|
children,
|
||||||
|
contents: if contents.len() > 0 {
|
||||||
|
Some(contents.into())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
},
|
||||||
|
post_blank: post_blank.map(Into::<&str>::into),
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg_attr(
|
||||||
|
feature = "tracing",
|
||||||
|
tracing::instrument(ret, level = "debug", skip(context))
|
||||||
|
)]
|
||||||
|
fn children<'b, 'g, 'r, 's>(
|
||||||
|
context: RefContext<'b, 'g, 'r, 's>,
|
||||||
|
input: OrgSource<'s>,
|
||||||
|
) -> Res<OrgSource<'s>, Vec<NodeProperty<'s>>> {
|
||||||
|
let node_property_matcher = parser_with_context!(node_property)(context);
|
||||||
|
let exit_matcher = parser_with_context!(exit_matcher_parser)(context);
|
||||||
|
let (remaining, (children, _exit_contents)) =
|
||||||
|
many_till(node_property_matcher, exit_matcher)(input)?;
|
||||||
|
Ok((remaining, children))
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
feature = "tracing",
|
feature = "tracing",
|
||||||
tracing::instrument(ret, level = "debug", skip(_context))
|
tracing::instrument(ret, level = "debug", skip(_context))
|
||||||
|
|||||||
@@ -175,9 +175,7 @@ pub(crate) trait RematchObject<'x> {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::context::Context;
|
|
||||||
use crate::context::GlobalSettings;
|
use crate::context::GlobalSettings;
|
||||||
use crate::context::List;
|
|
||||||
use crate::parser::element_parser::element;
|
use crate::parser::element_parser::element;
|
||||||
use crate::types::Bold;
|
use crate::types::Bold;
|
||||||
use crate::types::Element;
|
use crate::types::Element;
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
use nom::combinator::consumed;
|
|
||||||
use nom::combinator::opt;
|
use nom::combinator::opt;
|
||||||
use nom::combinator::recognize;
|
use nom::combinator::recognize;
|
||||||
use nom::combinator::verify;
|
use nom::combinator::verify;
|
||||||
@@ -59,12 +58,12 @@ pub(crate) fn zeroth_section<'b, 'g, 'r, 's>(
|
|||||||
many0(blank_line),
|
many0(blank_line),
|
||||||
)))(input)?;
|
)))(input)?;
|
||||||
|
|
||||||
let (remaining, (contents, (mut children, _exit_contents))) = consumed(verify(
|
let (remaining, (mut children, _exit_contents)) = verify(
|
||||||
many_till(element_matcher, exit_matcher),
|
many_till(element_matcher, exit_matcher),
|
||||||
|(children, _exit_contents)| {
|
|(children, _exit_contents)| {
|
||||||
!children.is_empty() || comment_and_property_drawer_element.is_some()
|
!children.is_empty() || comment_and_property_drawer_element.is_some()
|
||||||
},
|
},
|
||||||
))(remaining)?;
|
)(remaining)?;
|
||||||
|
|
||||||
if let Some((comment, property_drawer, _ws)) = comment_and_property_drawer_element {
|
if let Some((comment, property_drawer, _ws)) = comment_and_property_drawer_element {
|
||||||
children.insert(0, Element::PropertyDrawer(property_drawer));
|
children.insert(0, Element::PropertyDrawer(property_drawer));
|
||||||
@@ -81,7 +80,6 @@ pub(crate) fn zeroth_section<'b, 'g, 'r, 's>(
|
|||||||
remaining,
|
remaining,
|
||||||
Section {
|
Section {
|
||||||
source: source.into(),
|
source: source.into(),
|
||||||
contents: Some(contents.into()),
|
|
||||||
post_blank: post_blank.map(Into::<&str>::into),
|
post_blank: post_blank.map(Into::<&str>::into),
|
||||||
children,
|
children,
|
||||||
},
|
},
|
||||||
@@ -118,12 +116,12 @@ pub(crate) fn section<'b, 'g, 'r, 's>(
|
|||||||
remaining = remain;
|
remaining = remain;
|
||||||
input = remain;
|
input = remain;
|
||||||
}
|
}
|
||||||
let (remaining, (contents, (mut children, _exit_contents))) = consumed(verify(
|
let (remaining, (mut children, _exit_contents)) = verify(
|
||||||
many_till(element_matcher, exit_matcher),
|
many_till(element_matcher, exit_matcher),
|
||||||
|(children, _exit_contents)| {
|
|(children, _exit_contents)| {
|
||||||
!children.is_empty() || property_drawer_element.is_some() || planning_element.is_some()
|
!children.is_empty() || property_drawer_element.is_some() || planning_element.is_some()
|
||||||
},
|
},
|
||||||
))(remaining)?;
|
)(remaining)?;
|
||||||
if let Some(ele) = property_drawer_element.map(Element::PropertyDrawer) {
|
if let Some(ele) = property_drawer_element.map(Element::PropertyDrawer) {
|
||||||
children.insert(0, ele);
|
children.insert(0, ele);
|
||||||
}
|
}
|
||||||
@@ -139,7 +137,6 @@ pub(crate) fn section<'b, 'g, 'r, 's>(
|
|||||||
remaining,
|
remaining,
|
||||||
Section {
|
Section {
|
||||||
source: source.into(),
|
source: source.into(),
|
||||||
contents: Some(contents.into()),
|
|
||||||
post_blank: post_blank.map(Into::<&str>::into),
|
post_blank: post_blank.map(Into::<&str>::into),
|
||||||
children,
|
children,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ use nom::bytes::complete::is_not;
|
|||||||
use nom::bytes::complete::tag;
|
use nom::bytes::complete::tag;
|
||||||
use nom::character::complete::line_ending;
|
use nom::character::complete::line_ending;
|
||||||
use nom::character::complete::space0;
|
use nom::character::complete::space0;
|
||||||
|
use nom::combinator::consumed;
|
||||||
use nom::combinator::not;
|
use nom::combinator::not;
|
||||||
use nom::combinator::opt;
|
use nom::combinator::opt;
|
||||||
use nom::combinator::peek;
|
use nom::combinator::peek;
|
||||||
@@ -67,13 +68,13 @@ where
|
|||||||
let org_mode_table_row_matcher = parser_with_context!(org_mode_table_row)(&parser_context);
|
let org_mode_table_row_matcher = parser_with_context!(org_mode_table_row)(&parser_context);
|
||||||
let exit_matcher = parser_with_context!(exit_matcher_parser)(&parser_context);
|
let exit_matcher = parser_with_context!(exit_matcher_parser)(&parser_context);
|
||||||
|
|
||||||
let (remaining, (children, _exit_contents)) =
|
let (remaining, (contents, (children, _exit_contents))) =
|
||||||
many_till(org_mode_table_row_matcher, exit_matcher)(remaining)?;
|
consumed(many_till(org_mode_table_row_matcher, exit_matcher))(remaining)?;
|
||||||
|
|
||||||
let (remaining, formulas) =
|
let (remaining, formulas) =
|
||||||
many0(parser_with_context!(table_formula_keyword)(context))(remaining)?;
|
many0(parser_with_context!(table_formula_keyword)(context))(remaining)?;
|
||||||
|
|
||||||
let (remaining, _trailing_ws) =
|
let (remaining, post_blank) =
|
||||||
maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?;
|
maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?;
|
||||||
let source = get_consumed(input, remaining);
|
let source = get_consumed(input, remaining);
|
||||||
|
|
||||||
@@ -87,6 +88,8 @@ where
|
|||||||
),
|
),
|
||||||
formulas,
|
formulas,
|
||||||
children,
|
children,
|
||||||
|
contents: Into::<&str>::into(contents),
|
||||||
|
post_blank: post_blank.map(Into::<&str>::into),
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
@@ -150,6 +153,7 @@ fn org_mode_table_row_rule<'b, 'g, 'r, 's>(
|
|||||||
TableRow {
|
TableRow {
|
||||||
source: source.into(),
|
source: source.into(),
|
||||||
children: Vec::new(),
|
children: Vec::new(),
|
||||||
|
contents: None,
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
@@ -164,8 +168,8 @@ fn org_mode_table_row_regular<'b, 'g, 'r, 's>(
|
|||||||
) -> Res<OrgSource<'s>, TableRow<'s>> {
|
) -> Res<OrgSource<'s>, TableRow<'s>> {
|
||||||
start_of_line(input)?;
|
start_of_line(input)?;
|
||||||
let (remaining, _) = tuple((space0, tag("|")))(input)?;
|
let (remaining, _) = tuple((space0, tag("|")))(input)?;
|
||||||
let (remaining, children) =
|
let (remaining, (contents, children)) =
|
||||||
many1(parser_with_context!(org_mode_table_cell)(context))(remaining)?;
|
consumed(many1(parser_with_context!(org_mode_table_cell)(context)))(remaining)?;
|
||||||
let (remaining, _tail) = recognize(tuple((space0, org_line_ending)))(remaining)?;
|
let (remaining, _tail) = recognize(tuple((space0, org_line_ending)))(remaining)?;
|
||||||
let source = get_consumed(input, remaining);
|
let source = get_consumed(input, remaining);
|
||||||
Ok((
|
Ok((
|
||||||
@@ -173,6 +177,11 @@ fn org_mode_table_row_regular<'b, 'g, 'r, 's>(
|
|||||||
TableRow {
|
TableRow {
|
||||||
source: source.into(),
|
source: source.into(),
|
||||||
children,
|
children,
|
||||||
|
contents: if contents.len() > 0 {
|
||||||
|
Some(Into::<&str>::into(contents))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
},
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
@@ -194,12 +203,12 @@ fn org_mode_table_cell<'b, 'g, 'r, 's>(
|
|||||||
parser_with_context!(table_cell_set_object)(&parser_context);
|
parser_with_context!(table_cell_set_object)(&parser_context);
|
||||||
let exit_matcher = parser_with_context!(exit_matcher_parser)(&parser_context);
|
let exit_matcher = parser_with_context!(exit_matcher_parser)(&parser_context);
|
||||||
let (remaining, _) = space0(input)?;
|
let (remaining, _) = space0(input)?;
|
||||||
let (remaining, (children, _exit_contents)) = verify(
|
let (remaining, (contents, (children, _exit_contents))) = consumed(verify(
|
||||||
many_till(table_cell_set_object_matcher, exit_matcher),
|
many_till(table_cell_set_object_matcher, exit_matcher),
|
||||||
|(children, exit_contents)| {
|
|(children, exit_contents)| {
|
||||||
!children.is_empty() || Into::<&str>::into(exit_contents).ends_with('|')
|
!children.is_empty() || Into::<&str>::into(exit_contents).ends_with('|')
|
||||||
},
|
},
|
||||||
)(remaining)?;
|
))(remaining)?;
|
||||||
|
|
||||||
let (remaining, _tail) = org_mode_table_cell_end(&parser_context, remaining)?;
|
let (remaining, _tail) = org_mode_table_cell_end(&parser_context, remaining)?;
|
||||||
|
|
||||||
@@ -210,6 +219,7 @@ fn org_mode_table_cell<'b, 'g, 'r, 's>(
|
|||||||
TableCell {
|
TableCell {
|
||||||
source: source.into(),
|
source: source.into(),
|
||||||
children,
|
children,
|
||||||
|
contents: Into::<&str>::into(contents),
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ pub(crate) fn target<'b, 'g, 'r, 's>(
|
|||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
let (remaining, _) = tag(">>")(remaining)?;
|
let (remaining, _) = tag(">>")(remaining)?;
|
||||||
let (remaining, _trailing_whitespace) =
|
let (remaining, post_blank) =
|
||||||
maybe_consume_object_trailing_whitespace_if_not_exiting(context, remaining)?;
|
maybe_consume_object_trailing_whitespace_if_not_exiting(context, remaining)?;
|
||||||
let source = get_consumed(input, remaining);
|
let source = get_consumed(input, remaining);
|
||||||
|
|
||||||
@@ -55,6 +55,7 @@ pub(crate) fn target<'b, 'g, 'r, 's>(
|
|||||||
Target {
|
Target {
|
||||||
source: source.into(),
|
source: source.into(),
|
||||||
value: body.into(),
|
value: body.into(),
|
||||||
|
post_blank: post_blank.map(Into::<&str>::into),
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,8 +53,8 @@ pub(crate) fn timestamp<'b, 'g, 'r, 's>(
|
|||||||
parser_with_context!(inactive_time_range_timestamp)(context),
|
parser_with_context!(inactive_time_range_timestamp)(context),
|
||||||
parser_with_context!(active_date_range_timestamp)(context),
|
parser_with_context!(active_date_range_timestamp)(context),
|
||||||
parser_with_context!(inactive_date_range_timestamp)(context),
|
parser_with_context!(inactive_date_range_timestamp)(context),
|
||||||
parser_with_context!(active_timestamp)(context),
|
parser_with_context!(active_timestamp(true))(context),
|
||||||
parser_with_context!(inactive_timestamp)(context),
|
parser_with_context!(inactive_timestamp(true))(context),
|
||||||
))(input)
|
))(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -126,13 +126,23 @@ fn sexp_end<'b, 'g, 'r, 's>(
|
|||||||
alt((tag(")>"), recognize(one_of(">\n"))))(input)
|
alt((tag(")>"), recognize(one_of(">\n"))))(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const fn active_timestamp(
|
||||||
|
allow_post_blank: bool,
|
||||||
|
) -> impl for<'b, 'g, 'r, 's> Fn(
|
||||||
|
RefContext<'b, 'g, 'r, 's>,
|
||||||
|
OrgSource<'s>,
|
||||||
|
) -> Res<OrgSource<'s>, Timestamp<'s>> {
|
||||||
|
move |context, input| impl_active_timestamp(context, input, allow_post_blank)
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
feature = "tracing",
|
feature = "tracing",
|
||||||
tracing::instrument(ret, level = "debug", skip(context))
|
tracing::instrument(ret, level = "debug", skip(context))
|
||||||
)]
|
)]
|
||||||
fn active_timestamp<'b, 'g, 'r, 's>(
|
fn impl_active_timestamp<'b, 'g, 'r, 's>(
|
||||||
context: RefContext<'b, 'g, 'r, 's>,
|
context: RefContext<'b, 'g, 'r, 's>,
|
||||||
input: OrgSource<'s>,
|
input: OrgSource<'s>,
|
||||||
|
allow_post_blank: bool,
|
||||||
) -> Res<OrgSource<'s>, Timestamp<'s>> {
|
) -> Res<OrgSource<'s>, Timestamp<'s>> {
|
||||||
let (remaining, _) = tag("<")(input)?;
|
let (remaining, _) = tag("<")(input)?;
|
||||||
let (remaining, start) = date(context, remaining)?;
|
let (remaining, start) = date(context, remaining)?;
|
||||||
@@ -160,8 +170,11 @@ fn active_timestamp<'b, 'g, 'r, 's>(
|
|||||||
)))(remaining)?;
|
)))(remaining)?;
|
||||||
let (remaining, _) = tag(">")(remaining)?;
|
let (remaining, _) = tag(">")(remaining)?;
|
||||||
|
|
||||||
let (remaining, post_blank) =
|
let (remaining, post_blank) = if allow_post_blank {
|
||||||
maybe_consume_object_trailing_whitespace_if_not_exiting(context, remaining)?;
|
maybe_consume_object_trailing_whitespace_if_not_exiting(context, remaining)?
|
||||||
|
} else {
|
||||||
|
(remaining, None)
|
||||||
|
};
|
||||||
let source = get_consumed(input, remaining);
|
let source = get_consumed(input, remaining);
|
||||||
|
|
||||||
Ok((
|
Ok((
|
||||||
@@ -181,13 +194,23 @@ fn active_timestamp<'b, 'g, 'r, 's>(
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) const fn inactive_timestamp(
|
||||||
|
allow_post_blank: bool,
|
||||||
|
) -> impl for<'b, 'g, 'r, 's> Fn(
|
||||||
|
RefContext<'b, 'g, 'r, 's>,
|
||||||
|
OrgSource<'s>,
|
||||||
|
) -> Res<OrgSource<'s>, Timestamp<'s>> {
|
||||||
|
move |context, input| impl_inactive_timestamp(context, input, allow_post_blank)
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
feature = "tracing",
|
feature = "tracing",
|
||||||
tracing::instrument(ret, level = "debug", skip(context))
|
tracing::instrument(ret, level = "debug", skip(context))
|
||||||
)]
|
)]
|
||||||
pub(crate) fn inactive_timestamp<'b, 'g, 'r, 's>(
|
fn impl_inactive_timestamp<'b, 'g, 'r, 's>(
|
||||||
context: RefContext<'b, 'g, 'r, 's>,
|
context: RefContext<'b, 'g, 'r, 's>,
|
||||||
input: OrgSource<'s>,
|
input: OrgSource<'s>,
|
||||||
|
allow_post_blank: bool,
|
||||||
) -> Res<OrgSource<'s>, Timestamp<'s>> {
|
) -> Res<OrgSource<'s>, Timestamp<'s>> {
|
||||||
let (remaining, _) = tag("[")(input)?;
|
let (remaining, _) = tag("[")(input)?;
|
||||||
let (remaining, start) = date(context, remaining)?;
|
let (remaining, start) = date(context, remaining)?;
|
||||||
@@ -215,8 +238,11 @@ pub(crate) fn inactive_timestamp<'b, 'g, 'r, 's>(
|
|||||||
)))(remaining)?;
|
)))(remaining)?;
|
||||||
let (remaining, _) = tag("]")(remaining)?;
|
let (remaining, _) = tag("]")(remaining)?;
|
||||||
|
|
||||||
let (remaining, post_blank) =
|
let (remaining, post_blank) = if allow_post_blank {
|
||||||
maybe_consume_object_trailing_whitespace_if_not_exiting(context, remaining)?;
|
maybe_consume_object_trailing_whitespace_if_not_exiting(context, remaining)?
|
||||||
|
} else {
|
||||||
|
(remaining, None)
|
||||||
|
};
|
||||||
let source = get_consumed(input, remaining);
|
let source = get_consumed(input, remaining);
|
||||||
|
|
||||||
Ok((
|
Ok((
|
||||||
@@ -244,10 +270,10 @@ fn active_date_range_timestamp<'b, 'g, 'r, 's>(
|
|||||||
context: RefContext<'b, 'g, 'r, 's>,
|
context: RefContext<'b, 'g, 'r, 's>,
|
||||||
input: OrgSource<'s>,
|
input: OrgSource<'s>,
|
||||||
) -> Res<OrgSource<'s>, Timestamp<'s>> {
|
) -> Res<OrgSource<'s>, Timestamp<'s>> {
|
||||||
let (remaining, first_timestamp) = active_timestamp(context, input)?;
|
let (remaining, first_timestamp) = impl_active_timestamp(context, input, false)?;
|
||||||
// TODO: Does the space0 at the end of the active/inactive timestamp parsers cause this to be incorrect? I could use a look-behind to make sure the preceding character is not whitespace
|
// TODO: Does the space0 at the end of the active/inactive timestamp parsers cause this to be incorrect? I could use a look-behind to make sure the preceding character is not whitespace
|
||||||
let (remaining, _separator) = tag("--")(remaining)?;
|
let (remaining, _separator) = tag("--")(remaining)?;
|
||||||
let (remaining, second_timestamp) = active_timestamp(context, remaining)?;
|
let (remaining, second_timestamp) = impl_active_timestamp(context, remaining, false)?;
|
||||||
|
|
||||||
let (remaining, post_blank) =
|
let (remaining, post_blank) =
|
||||||
maybe_consume_object_trailing_whitespace_if_not_exiting(context, remaining)?;
|
maybe_consume_object_trailing_whitespace_if_not_exiting(context, remaining)?;
|
||||||
@@ -335,10 +361,10 @@ pub(crate) fn inactive_date_range_timestamp<'b, 'g, 'r, 's>(
|
|||||||
context: RefContext<'b, 'g, 'r, 's>,
|
context: RefContext<'b, 'g, 'r, 's>,
|
||||||
input: OrgSource<'s>,
|
input: OrgSource<'s>,
|
||||||
) -> Res<OrgSource<'s>, Timestamp<'s>> {
|
) -> Res<OrgSource<'s>, Timestamp<'s>> {
|
||||||
let (remaining, first_timestamp) = inactive_timestamp(context, input)?;
|
let (remaining, first_timestamp) = impl_inactive_timestamp(context, input, false)?;
|
||||||
// TODO: Does the space0 at the end of the active/inactive timestamp parsers cause this to be incorrect? I could use a look-behind to make sure the preceding character is not whitespace
|
// TODO: Does the space0 at the end of the active/inactive timestamp parsers cause this to be incorrect? I could use a look-behind to make sure the preceding character is not whitespace
|
||||||
let (remaining, _separator) = tag("--")(remaining)?;
|
let (remaining, _separator) = tag("--")(remaining)?;
|
||||||
let (remaining, second_timestamp) = inactive_timestamp(context, remaining)?;
|
let (remaining, second_timestamp) = impl_inactive_timestamp(context, remaining, false)?;
|
||||||
|
|
||||||
let (remaining, post_blank) =
|
let (remaining, post_blank) =
|
||||||
maybe_consume_object_trailing_whitespace_if_not_exiting(context, remaining)?;
|
maybe_consume_object_trailing_whitespace_if_not_exiting(context, remaining)?;
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use super::remove_trailing::RemoveTrailing;
|
|
||||||
use super::Element;
|
use super::Element;
|
||||||
use super::NodeProperty;
|
use super::NodeProperty;
|
||||||
use super::Object;
|
use super::Object;
|
||||||
@@ -18,6 +17,7 @@ pub struct Document<'s> {
|
|||||||
pub path: Option<PathBuf>,
|
pub path: Option<PathBuf>,
|
||||||
pub zeroth_section: Option<Section<'s>>,
|
pub zeroth_section: Option<Section<'s>>,
|
||||||
pub children: Vec<Heading<'s>>,
|
pub children: Vec<Heading<'s>>,
|
||||||
|
pub contents: &'s str,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@@ -35,17 +35,19 @@ pub struct Heading<'s> {
|
|||||||
pub scheduled: Option<Timestamp<'s>>,
|
pub scheduled: Option<Timestamp<'s>>,
|
||||||
pub deadline: Option<Timestamp<'s>>,
|
pub deadline: Option<Timestamp<'s>>,
|
||||||
pub closed: Option<Timestamp<'s>>,
|
pub closed: Option<Timestamp<'s>>,
|
||||||
|
pub contents: Option<&'s str>,
|
||||||
|
pub post_blank: Option<&'s str>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Section<'s> {
|
pub struct Section<'s> {
|
||||||
pub source: &'s str,
|
pub source: &'s str,
|
||||||
pub contents: Option<&'s str>,
|
|
||||||
pub post_blank: Option<&'s str>,
|
pub post_blank: Option<&'s str>,
|
||||||
pub children: Vec<Element<'s>>,
|
pub children: Vec<Element<'s>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
#[allow(clippy::large_enum_variant)]
|
||||||
pub enum DocumentElement<'s> {
|
pub enum DocumentElement<'s> {
|
||||||
Heading(Heading<'s>),
|
Heading(Heading<'s>),
|
||||||
Section(Section<'s>),
|
Section(Section<'s>),
|
||||||
@@ -63,35 +65,11 @@ impl<'s> StandardProperties<'s> for Document<'s> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||||
let post_blank = self.get_post_blank();
|
Some(self.contents)
|
||||||
let mut content_lines = self
|
|
||||||
.source
|
|
||||||
.split_inclusive('\n')
|
|
||||||
.remove_trailing(post_blank);
|
|
||||||
let first_line = content_lines.next();
|
|
||||||
let last_line = content_lines.last().or(first_line);
|
|
||||||
match (first_line, last_line) {
|
|
||||||
(None, None) => None,
|
|
||||||
(None, Some(_)) | (Some(_), None) => unreachable!(),
|
|
||||||
(Some(first_line), Some(last_line)) => {
|
|
||||||
let first_line_offset = first_line.as_ptr() as usize;
|
|
||||||
let last_line_offset = last_line.as_ptr() as usize + last_line.len();
|
|
||||||
let source_offset = self.source.as_ptr() as usize;
|
|
||||||
debug_assert!(super::lesser_element::is_slice_of(self.source, first_line));
|
|
||||||
debug_assert!(super::lesser_element::is_slice_of(self.source, last_line));
|
|
||||||
Some(
|
|
||||||
&self.source[(first_line_offset - source_offset)
|
|
||||||
..(last_line_offset - first_line_offset)],
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_post_blank(&self) -> PostBlank {
|
fn get_post_blank(&self) -> PostBlank {
|
||||||
self.into_iter()
|
0
|
||||||
.last()
|
|
||||||
.map(|child| child.get_post_blank())
|
|
||||||
.unwrap_or(0)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,7 +79,7 @@ impl<'s> StandardProperties<'s> for Section<'s> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||||
self.contents
|
Some(self.source)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_post_blank(&self) -> PostBlank {
|
fn get_post_blank(&self) -> PostBlank {
|
||||||
@@ -119,39 +97,15 @@ impl<'s> StandardProperties<'s> for Heading<'s> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||||
let first_child = self.children.first();
|
self.contents
|
||||||
let last_child = self.children.last();
|
|
||||||
match (first_child, last_child) {
|
|
||||||
(None, None) => None,
|
|
||||||
(None, Some(_)) | (Some(_), None) => unreachable!(),
|
|
||||||
(Some(first_child), Some(last_child)) => {
|
|
||||||
let first_child_offset = first_child.get_source().as_ptr() as usize;
|
|
||||||
let last_child_offset = {
|
|
||||||
let last_child_source = last_child.get_source();
|
|
||||||
last_child_source.as_ptr() as usize + last_child_source.len()
|
|
||||||
};
|
|
||||||
let source_offset = self.source.as_ptr() as usize;
|
|
||||||
debug_assert!(super::lesser_element::is_slice_of(
|
|
||||||
self.source,
|
|
||||||
first_child.get_source()
|
|
||||||
));
|
|
||||||
debug_assert!(super::lesser_element::is_slice_of(
|
|
||||||
self.source,
|
|
||||||
last_child.get_source()
|
|
||||||
));
|
|
||||||
Some(
|
|
||||||
&self.source[(first_child_offset - source_offset)
|
|
||||||
..(last_child_offset - first_child_offset)],
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_post_blank(&self) -> PostBlank {
|
fn get_post_blank(&self) -> PostBlank {
|
||||||
self.children
|
self.post_blank
|
||||||
.last()
|
.map(|text| text.lines().count())
|
||||||
.map(|child| child.get_post_blank())
|
|
||||||
.unwrap_or(0)
|
.unwrap_or(0)
|
||||||
|
.try_into()
|
||||||
|
.expect("Too much post-blank to fit into a PostBlank.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ pub struct PlainList<'s> {
|
|||||||
pub affiliated_keywords: AffiliatedKeywords<'s>,
|
pub affiliated_keywords: AffiliatedKeywords<'s>,
|
||||||
pub list_type: PlainListType,
|
pub list_type: PlainListType,
|
||||||
pub children: Vec<PlainListItem<'s>>,
|
pub children: Vec<PlainListItem<'s>>,
|
||||||
|
pub contents: Option<&'s str>, // TODO: Can contents ever be None?
|
||||||
|
pub post_blank: Option<&'s str>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
@@ -35,6 +37,8 @@ pub struct PlainListItem<'s> {
|
|||||||
pub tag: Vec<Object<'s>>,
|
pub tag: Vec<Object<'s>>,
|
||||||
pub pre_blank: PlainListItemPreBlank,
|
pub pre_blank: PlainListItemPreBlank,
|
||||||
pub children: Vec<Element<'s>>,
|
pub children: Vec<Element<'s>>,
|
||||||
|
pub contents: Option<&'s str>,
|
||||||
|
pub post_blank: Option<&'s str>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type PlainListItemCounter = u16;
|
pub type PlainListItemCounter = u16;
|
||||||
@@ -52,6 +56,8 @@ pub struct CenterBlock<'s> {
|
|||||||
pub source: &'s str,
|
pub source: &'s str,
|
||||||
pub affiliated_keywords: AffiliatedKeywords<'s>,
|
pub affiliated_keywords: AffiliatedKeywords<'s>,
|
||||||
pub children: Vec<Element<'s>>,
|
pub children: Vec<Element<'s>>,
|
||||||
|
pub contents: Option<&'s str>,
|
||||||
|
pub post_blank: Option<&'s str>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@@ -59,6 +65,8 @@ pub struct QuoteBlock<'s> {
|
|||||||
pub source: &'s str,
|
pub source: &'s str,
|
||||||
pub affiliated_keywords: AffiliatedKeywords<'s>,
|
pub affiliated_keywords: AffiliatedKeywords<'s>,
|
||||||
pub children: Vec<Element<'s>>,
|
pub children: Vec<Element<'s>>,
|
||||||
|
pub contents: Option<&'s str>,
|
||||||
|
pub post_blank: Option<&'s str>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@@ -68,6 +76,8 @@ pub struct SpecialBlock<'s> {
|
|||||||
pub block_type: &'s str,
|
pub block_type: &'s str,
|
||||||
pub parameters: Option<&'s str>,
|
pub parameters: Option<&'s str>,
|
||||||
pub children: Vec<Element<'s>>,
|
pub children: Vec<Element<'s>>,
|
||||||
|
pub contents: Option<&'s str>,
|
||||||
|
pub post_blank: Option<&'s str>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@@ -77,6 +87,8 @@ pub struct DynamicBlock<'s> {
|
|||||||
pub block_name: &'s str,
|
pub block_name: &'s str,
|
||||||
pub parameters: Option<&'s str>,
|
pub parameters: Option<&'s str>,
|
||||||
pub children: Vec<Element<'s>>,
|
pub children: Vec<Element<'s>>,
|
||||||
|
pub contents: Option<&'s str>,
|
||||||
|
pub post_blank: Option<&'s str>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@@ -95,12 +107,16 @@ pub struct Drawer<'s> {
|
|||||||
pub affiliated_keywords: AffiliatedKeywords<'s>,
|
pub affiliated_keywords: AffiliatedKeywords<'s>,
|
||||||
pub drawer_name: &'s str,
|
pub drawer_name: &'s str,
|
||||||
pub children: Vec<Element<'s>>,
|
pub children: Vec<Element<'s>>,
|
||||||
|
pub contents: Option<&'s str>,
|
||||||
|
pub post_blank: Option<&'s str>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct PropertyDrawer<'s> {
|
pub struct PropertyDrawer<'s> {
|
||||||
pub source: &'s str,
|
pub source: &'s str,
|
||||||
pub children: Vec<NodeProperty<'s>>,
|
pub children: Vec<NodeProperty<'s>>,
|
||||||
|
pub contents: Option<&'s str>,
|
||||||
|
pub post_blank: Option<&'s str>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@@ -116,12 +132,15 @@ pub struct Table<'s> {
|
|||||||
pub affiliated_keywords: AffiliatedKeywords<'s>,
|
pub affiliated_keywords: AffiliatedKeywords<'s>,
|
||||||
pub formulas: Vec<Keyword<'s>>,
|
pub formulas: Vec<Keyword<'s>>,
|
||||||
pub children: Vec<TableRow<'s>>,
|
pub children: Vec<TableRow<'s>>,
|
||||||
|
pub contents: &'s str,
|
||||||
|
pub post_blank: Option<&'s str>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct TableRow<'s> {
|
pub struct TableRow<'s> {
|
||||||
pub source: &'s str,
|
pub source: &'s str,
|
||||||
pub children: Vec<TableCell<'s>>,
|
pub children: Vec<TableCell<'s>>,
|
||||||
|
pub contents: Option<&'s str>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@@ -136,11 +155,15 @@ impl<'s> StandardProperties<'s> for PlainList<'s> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||||
todo!()
|
self.contents
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_post_blank(&self) -> PostBlank {
|
fn get_post_blank(&self) -> PostBlank {
|
||||||
todo!()
|
self.post_blank
|
||||||
|
.map(|text| text.lines().count())
|
||||||
|
.unwrap_or(0)
|
||||||
|
.try_into()
|
||||||
|
.expect("Too much post-blank to fit into a PostBlank.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -150,11 +173,15 @@ impl<'s> StandardProperties<'s> for PlainListItem<'s> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||||
todo!()
|
self.contents
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_post_blank(&self) -> PostBlank {
|
fn get_post_blank(&self) -> PostBlank {
|
||||||
todo!()
|
self.post_blank
|
||||||
|
.map(|text| text.lines().count())
|
||||||
|
.unwrap_or(0)
|
||||||
|
.try_into()
|
||||||
|
.expect("Too much post-blank to fit into a PostBlank.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -164,11 +191,15 @@ impl<'s> StandardProperties<'s> for CenterBlock<'s> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||||
todo!()
|
self.contents
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_post_blank(&self) -> PostBlank {
|
fn get_post_blank(&self) -> PostBlank {
|
||||||
todo!()
|
self.post_blank
|
||||||
|
.map(|text| text.lines().count())
|
||||||
|
.unwrap_or(0)
|
||||||
|
.try_into()
|
||||||
|
.expect("Too much post-blank to fit into a PostBlank.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -178,11 +209,15 @@ impl<'s> StandardProperties<'s> for QuoteBlock<'s> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||||
todo!()
|
self.contents
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_post_blank(&self) -> PostBlank {
|
fn get_post_blank(&self) -> PostBlank {
|
||||||
todo!()
|
self.post_blank
|
||||||
|
.map(|text| text.lines().count())
|
||||||
|
.unwrap_or(0)
|
||||||
|
.try_into()
|
||||||
|
.expect("Too much post-blank to fit into a PostBlank.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -192,11 +227,15 @@ impl<'s> StandardProperties<'s> for SpecialBlock<'s> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||||
todo!()
|
self.contents
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_post_blank(&self) -> PostBlank {
|
fn get_post_blank(&self) -> PostBlank {
|
||||||
todo!()
|
self.post_blank
|
||||||
|
.map(|text| text.lines().count())
|
||||||
|
.unwrap_or(0)
|
||||||
|
.try_into()
|
||||||
|
.expect("Too much post-blank to fit into a PostBlank.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -206,11 +245,15 @@ impl<'s> StandardProperties<'s> for DynamicBlock<'s> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||||
todo!()
|
self.contents
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_post_blank(&self) -> PostBlank {
|
fn get_post_blank(&self) -> PostBlank {
|
||||||
todo!()
|
self.post_blank
|
||||||
|
.map(|text| text.lines().count())
|
||||||
|
.unwrap_or(0)
|
||||||
|
.try_into()
|
||||||
|
.expect("Too much post-blank to fit into a PostBlank.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -238,11 +281,15 @@ impl<'s> StandardProperties<'s> for Drawer<'s> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||||
todo!()
|
self.contents
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_post_blank(&self) -> PostBlank {
|
fn get_post_blank(&self) -> PostBlank {
|
||||||
todo!()
|
self.post_blank
|
||||||
|
.map(|text| text.lines().count())
|
||||||
|
.unwrap_or(0)
|
||||||
|
.try_into()
|
||||||
|
.expect("Too much post-blank to fit into a PostBlank.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -252,11 +299,15 @@ impl<'s> StandardProperties<'s> for PropertyDrawer<'s> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||||
todo!()
|
self.contents
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_post_blank(&self) -> PostBlank {
|
fn get_post_blank(&self) -> PostBlank {
|
||||||
todo!()
|
self.post_blank
|
||||||
|
.map(|text| text.lines().count())
|
||||||
|
.unwrap_or(0)
|
||||||
|
.try_into()
|
||||||
|
.expect("Too much post-blank to fit into a PostBlank.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -266,11 +317,11 @@ impl<'s> StandardProperties<'s> for NodeProperty<'s> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||||
todo!()
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_post_blank(&self) -> PostBlank {
|
fn get_post_blank(&self) -> PostBlank {
|
||||||
todo!()
|
0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -280,11 +331,15 @@ impl<'s> StandardProperties<'s> for Table<'s> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||||
todo!()
|
Some(self.contents)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_post_blank(&self) -> PostBlank {
|
fn get_post_blank(&self) -> PostBlank {
|
||||||
todo!()
|
self.post_blank
|
||||||
|
.map(|text| text.lines().count())
|
||||||
|
.unwrap_or(0)
|
||||||
|
.try_into()
|
||||||
|
.expect("Too much post-blank to fit into a PostBlank.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -294,11 +349,11 @@ impl<'s> StandardProperties<'s> for TableRow<'s> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||||
todo!()
|
self.contents
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_post_blank(&self) -> PostBlank {
|
fn get_post_blank(&self) -> PostBlank {
|
||||||
todo!()
|
0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ pub struct Comment<'s> {
|
|||||||
pub struct TableCell<'s> {
|
pub struct TableCell<'s> {
|
||||||
pub source: &'s str,
|
pub source: &'s str,
|
||||||
pub children: Vec<Object<'s>>,
|
pub children: Vec<Object<'s>>,
|
||||||
|
pub contents: &'s str,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@@ -50,6 +51,8 @@ pub struct VerseBlock<'s> {
|
|||||||
pub affiliated_keywords: AffiliatedKeywords<'s>,
|
pub affiliated_keywords: AffiliatedKeywords<'s>,
|
||||||
pub data: Option<&'s str>,
|
pub data: Option<&'s str>,
|
||||||
pub children: Vec<Object<'s>>,
|
pub children: Vec<Object<'s>>,
|
||||||
|
pub contents: &'s str,
|
||||||
|
pub post_blank: Option<&'s str>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@@ -57,6 +60,7 @@ pub struct CommentBlock<'s> {
|
|||||||
pub source: &'s str,
|
pub source: &'s str,
|
||||||
pub affiliated_keywords: AffiliatedKeywords<'s>,
|
pub affiliated_keywords: AffiliatedKeywords<'s>,
|
||||||
pub contents: &'s str,
|
pub contents: &'s str,
|
||||||
|
pub post_blank: Option<&'s str>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type CharOffsetInLine = u16;
|
pub type CharOffsetInLine = u16;
|
||||||
@@ -80,6 +84,7 @@ pub struct ExampleBlock<'s> {
|
|||||||
pub use_labels: bool,
|
pub use_labels: bool,
|
||||||
pub label_format: Option<&'s str>,
|
pub label_format: Option<&'s str>,
|
||||||
pub value: &'s str,
|
pub value: &'s str,
|
||||||
|
pub post_blank: Option<&'s str>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@@ -89,6 +94,7 @@ pub struct ExportBlock<'s> {
|
|||||||
pub export_type: Option<&'s str>,
|
pub export_type: Option<&'s str>,
|
||||||
pub data: Option<&'s str>,
|
pub data: Option<&'s str>,
|
||||||
pub value: &'s str,
|
pub value: &'s str,
|
||||||
|
pub post_blank: Option<&'s str>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@@ -104,6 +110,7 @@ pub struct SrcBlock<'s> {
|
|||||||
pub use_labels: bool,
|
pub use_labels: bool,
|
||||||
pub label_format: Option<&'s str>,
|
pub label_format: Option<&'s str>,
|
||||||
pub value: &'s str,
|
pub value: &'s str,
|
||||||
|
pub post_blank: Option<&'s str>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@@ -118,6 +125,7 @@ pub struct Clock<'s> {
|
|||||||
pub timestamp: Timestamp<'s>,
|
pub timestamp: Timestamp<'s>,
|
||||||
pub duration: Option<&'s str>,
|
pub duration: Option<&'s str>,
|
||||||
pub status: ClockStatus,
|
pub status: ClockStatus,
|
||||||
|
pub post_blank: Option<&'s str>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@@ -125,6 +133,7 @@ pub struct DiarySexp<'s> {
|
|||||||
pub source: &'s str,
|
pub source: &'s str,
|
||||||
pub affiliated_keywords: AffiliatedKeywords<'s>,
|
pub affiliated_keywords: AffiliatedKeywords<'s>,
|
||||||
pub value: &'s str,
|
pub value: &'s str,
|
||||||
|
pub post_blank: Option<&'s str>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@@ -133,6 +142,7 @@ pub struct Planning<'s> {
|
|||||||
pub scheduled: Option<Timestamp<'s>>,
|
pub scheduled: Option<Timestamp<'s>>,
|
||||||
pub deadline: Option<Timestamp<'s>>,
|
pub deadline: Option<Timestamp<'s>>,
|
||||||
pub closed: Option<Timestamp<'s>>,
|
pub closed: Option<Timestamp<'s>>,
|
||||||
|
pub post_blank: Option<&'s str>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@@ -140,12 +150,14 @@ pub struct FixedWidthArea<'s> {
|
|||||||
pub source: &'s str,
|
pub source: &'s str,
|
||||||
pub affiliated_keywords: AffiliatedKeywords<'s>,
|
pub affiliated_keywords: AffiliatedKeywords<'s>,
|
||||||
pub value: Vec<&'s str>,
|
pub value: Vec<&'s str>,
|
||||||
|
pub post_blank: Option<&'s str>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct HorizontalRule<'s> {
|
pub struct HorizontalRule<'s> {
|
||||||
pub source: &'s str,
|
pub source: &'s str,
|
||||||
pub affiliated_keywords: AffiliatedKeywords<'s>,
|
pub affiliated_keywords: AffiliatedKeywords<'s>,
|
||||||
|
pub post_blank: Option<&'s str>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@@ -166,6 +178,7 @@ pub struct BabelCall<'s> {
|
|||||||
pub inside_header: Option<&'s str>,
|
pub inside_header: Option<&'s str>,
|
||||||
pub arguments: Option<&'s str>,
|
pub arguments: Option<&'s str>,
|
||||||
pub end_header: Option<&'s str>,
|
pub end_header: Option<&'s str>,
|
||||||
|
pub post_blank: Option<&'s str>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@@ -191,11 +204,16 @@ impl<'s> Paragraph<'s> {
|
|||||||
/// Generate a paragraph of the passed in text with no additional properties.
|
/// Generate a paragraph of the passed in text with no additional properties.
|
||||||
///
|
///
|
||||||
/// This is used for elements that support an "empty" content like greater blocks.
|
/// This is used for elements that support an "empty" content like greater blocks.
|
||||||
pub(crate) fn of_text(source: &'s str, body: &'s str) -> Self {
|
pub(crate) fn of_text(
|
||||||
|
source: &'s str,
|
||||||
|
body: &'s str,
|
||||||
|
contents: Option<&'s str>,
|
||||||
|
post_blank: Option<&'s str>,
|
||||||
|
) -> Self {
|
||||||
Paragraph {
|
Paragraph {
|
||||||
source,
|
source,
|
||||||
contents: None, // TODO
|
contents,
|
||||||
post_blank: None, // TODO
|
post_blank,
|
||||||
affiliated_keywords: AffiliatedKeywords::default(),
|
affiliated_keywords: AffiliatedKeywords::default(),
|
||||||
children: vec![Object::PlainText(PlainText { source: body })],
|
children: vec![Object::PlainText(PlainText { source: body })],
|
||||||
}
|
}
|
||||||
@@ -226,11 +244,11 @@ impl<'s> StandardProperties<'s> for TableCell<'s> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||||
todo!()
|
Some(self.contents)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_post_blank(&self) -> PostBlank {
|
fn get_post_blank(&self) -> PostBlank {
|
||||||
todo!()
|
0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -258,11 +276,15 @@ impl<'s> StandardProperties<'s> for VerseBlock<'s> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||||
todo!()
|
Some(self.contents)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_post_blank(&self) -> PostBlank {
|
fn get_post_blank(&self) -> PostBlank {
|
||||||
todo!()
|
self.post_blank
|
||||||
|
.map(|text| text.lines().count())
|
||||||
|
.unwrap_or(0)
|
||||||
|
.try_into()
|
||||||
|
.expect("Too much post-blank to fit into a PostBlank.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<'s> StandardProperties<'s> for CommentBlock<'s> {
|
impl<'s> StandardProperties<'s> for CommentBlock<'s> {
|
||||||
@@ -271,11 +293,15 @@ impl<'s> StandardProperties<'s> for CommentBlock<'s> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||||
todo!()
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_post_blank(&self) -> PostBlank {
|
fn get_post_blank(&self) -> PostBlank {
|
||||||
todo!()
|
self.post_blank
|
||||||
|
.map(|text| text.lines().count())
|
||||||
|
.unwrap_or(0)
|
||||||
|
.try_into()
|
||||||
|
.expect("Too much post-blank to fit into a PostBlank.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<'s> StandardProperties<'s> for ExampleBlock<'s> {
|
impl<'s> StandardProperties<'s> for ExampleBlock<'s> {
|
||||||
@@ -284,11 +310,15 @@ impl<'s> StandardProperties<'s> for ExampleBlock<'s> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||||
todo!()
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_post_blank(&self) -> PostBlank {
|
fn get_post_blank(&self) -> PostBlank {
|
||||||
todo!()
|
self.post_blank
|
||||||
|
.map(|text| text.lines().count())
|
||||||
|
.unwrap_or(0)
|
||||||
|
.try_into()
|
||||||
|
.expect("Too much post-blank to fit into a PostBlank.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<'s> StandardProperties<'s> for ExportBlock<'s> {
|
impl<'s> StandardProperties<'s> for ExportBlock<'s> {
|
||||||
@@ -297,11 +327,15 @@ impl<'s> StandardProperties<'s> for ExportBlock<'s> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||||
todo!()
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_post_blank(&self) -> PostBlank {
|
fn get_post_blank(&self) -> PostBlank {
|
||||||
todo!()
|
self.post_blank
|
||||||
|
.map(|text| text.lines().count())
|
||||||
|
.unwrap_or(0)
|
||||||
|
.try_into()
|
||||||
|
.expect("Too much post-blank to fit into a PostBlank.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<'s> StandardProperties<'s> for SrcBlock<'s> {
|
impl<'s> StandardProperties<'s> for SrcBlock<'s> {
|
||||||
@@ -310,11 +344,15 @@ impl<'s> StandardProperties<'s> for SrcBlock<'s> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||||
todo!()
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_post_blank(&self) -> PostBlank {
|
fn get_post_blank(&self) -> PostBlank {
|
||||||
todo!()
|
self.post_blank
|
||||||
|
.map(|text| text.lines().count())
|
||||||
|
.unwrap_or(0)
|
||||||
|
.try_into()
|
||||||
|
.expect("Too much post-blank to fit into a PostBlank.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -324,11 +362,15 @@ impl<'s> StandardProperties<'s> for Clock<'s> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||||
todo!()
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_post_blank(&self) -> PostBlank {
|
fn get_post_blank(&self) -> PostBlank {
|
||||||
todo!()
|
self.post_blank
|
||||||
|
.map(|text| text.lines().count())
|
||||||
|
.unwrap_or(0)
|
||||||
|
.try_into()
|
||||||
|
.expect("Too much post-blank to fit into a PostBlank.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -338,11 +380,15 @@ impl<'s> StandardProperties<'s> for DiarySexp<'s> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||||
todo!()
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_post_blank(&self) -> PostBlank {
|
fn get_post_blank(&self) -> PostBlank {
|
||||||
todo!()
|
self.post_blank
|
||||||
|
.map(|text| text.lines().count())
|
||||||
|
.unwrap_or(0)
|
||||||
|
.try_into()
|
||||||
|
.expect("Too much post-blank to fit into a PostBlank.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -352,11 +398,15 @@ impl<'s> StandardProperties<'s> for Planning<'s> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||||
todo!()
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_post_blank(&self) -> PostBlank {
|
fn get_post_blank(&self) -> PostBlank {
|
||||||
todo!()
|
self.post_blank
|
||||||
|
.map(|text| text.lines().count())
|
||||||
|
.unwrap_or(0)
|
||||||
|
.try_into()
|
||||||
|
.expect("Too much post-blank to fit into a PostBlank.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -366,11 +416,15 @@ impl<'s> StandardProperties<'s> for FixedWidthArea<'s> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||||
todo!()
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_post_blank(&self) -> PostBlank {
|
fn get_post_blank(&self) -> PostBlank {
|
||||||
todo!()
|
self.post_blank
|
||||||
|
.map(|text| text.lines().count())
|
||||||
|
.unwrap_or(0)
|
||||||
|
.try_into()
|
||||||
|
.expect("Too much post-blank to fit into a PostBlank.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -380,11 +434,15 @@ impl<'s> StandardProperties<'s> for HorizontalRule<'s> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||||
todo!()
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_post_blank(&self) -> PostBlank {
|
fn get_post_blank(&self) -> PostBlank {
|
||||||
todo!()
|
self.post_blank
|
||||||
|
.map(|text| text.lines().count())
|
||||||
|
.unwrap_or(0)
|
||||||
|
.try_into()
|
||||||
|
.expect("Too much post-blank to fit into a PostBlank.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -412,11 +470,15 @@ impl<'s> StandardProperties<'s> for BabelCall<'s> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||||
todo!()
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_post_blank(&self) -> PostBlank {
|
fn get_post_blank(&self) -> PostBlank {
|
||||||
todo!()
|
self.post_blank
|
||||||
|
.map(|text| text.lines().count())
|
||||||
|
.unwrap_or(0)
|
||||||
|
.try_into()
|
||||||
|
.expect("Too much post-blank to fit into a PostBlank.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -452,13 +514,7 @@ impl<'s> Comment<'s> {
|
|||||||
|
|
||||||
impl<'s> FixedWidthArea<'s> {
|
impl<'s> FixedWidthArea<'s> {
|
||||||
pub fn get_value(&self) -> String {
|
pub fn get_value(&self) -> String {
|
||||||
let final_size = self.value.iter().map(|line| line.len()).sum();
|
self.value.join("\n")
|
||||||
let mut ret = String::with_capacity(final_size);
|
|
||||||
for line in &self.value {
|
|
||||||
ret.push_str(line);
|
|
||||||
}
|
|
||||||
|
|
||||||
ret
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ mod greater_element;
|
|||||||
mod lesser_element;
|
mod lesser_element;
|
||||||
mod macros;
|
mod macros;
|
||||||
mod object;
|
mod object;
|
||||||
mod remove_trailing;
|
|
||||||
mod standard_properties;
|
mod standard_properties;
|
||||||
mod util;
|
mod util;
|
||||||
pub use affiliated_keyword::AffiliatedKeyword;
|
pub use affiliated_keyword::AffiliatedKeyword;
|
||||||
|
|||||||
@@ -266,6 +266,7 @@ pub struct LineBreak<'s> {
|
|||||||
pub struct Target<'s> {
|
pub struct Target<'s> {
|
||||||
pub source: &'s str,
|
pub source: &'s str,
|
||||||
pub value: &'s str,
|
pub value: &'s str,
|
||||||
|
pub post_blank: Option<&'s str>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@@ -331,19 +332,19 @@ pub type HourInner = u8;
|
|||||||
pub type MinuteInner = u8;
|
pub type MinuteInner = u8;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Year(YearInner);
|
pub struct Year(pub YearInner);
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Month(MonthInner);
|
pub struct Month(pub MonthInner);
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct DayOfMonth(DayOfMonthInner);
|
pub struct DayOfMonth(pub DayOfMonthInner);
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Hour(HourInner);
|
pub struct Hour(pub HourInner);
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Minute(MinuteInner);
|
pub struct Minute(pub MinuteInner);
|
||||||
|
|
||||||
impl Year {
|
impl Year {
|
||||||
// TODO: Make a real error type instead of a boxed any error.
|
// TODO: Make a real error type instead of a boxed any error.
|
||||||
@@ -923,11 +924,15 @@ impl<'s> StandardProperties<'s> for Target<'s> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||||
todo!()
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_post_blank(&self) -> PostBlank {
|
fn get_post_blank(&self) -> PostBlank {
|
||||||
todo!()
|
self.post_blank
|
||||||
|
.map(|post_blank| post_blank.chars().count())
|
||||||
|
.unwrap_or(0)
|
||||||
|
.try_into()
|
||||||
|
.expect("Too much post-blank to fit into a PostBlank.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1009,11 +1014,13 @@ impl<'s> StandardProperties<'s> for PlainText<'s> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||||
todo!()
|
// This field does not actually exist in emacs for plaintext
|
||||||
|
Some(self.source)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_post_blank(&self) -> PostBlank {
|
fn get_post_blank(&self) -> PostBlank {
|
||||||
todo!()
|
// This field does not actually exist in emacs for plaintext
|
||||||
|
0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,56 +0,0 @@
|
|||||||
pub(crate) trait RemoveTrailing: Iterator + Sized {
|
|
||||||
fn remove_trailing<R: Into<usize>>(self, amount_to_remove: R) -> RemoveTrailingIter<Self>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<I> RemoveTrailing for I
|
|
||||||
where
|
|
||||||
I: Iterator,
|
|
||||||
{
|
|
||||||
fn remove_trailing<R: Into<usize>>(self, amount_to_remove: R) -> RemoveTrailingIter<Self> {
|
|
||||||
RemoveTrailingIter {
|
|
||||||
inner: self,
|
|
||||||
buffer: Vec::new(),
|
|
||||||
next_to_pop: 0,
|
|
||||||
amount_to_remove: amount_to_remove.into(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) struct RemoveTrailingIter<I: Iterator> {
|
|
||||||
inner: I,
|
|
||||||
buffer: Vec<I::Item>,
|
|
||||||
next_to_pop: usize,
|
|
||||||
amount_to_remove: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<I: Iterator> Iterator for RemoveTrailingIter<I> {
|
|
||||||
type Item = I::Item;
|
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
|
||||||
if self.buffer.len() < self.amount_to_remove {
|
|
||||||
self.buffer.reserve_exact(self.amount_to_remove);
|
|
||||||
}
|
|
||||||
while self.buffer.len() < self.amount_to_remove {
|
|
||||||
if let Some(elem) = self.inner.next() {
|
|
||||||
self.buffer.push(elem);
|
|
||||||
} else {
|
|
||||||
// The inner was smaller than amount_to_remove, so never return anything.
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let new_value = self.inner.next();
|
|
||||||
if self.amount_to_remove == 0 {
|
|
||||||
return new_value;
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(new_value) = new_value {
|
|
||||||
let ret = std::mem::replace(&mut self.buffer[self.next_to_pop], new_value);
|
|
||||||
self.next_to_pop = (self.next_to_pop + 1) % self.amount_to_remove;
|
|
||||||
Some(ret)
|
|
||||||
} else {
|
|
||||||
// We have exactly the amount in the buffer than we wanted to cut off, so stop returning values.
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -2,28 +2,53 @@ use std::path::Path;
|
|||||||
|
|
||||||
use tokio::process::Command;
|
use tokio::process::Command;
|
||||||
|
|
||||||
use crate::context::HeadlineLevelFilter;
|
|
||||||
use crate::settings::GlobalSettings;
|
use crate::settings::GlobalSettings;
|
||||||
|
use crate::settings::HeadlineLevelFilter;
|
||||||
|
|
||||||
/// Generate elisp to configure org-mode parsing settings
|
pub async fn print_versions() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
///
|
eprintln!("Using emacs version: {}", get_emacs_version().await?.trim());
|
||||||
/// Currently only org-list-allow-alphabetical is supported.
|
eprintln!(
|
||||||
fn global_settings_elisp(global_settings: &GlobalSettings) -> String {
|
"Using org-mode version: {}",
|
||||||
// This string concatenation is wildly inefficient but its only called in tests 🤷.
|
get_org_mode_version().await?.trim()
|
||||||
let mut ret = "".to_owned();
|
);
|
||||||
if global_settings.list_allow_alphabetical {
|
Ok(())
|
||||||
ret += "(setq org-list-allow-alphabetical t)\n"
|
}
|
||||||
}
|
|
||||||
if global_settings.tab_width != crate::settings::DEFAULT_TAB_WIDTH {
|
pub(crate) async fn get_emacs_version() -> Result<String, Box<dyn std::error::Error>> {
|
||||||
ret += format!("(setq-default tab-width {})", global_settings.tab_width).as_str();
|
let elisp_script = r#"(progn
|
||||||
}
|
(message "%s" (version))
|
||||||
if global_settings.odd_levels_only != HeadlineLevelFilter::default() {
|
)"#;
|
||||||
ret += match global_settings.odd_levels_only {
|
let mut cmd = Command::new("emacs");
|
||||||
HeadlineLevelFilter::Odd => "(setq org-odd-levels-only t)\n",
|
let cmd = cmd
|
||||||
HeadlineLevelFilter::OddEven => "(setq org-odd-levels-only nil)\n",
|
.arg("-q")
|
||||||
};
|
.arg("--no-site-file")
|
||||||
}
|
.arg("--no-splash")
|
||||||
ret
|
.arg("--batch")
|
||||||
|
.arg("--eval")
|
||||||
|
.arg(elisp_script);
|
||||||
|
|
||||||
|
let out = cmd.output().await?;
|
||||||
|
out.status.exit_ok()?;
|
||||||
|
Ok(String::from_utf8(out.stderr)?)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) async fn get_org_mode_version() -> Result<String, Box<dyn std::error::Error>> {
|
||||||
|
let elisp_script = r#"(progn
|
||||||
|
(org-mode)
|
||||||
|
(message "%s" (org-version nil t nil))
|
||||||
|
)"#;
|
||||||
|
let mut cmd = Command::new("emacs");
|
||||||
|
let cmd = cmd
|
||||||
|
.arg("-q")
|
||||||
|
.arg("--no-site-file")
|
||||||
|
.arg("--no-splash")
|
||||||
|
.arg("--batch")
|
||||||
|
.arg("--eval")
|
||||||
|
.arg(elisp_script);
|
||||||
|
|
||||||
|
let out = cmd.output().await?;
|
||||||
|
out.status.exit_ok()?;
|
||||||
|
Ok(String::from_utf8(out.stderr)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn emacs_parse_anonymous_org_document<'g, 's, C>(
|
pub(crate) async fn emacs_parse_anonymous_org_document<'g, 's, C>(
|
||||||
@@ -144,39 +169,23 @@ where
|
|||||||
output
|
output
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_emacs_version() -> Result<String, Box<dyn std::error::Error>> {
|
/// Generate elisp to configure org-mode parsing settings
|
||||||
let elisp_script = r#"(progn
|
///
|
||||||
(message "%s" (version))
|
/// Currently only org-list-allow-alphabetical is supported.
|
||||||
)"#;
|
fn global_settings_elisp(global_settings: &GlobalSettings) -> String {
|
||||||
let mut cmd = Command::new("emacs");
|
// This string concatenation is wildly inefficient but its only called in tests 🤷.
|
||||||
let cmd = cmd
|
let mut ret = "".to_owned();
|
||||||
.arg("-q")
|
if global_settings.list_allow_alphabetical {
|
||||||
.arg("--no-site-file")
|
ret += "(setq org-list-allow-alphabetical t)\n"
|
||||||
.arg("--no-splash")
|
}
|
||||||
.arg("--batch")
|
if global_settings.tab_width != crate::settings::DEFAULT_TAB_WIDTH {
|
||||||
.arg("--eval")
|
ret += format!("(setq-default tab-width {})", global_settings.tab_width).as_str();
|
||||||
.arg(elisp_script);
|
}
|
||||||
|
if global_settings.odd_levels_only != HeadlineLevelFilter::default() {
|
||||||
let out = cmd.output().await?;
|
ret += match global_settings.odd_levels_only {
|
||||||
out.status.exit_ok()?;
|
HeadlineLevelFilter::Odd => "(setq org-odd-levels-only t)\n",
|
||||||
Ok(String::from_utf8(out.stderr)?)
|
HeadlineLevelFilter::OddEven => "(setq org-odd-levels-only nil)\n",
|
||||||
}
|
};
|
||||||
|
}
|
||||||
pub async fn get_org_mode_version() -> Result<String, Box<dyn std::error::Error>> {
|
ret
|
||||||
let elisp_script = r#"(progn
|
|
||||||
(org-mode)
|
|
||||||
(message "%s" (org-version nil t nil))
|
|
||||||
)"#;
|
|
||||||
let mut cmd = Command::new("emacs");
|
|
||||||
let cmd = cmd
|
|
||||||
.arg("-q")
|
|
||||||
.arg("--no-site-file")
|
|
||||||
.arg("--no-splash")
|
|
||||||
.arg("--batch")
|
|
||||||
.arg("--eval")
|
|
||||||
.arg(elisp_script);
|
|
||||||
|
|
||||||
let out = cmd.output().await?;
|
|
||||||
out.status.exit_ok()?;
|
|
||||||
Ok(String::from_utf8(out.stderr)?)
|
|
||||||
}
|
}
|
||||||
14
src/util/elisp/mod.rs
Normal file
14
src/util/elisp/mod.rs
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
mod sexp;
|
||||||
|
mod util;
|
||||||
|
|
||||||
|
pub use sexp::sexp;
|
||||||
|
pub(crate) use sexp::unquote;
|
||||||
|
#[cfg(feature = "wasm_test")]
|
||||||
|
pub(crate) use sexp::TextWithProperties;
|
||||||
|
pub use sexp::Token;
|
||||||
|
#[cfg(feature = "compare")]
|
||||||
|
pub(crate) use util::get_emacs_standard_properties;
|
||||||
|
#[cfg(feature = "wasm_test")]
|
||||||
|
pub(crate) use util::maybe_token_to_usize;
|
||||||
|
#[cfg(feature = "wasm_test")]
|
||||||
|
pub(crate) use util::EmacsStandardProperties;
|
||||||
@@ -61,6 +61,7 @@ impl<'s> Token<'s> {
|
|||||||
}?)
|
}?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "compare")]
|
||||||
pub(crate) fn as_text<'p>(
|
pub(crate) fn as_text<'p>(
|
||||||
&'p self,
|
&'p self,
|
||||||
) -> Result<&'p TextWithProperties<'s>, Box<dyn std::error::Error>> {
|
) -> Result<&'p TextWithProperties<'s>, Box<dyn std::error::Error>> {
|
||||||
76
src/util/elisp/util.rs
Normal file
76
src/util/elisp/util.rs
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
use super::Token;
|
||||||
|
|
||||||
|
pub(crate) fn maybe_token_to_usize(
|
||||||
|
token: Option<&Token<'_>>,
|
||||||
|
) -> Result<Option<usize>, Box<dyn std::error::Error>> {
|
||||||
|
Ok(token
|
||||||
|
.map(|token| token.as_atom())
|
||||||
|
.map_or(Ok(None), |r| r.map(Some))?
|
||||||
|
.and_then(|val| {
|
||||||
|
if val == "nil" {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(val.parse::<usize>())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.map_or(Ok(None), |r| r.map(Some))?)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) struct EmacsStandardProperties {
|
||||||
|
pub(crate) begin: Option<usize>,
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub(crate) post_affiliated: Option<usize>,
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub(crate) contents_begin: Option<usize>,
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub(crate) contents_end: Option<usize>,
|
||||||
|
pub(crate) end: Option<usize>,
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub(crate) post_blank: Option<usize>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "compare")]
|
||||||
|
pub(crate) fn get_emacs_standard_properties(
|
||||||
|
emacs: &Token<'_>,
|
||||||
|
) -> Result<EmacsStandardProperties, Box<dyn std::error::Error>> {
|
||||||
|
let children = emacs.as_list()?;
|
||||||
|
let attributes_child = children.get(1).ok_or("Should have an attributes child.")?;
|
||||||
|
let attributes_map = attributes_child.as_map()?;
|
||||||
|
let standard_properties = attributes_map.get(":standard-properties");
|
||||||
|
Ok(if standard_properties.is_some() {
|
||||||
|
let mut std_props = standard_properties
|
||||||
|
.expect("if statement proves its Some")
|
||||||
|
.as_vector()?
|
||||||
|
.iter();
|
||||||
|
let begin = maybe_token_to_usize(std_props.next())?;
|
||||||
|
let post_affiliated = maybe_token_to_usize(std_props.next())?;
|
||||||
|
let contents_begin = maybe_token_to_usize(std_props.next())?;
|
||||||
|
let contents_end = maybe_token_to_usize(std_props.next())?;
|
||||||
|
let end = maybe_token_to_usize(std_props.next())?;
|
||||||
|
let post_blank = maybe_token_to_usize(std_props.next())?;
|
||||||
|
EmacsStandardProperties {
|
||||||
|
begin,
|
||||||
|
post_affiliated,
|
||||||
|
contents_begin,
|
||||||
|
contents_end,
|
||||||
|
end,
|
||||||
|
post_blank,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let begin = maybe_token_to_usize(attributes_map.get(":begin").copied())?;
|
||||||
|
let end = maybe_token_to_usize(attributes_map.get(":end").copied())?;
|
||||||
|
let contents_begin = maybe_token_to_usize(attributes_map.get(":contents-begin").copied())?;
|
||||||
|
let contents_end = maybe_token_to_usize(attributes_map.get(":contents-end").copied())?;
|
||||||
|
let post_blank = maybe_token_to_usize(attributes_map.get(":post-blank").copied())?;
|
||||||
|
let post_affiliated =
|
||||||
|
maybe_token_to_usize(attributes_map.get(":post-affiliated").copied())?;
|
||||||
|
EmacsStandardProperties {
|
||||||
|
begin,
|
||||||
|
post_affiliated,
|
||||||
|
contents_begin,
|
||||||
|
contents_end,
|
||||||
|
end,
|
||||||
|
post_blank,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
8
src/util/mod.rs
Normal file
8
src/util/mod.rs
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#[cfg(any(feature = "compare", feature = "wasm_test"))]
|
||||||
|
pub mod cli;
|
||||||
|
#[cfg(any(feature = "compare", feature = "wasm_test"))]
|
||||||
|
pub mod elisp;
|
||||||
|
#[cfg(any(feature = "compare", feature = "wasm", feature = "wasm_test"))]
|
||||||
|
pub mod elisp_fact;
|
||||||
|
#[cfg(any(feature = "compare", feature = "wasm_test"))]
|
||||||
|
pub mod terminal;
|
||||||
42
src/util/terminal.rs
Normal file
42
src/util/terminal.rs
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
use std::borrow::Cow;
|
||||||
|
|
||||||
|
fn should_use_color() -> bool {
|
||||||
|
!std::env::var("NO_COLOR").is_ok_and(|val| !val.is_empty())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn foreground_color(red: u8, green: u8, blue: u8) -> Cow<'static, str> {
|
||||||
|
if should_use_color() {
|
||||||
|
format!(
|
||||||
|
"\x1b[38;2;{red};{green};{blue}m",
|
||||||
|
red = red,
|
||||||
|
green = green,
|
||||||
|
blue = blue
|
||||||
|
)
|
||||||
|
.into()
|
||||||
|
} else {
|
||||||
|
Cow::from("")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub(crate) fn background_color(red: u8, green: u8, blue: u8) -> Cow<'static, str> {
|
||||||
|
if should_use_color() {
|
||||||
|
format!(
|
||||||
|
"\x1b[48;2;{red};{green};{blue}m",
|
||||||
|
red = red,
|
||||||
|
green = green,
|
||||||
|
blue = blue
|
||||||
|
)
|
||||||
|
.into()
|
||||||
|
} else {
|
||||||
|
Cow::from("")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn reset_color() -> &'static str {
|
||||||
|
if should_use_color() {
|
||||||
|
"\x1b[0m"
|
||||||
|
} else {
|
||||||
|
""
|
||||||
|
}
|
||||||
|
}
|
||||||
95
src/wasm/additional_property.rs
Normal file
95
src/wasm/additional_property.rs
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use serde::Deserialize;
|
||||||
|
use serde::Serialize;
|
||||||
|
|
||||||
|
use super::macros::to_wasm;
|
||||||
|
use super::to_wasm::ToWasm;
|
||||||
|
use super::WasmAstNode;
|
||||||
|
use crate::types::AffiliatedKeywordValue;
|
||||||
|
use crate::types::AffiliatedKeywords;
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
#[serde(untagged)]
|
||||||
|
pub enum AdditionalPropertyValue {
|
||||||
|
SingleString(String),
|
||||||
|
ListOfStrings(Vec<String>),
|
||||||
|
OptionalPair {
|
||||||
|
optval: Option<String>,
|
||||||
|
val: String,
|
||||||
|
},
|
||||||
|
ObjectTree {
|
||||||
|
#[serde(rename = "object-tree")]
|
||||||
|
object_tree: Vec<(Option<Vec<WasmAstNode>>, Vec<WasmAstNode>)>,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize, Default)]
|
||||||
|
pub struct AdditionalProperties {
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub(crate) properties: HashMap<String, AdditionalPropertyValue>,
|
||||||
|
}
|
||||||
|
|
||||||
|
to_wasm!(
|
||||||
|
AdditionalProperties,
|
||||||
|
AffiliatedKeywords<'s>,
|
||||||
|
original,
|
||||||
|
wasm_context,
|
||||||
|
{
|
||||||
|
let mut additional_properties = AdditionalProperties::default();
|
||||||
|
for (name, val) in original.keywords.iter() {
|
||||||
|
let converted_val = match val {
|
||||||
|
AffiliatedKeywordValue::SingleString(val) => {
|
||||||
|
AdditionalPropertyValue::SingleString((*val).to_owned())
|
||||||
|
}
|
||||||
|
AffiliatedKeywordValue::ListOfStrings(val) => {
|
||||||
|
AdditionalPropertyValue::ListOfStrings(
|
||||||
|
val.iter().map(|s| (*s).to_owned()).collect(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
AffiliatedKeywordValue::OptionalPair { optval, val } => {
|
||||||
|
AdditionalPropertyValue::OptionalPair {
|
||||||
|
optval: optval.map(|s| (*s).to_owned()),
|
||||||
|
val: (*val).to_owned(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AffiliatedKeywordValue::ObjectTree(val) => {
|
||||||
|
let mut ret = Vec::with_capacity(val.len());
|
||||||
|
|
||||||
|
for (optval, value) in val {
|
||||||
|
let converted_optval = if let Some(optval) = optval {
|
||||||
|
Some(
|
||||||
|
optval
|
||||||
|
.iter()
|
||||||
|
.map(|child| {
|
||||||
|
child
|
||||||
|
.to_wasm(wasm_context.clone())
|
||||||
|
.map(Into::<WasmAstNode>::into)
|
||||||
|
})
|
||||||
|
.collect::<Result<Vec<_>, _>>()?,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
let converted_value = value
|
||||||
|
.iter()
|
||||||
|
.map(|child| {
|
||||||
|
child
|
||||||
|
.to_wasm(wasm_context.clone())
|
||||||
|
.map(Into::<WasmAstNode>::into)
|
||||||
|
})
|
||||||
|
.collect::<Result<Vec<_>, _>>()?;
|
||||||
|
|
||||||
|
ret.push((converted_optval, converted_value));
|
||||||
|
}
|
||||||
|
|
||||||
|
AdditionalPropertyValue::ObjectTree { object_tree: ret }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
additional_properties
|
||||||
|
.properties
|
||||||
|
.insert(name.clone(), converted_val);
|
||||||
|
}
|
||||||
|
Ok(additional_properties)
|
||||||
|
}
|
||||||
|
);
|
||||||
54
src/wasm/angle_link.rs
Normal file
54
src/wasm/angle_link.rs
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
use std::borrow::Cow;
|
||||||
|
|
||||||
|
use serde::Deserialize;
|
||||||
|
use serde::Serialize;
|
||||||
|
|
||||||
|
use super::ast_node::WasmAstNode;
|
||||||
|
use super::macros::to_wasm;
|
||||||
|
use super::to_wasm::ToWasm;
|
||||||
|
use crate::types::AngleLink;
|
||||||
|
use crate::types::LinkType;
|
||||||
|
use crate::util::elisp_fact::ElispFact;
|
||||||
|
use crate::wasm::to_wasm::ToWasmStandardProperties;
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
#[serde(tag = "format")]
|
||||||
|
#[serde(rename = "angle")]
|
||||||
|
pub struct WasmAngleLink {
|
||||||
|
#[serde(rename = "type")]
|
||||||
|
pub(crate) link_type: String,
|
||||||
|
pub(crate) path: String,
|
||||||
|
#[serde(rename = "raw-link")]
|
||||||
|
pub(crate) raw_link: String,
|
||||||
|
pub(crate) application: Option<String>,
|
||||||
|
#[serde(rename = "search-option")]
|
||||||
|
pub(crate) search_option: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
to_wasm!(
|
||||||
|
WasmAngleLink,
|
||||||
|
AngleLink<'s>,
|
||||||
|
original,
|
||||||
|
wasm_context,
|
||||||
|
{ WasmAstNode::AngleLink(original) },
|
||||||
|
{ "link".into() },
|
||||||
|
{
|
||||||
|
Ok((
|
||||||
|
Vec::new(),
|
||||||
|
WasmAngleLink {
|
||||||
|
link_type: match &original.link_type {
|
||||||
|
LinkType::File => "file".to_owned(),
|
||||||
|
LinkType::Protocol(protocol) => protocol.clone().into_owned(),
|
||||||
|
LinkType::Id => "id".to_owned(),
|
||||||
|
LinkType::CustomId => "custom-id".to_owned(),
|
||||||
|
LinkType::CodeRef => "coderef".to_owned(),
|
||||||
|
LinkType::Fuzzy => "fuzzy".to_owned(),
|
||||||
|
},
|
||||||
|
path: original.get_path().into_owned(),
|
||||||
|
raw_link: original.raw_link.to_owned(),
|
||||||
|
application: original.application.map(|c| c.to_owned()),
|
||||||
|
search_option: original.get_search_option().map(Cow::into_owned),
|
||||||
|
},
|
||||||
|
))
|
||||||
|
}
|
||||||
|
);
|
||||||
142
src/wasm/ast_node.rs
Normal file
142
src/wasm/ast_node.rs
Normal file
@@ -0,0 +1,142 @@
|
|||||||
|
use serde::Deserialize;
|
||||||
|
use serde::Serialize;
|
||||||
|
|
||||||
|
use super::angle_link::WasmAngleLink;
|
||||||
|
use super::babel_call::WasmBabelCall;
|
||||||
|
use super::bold::WasmBold;
|
||||||
|
use super::center_block::WasmCenterBlock;
|
||||||
|
use super::citation::WasmCitation;
|
||||||
|
use super::citation_reference::WasmCitationReference;
|
||||||
|
use super::clock::WasmClock;
|
||||||
|
use super::code::WasmCode;
|
||||||
|
use super::comment::WasmComment;
|
||||||
|
use super::comment_block::WasmCommentBlock;
|
||||||
|
use super::diary_sexp::WasmDiarySexp;
|
||||||
|
use super::document::WasmDocument;
|
||||||
|
use super::drawer::WasmDrawer;
|
||||||
|
use super::dynamic_block::WasmDynamicBlock;
|
||||||
|
use super::entity::WasmEntity;
|
||||||
|
use super::example_block::WasmExampleBlock;
|
||||||
|
use super::export_block::WasmExportBlock;
|
||||||
|
use super::export_snippet::WasmExportSnippet;
|
||||||
|
use super::fixed_width_area::WasmFixedWidthArea;
|
||||||
|
use super::footnote_definition::WasmFootnoteDefinition;
|
||||||
|
use super::footnote_reference::WasmFootnoteReference;
|
||||||
|
use super::headline::WasmHeadline;
|
||||||
|
use super::horizontal_rule::WasmHorizontalRule;
|
||||||
|
use super::inline_babel_call::WasmInlineBabelCall;
|
||||||
|
use super::inline_source_block::WasmInlineSourceBlock;
|
||||||
|
use super::italic::WasmItalic;
|
||||||
|
use super::keyword::WasmKeyword;
|
||||||
|
use super::latex_environment::WasmLatexEnvironment;
|
||||||
|
use super::latex_fragment::WasmLatexFragment;
|
||||||
|
use super::line_break::WasmLineBreak;
|
||||||
|
use super::node_property::WasmNodeProperty;
|
||||||
|
use super::org_macro::WasmOrgMacro;
|
||||||
|
use super::paragraph::WasmParagraph;
|
||||||
|
use super::plain_link::WasmPlainLink;
|
||||||
|
use super::plain_list::WasmPlainList;
|
||||||
|
use super::plain_list_item::WasmPlainListItem;
|
||||||
|
use super::plain_text::WasmPlainText;
|
||||||
|
use super::planning::WasmPlanning;
|
||||||
|
use super::property_drawer::WasmPropertyDrawer;
|
||||||
|
use super::quote_block::WasmQuoteBlock;
|
||||||
|
use super::radio_link::WasmRadioLink;
|
||||||
|
use super::radio_target::WasmRadioTarget;
|
||||||
|
use super::regular_link::WasmRegularLink;
|
||||||
|
use super::section::WasmSection;
|
||||||
|
use super::special_block::WasmSpecialBlock;
|
||||||
|
use super::src_block::WasmSrcBlock;
|
||||||
|
use super::statistics_cookie::WasmStatisticsCookie;
|
||||||
|
use super::strike_through::WasmStrikeThrough;
|
||||||
|
use super::subscript::WasmSubscript;
|
||||||
|
use super::superscript::WasmSuperscript;
|
||||||
|
use super::table::WasmTable;
|
||||||
|
use super::table_cell::WasmTableCell;
|
||||||
|
use super::table_row::WasmTableRow;
|
||||||
|
use super::target::WasmTarget;
|
||||||
|
use super::timestamp::WasmTimestamp;
|
||||||
|
use super::underline::WasmUnderline;
|
||||||
|
use super::verbatim::WasmVerbatim;
|
||||||
|
use super::verse_block::WasmVerseBlock;
|
||||||
|
use super::WasmStandardProperties;
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub struct WasmAstNodeWrapper<I> {
|
||||||
|
#[serde(rename = "ast-node")]
|
||||||
|
pub(crate) ast_node: String,
|
||||||
|
#[serde(rename = "standard-properties")]
|
||||||
|
pub(crate) standard_properties: WasmStandardProperties,
|
||||||
|
#[serde(rename = "children")]
|
||||||
|
pub(crate) children: Vec<WasmAstNode>,
|
||||||
|
#[serde(rename = "properties")]
|
||||||
|
pub(crate) properties: I,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
#[serde(untagged)]
|
||||||
|
pub enum WasmAstNode {
|
||||||
|
// Document Nodes
|
||||||
|
Document(WasmAstNodeWrapper<WasmDocument>),
|
||||||
|
Headline(WasmAstNodeWrapper<WasmHeadline>),
|
||||||
|
Section(WasmAstNodeWrapper<WasmSection>),
|
||||||
|
// Elements
|
||||||
|
Paragraph(WasmAstNodeWrapper<WasmParagraph>),
|
||||||
|
PlainList(WasmAstNodeWrapper<WasmPlainList>),
|
||||||
|
PlainListItem(WasmAstNodeWrapper<WasmPlainListItem>),
|
||||||
|
CenterBlock(WasmAstNodeWrapper<WasmCenterBlock>),
|
||||||
|
QuoteBlock(WasmAstNodeWrapper<WasmQuoteBlock>),
|
||||||
|
SpecialBlock(WasmAstNodeWrapper<WasmSpecialBlock>),
|
||||||
|
DynamicBlock(WasmAstNodeWrapper<WasmDynamicBlock>),
|
||||||
|
FootnoteDefinition(WasmAstNodeWrapper<WasmFootnoteDefinition>),
|
||||||
|
Comment(WasmAstNodeWrapper<WasmComment>),
|
||||||
|
Drawer(WasmAstNodeWrapper<WasmDrawer>),
|
||||||
|
PropertyDrawer(WasmAstNodeWrapper<WasmPropertyDrawer>),
|
||||||
|
NodeProperty(WasmAstNodeWrapper<WasmNodeProperty>),
|
||||||
|
Table(WasmAstNodeWrapper<WasmTable>),
|
||||||
|
TableRow(WasmAstNodeWrapper<WasmTableRow>),
|
||||||
|
VerseBlock(WasmAstNodeWrapper<WasmVerseBlock>),
|
||||||
|
CommentBlock(WasmAstNodeWrapper<WasmCommentBlock>),
|
||||||
|
ExampleBlock(WasmAstNodeWrapper<WasmExampleBlock>),
|
||||||
|
ExportBlock(WasmAstNodeWrapper<WasmExportBlock>),
|
||||||
|
SrcBlock(WasmAstNodeWrapper<WasmSrcBlock>),
|
||||||
|
Clock(WasmAstNodeWrapper<WasmClock>),
|
||||||
|
DiarySexp(WasmAstNodeWrapper<WasmDiarySexp>),
|
||||||
|
Planning(WasmAstNodeWrapper<WasmPlanning>),
|
||||||
|
FixedWidthArea(WasmAstNodeWrapper<WasmFixedWidthArea>),
|
||||||
|
HorizontalRule(WasmAstNodeWrapper<WasmHorizontalRule>),
|
||||||
|
Keyword(WasmAstNodeWrapper<WasmKeyword>),
|
||||||
|
BabelCall(WasmAstNodeWrapper<WasmBabelCall>),
|
||||||
|
LatexEnvironment(WasmAstNodeWrapper<WasmLatexEnvironment>),
|
||||||
|
// Objects
|
||||||
|
Bold(WasmAstNodeWrapper<WasmBold>),
|
||||||
|
Italic(WasmAstNodeWrapper<WasmItalic>),
|
||||||
|
Underline(WasmAstNodeWrapper<WasmUnderline>),
|
||||||
|
StrikeThrough(WasmAstNodeWrapper<WasmStrikeThrough>),
|
||||||
|
Code(WasmAstNodeWrapper<WasmCode>),
|
||||||
|
Verbatim(WasmAstNodeWrapper<WasmVerbatim>),
|
||||||
|
PlainText(WasmAstNodeWrapper<WasmPlainText>),
|
||||||
|
RegularLink(WasmAstNodeWrapper<WasmRegularLink>),
|
||||||
|
RadioLink(WasmAstNodeWrapper<WasmRadioLink>),
|
||||||
|
RadioTarget(WasmAstNodeWrapper<WasmRadioTarget>),
|
||||||
|
PlainLink(WasmAstNodeWrapper<WasmPlainLink>),
|
||||||
|
AngleLink(WasmAstNodeWrapper<WasmAngleLink>),
|
||||||
|
OrgMacro(WasmAstNodeWrapper<WasmOrgMacro>),
|
||||||
|
Entity(WasmAstNodeWrapper<WasmEntity>),
|
||||||
|
LatexFragment(WasmAstNodeWrapper<WasmLatexFragment>),
|
||||||
|
ExportSnippet(WasmAstNodeWrapper<WasmExportSnippet>),
|
||||||
|
FootnoteReference(WasmAstNodeWrapper<WasmFootnoteReference>),
|
||||||
|
Citation(WasmAstNodeWrapper<WasmCitation>),
|
||||||
|
CitationReference(WasmAstNodeWrapper<WasmCitationReference>),
|
||||||
|
InlineBabelCall(WasmAstNodeWrapper<WasmInlineBabelCall>),
|
||||||
|
InlineSourceBlock(WasmAstNodeWrapper<WasmInlineSourceBlock>),
|
||||||
|
LineBreak(WasmAstNodeWrapper<WasmLineBreak>),
|
||||||
|
Target(WasmAstNodeWrapper<WasmTarget>),
|
||||||
|
StatisticsCookie(WasmAstNodeWrapper<WasmStatisticsCookie>),
|
||||||
|
Subscript(WasmAstNodeWrapper<WasmSubscript>),
|
||||||
|
Superscript(WasmAstNodeWrapper<WasmSuperscript>),
|
||||||
|
TableCell(WasmAstNodeWrapper<WasmTableCell>),
|
||||||
|
Timestamp(WasmAstNodeWrapper<WasmTimestamp>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WasmAstNode {}
|
||||||
50
src/wasm/babel_call.rs
Normal file
50
src/wasm/babel_call.rs
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
use serde::Deserialize;
|
||||||
|
use serde::Serialize;
|
||||||
|
|
||||||
|
use super::ast_node::WasmAstNode;
|
||||||
|
use super::macros::to_wasm;
|
||||||
|
use super::to_wasm::ToWasm;
|
||||||
|
use super::AdditionalProperties;
|
||||||
|
use crate::types::BabelCall;
|
||||||
|
use crate::types::GetAffiliatedKeywords;
|
||||||
|
use crate::util::elisp_fact::ElispFact;
|
||||||
|
use crate::wasm::to_wasm::ToWasmStandardProperties;
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub struct WasmBabelCall {
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub(crate) additional_properties: AdditionalProperties,
|
||||||
|
pub(crate) call: Option<String>,
|
||||||
|
#[serde(rename = "inside-header")]
|
||||||
|
pub(crate) inside_header: Option<String>,
|
||||||
|
pub(crate) arguments: Option<String>,
|
||||||
|
#[serde(rename = "end-header")]
|
||||||
|
pub(crate) end_header: Option<String>,
|
||||||
|
pub(crate) value: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
to_wasm!(
|
||||||
|
WasmBabelCall,
|
||||||
|
BabelCall<'s>,
|
||||||
|
original,
|
||||||
|
wasm_context,
|
||||||
|
{ WasmAstNode::BabelCall(original) },
|
||||||
|
{ "babel-call".into() },
|
||||||
|
{
|
||||||
|
let additional_properties = original
|
||||||
|
.get_affiliated_keywords()
|
||||||
|
.to_wasm(wasm_context.clone())?;
|
||||||
|
|
||||||
|
Ok((
|
||||||
|
Vec::new(),
|
||||||
|
WasmBabelCall {
|
||||||
|
additional_properties,
|
||||||
|
call: original.call.map(|s| s.to_owned()),
|
||||||
|
inside_header: original.inside_header.map(|s| s.to_owned()),
|
||||||
|
arguments: original.arguments.map(|s| s.to_owned()),
|
||||||
|
end_header: original.end_header.map(|s| s.to_owned()),
|
||||||
|
value: original.value.to_owned(),
|
||||||
|
},
|
||||||
|
))
|
||||||
|
}
|
||||||
|
);
|
||||||
34
src/wasm/bold.rs
Normal file
34
src/wasm/bold.rs
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
use serde::Deserialize;
|
||||||
|
use serde::Serialize;
|
||||||
|
|
||||||
|
use super::ast_node::WasmAstNode;
|
||||||
|
use super::macros::to_wasm;
|
||||||
|
use super::to_wasm::ToWasm;
|
||||||
|
use crate::types::Bold;
|
||||||
|
use crate::util::elisp_fact::ElispFact;
|
||||||
|
use crate::wasm::to_wasm::ToWasmStandardProperties;
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub struct WasmBold {}
|
||||||
|
|
||||||
|
to_wasm!(
|
||||||
|
WasmBold,
|
||||||
|
Bold<'s>,
|
||||||
|
original,
|
||||||
|
wasm_context,
|
||||||
|
{ WasmAstNode::Bold(original) },
|
||||||
|
{ "bold".into() },
|
||||||
|
{
|
||||||
|
let children = original
|
||||||
|
.children
|
||||||
|
.iter()
|
||||||
|
.map(|child| {
|
||||||
|
child
|
||||||
|
.to_wasm(wasm_context.clone())
|
||||||
|
.map(Into::<WasmAstNode>::into)
|
||||||
|
})
|
||||||
|
.collect::<Result<Vec<_>, _>>()?;
|
||||||
|
|
||||||
|
Ok((children, WasmBold {}))
|
||||||
|
}
|
||||||
|
);
|
||||||
48
src/wasm/center_block.rs
Normal file
48
src/wasm/center_block.rs
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
use serde::Deserialize;
|
||||||
|
use serde::Serialize;
|
||||||
|
|
||||||
|
use super::ast_node::WasmAstNode;
|
||||||
|
use super::macros::to_wasm;
|
||||||
|
use super::to_wasm::ToWasm;
|
||||||
|
use super::AdditionalProperties;
|
||||||
|
use crate::types::CenterBlock;
|
||||||
|
use crate::types::GetAffiliatedKeywords;
|
||||||
|
use crate::util::elisp_fact::ElispFact;
|
||||||
|
use crate::wasm::to_wasm::ToWasmStandardProperties;
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub struct WasmCenterBlock {
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub(crate) additional_properties: AdditionalProperties,
|
||||||
|
}
|
||||||
|
|
||||||
|
to_wasm!(
|
||||||
|
WasmCenterBlock,
|
||||||
|
CenterBlock<'s>,
|
||||||
|
original,
|
||||||
|
wasm_context,
|
||||||
|
{ WasmAstNode::CenterBlock(original) },
|
||||||
|
{ "center-block".into() },
|
||||||
|
{
|
||||||
|
let additional_properties = original
|
||||||
|
.get_affiliated_keywords()
|
||||||
|
.to_wasm(wasm_context.clone())?;
|
||||||
|
|
||||||
|
let children = original
|
||||||
|
.children
|
||||||
|
.iter()
|
||||||
|
.map(|child| {
|
||||||
|
child
|
||||||
|
.to_wasm(wasm_context.clone())
|
||||||
|
.map(Into::<WasmAstNode>::into)
|
||||||
|
})
|
||||||
|
.collect::<Result<Vec<_>, _>>()?;
|
||||||
|
|
||||||
|
Ok((
|
||||||
|
children,
|
||||||
|
WasmCenterBlock {
|
||||||
|
additional_properties,
|
||||||
|
},
|
||||||
|
))
|
||||||
|
}
|
||||||
|
);
|
||||||
71
src/wasm/citation.rs
Normal file
71
src/wasm/citation.rs
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
use serde::Deserialize;
|
||||||
|
use serde::Serialize;
|
||||||
|
|
||||||
|
use super::ast_node::WasmAstNode;
|
||||||
|
use super::macros::to_wasm;
|
||||||
|
use super::to_wasm::ToWasm;
|
||||||
|
use crate::types::Citation;
|
||||||
|
use crate::util::elisp_fact::ElispFact;
|
||||||
|
use crate::wasm::to_wasm::ToWasmStandardProperties;
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub struct WasmCitation {
|
||||||
|
pub(crate) style: Option<String>,
|
||||||
|
pub(crate) prefix: Option<Vec<WasmAstNode>>,
|
||||||
|
pub(crate) suffix: Option<Vec<WasmAstNode>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
to_wasm!(
|
||||||
|
WasmCitation,
|
||||||
|
Citation<'s>,
|
||||||
|
original,
|
||||||
|
wasm_context,
|
||||||
|
{ WasmAstNode::Citation(original) },
|
||||||
|
{ "citation".into() },
|
||||||
|
{
|
||||||
|
let children = original
|
||||||
|
.children
|
||||||
|
.iter()
|
||||||
|
.map(|child| {
|
||||||
|
child
|
||||||
|
.to_wasm(wasm_context.clone())
|
||||||
|
.map(Into::<WasmAstNode>::into)
|
||||||
|
})
|
||||||
|
.collect::<Result<Vec<_>, _>>()?;
|
||||||
|
let prefix = original
|
||||||
|
.prefix
|
||||||
|
.iter()
|
||||||
|
.map(|child| {
|
||||||
|
child
|
||||||
|
.to_wasm(wasm_context.clone())
|
||||||
|
.map(Into::<WasmAstNode>::into)
|
||||||
|
})
|
||||||
|
.collect::<Result<Vec<_>, _>>()?;
|
||||||
|
let suffix = original
|
||||||
|
.suffix
|
||||||
|
.iter()
|
||||||
|
.map(|child| {
|
||||||
|
child
|
||||||
|
.to_wasm(wasm_context.clone())
|
||||||
|
.map(Into::<WasmAstNode>::into)
|
||||||
|
})
|
||||||
|
.collect::<Result<Vec<_>, _>>()?;
|
||||||
|
|
||||||
|
Ok((
|
||||||
|
children,
|
||||||
|
WasmCitation {
|
||||||
|
style: original.style.map(|s| s.to_owned()),
|
||||||
|
prefix: if prefix.is_empty() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(prefix)
|
||||||
|
},
|
||||||
|
suffix: if suffix.is_empty() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(suffix)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
))
|
||||||
|
}
|
||||||
|
);
|
||||||
62
src/wasm/citation_reference.rs
Normal file
62
src/wasm/citation_reference.rs
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
use serde::Deserialize;
|
||||||
|
use serde::Serialize;
|
||||||
|
|
||||||
|
use super::ast_node::WasmAstNode;
|
||||||
|
use super::macros::to_wasm;
|
||||||
|
use super::to_wasm::ToWasm;
|
||||||
|
use crate::types::CitationReference;
|
||||||
|
use crate::util::elisp_fact::ElispFact;
|
||||||
|
use crate::wasm::to_wasm::ToWasmStandardProperties;
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub struct WasmCitationReference {
|
||||||
|
pub(crate) key: String,
|
||||||
|
pub(crate) prefix: Option<Vec<WasmAstNode>>,
|
||||||
|
pub(crate) suffix: Option<Vec<WasmAstNode>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
to_wasm!(
|
||||||
|
WasmCitationReference,
|
||||||
|
CitationReference<'s>,
|
||||||
|
original,
|
||||||
|
wasm_context,
|
||||||
|
{ WasmAstNode::CitationReference(original) },
|
||||||
|
{ "citation-reference".into() },
|
||||||
|
{
|
||||||
|
let prefix = original
|
||||||
|
.prefix
|
||||||
|
.iter()
|
||||||
|
.map(|child| {
|
||||||
|
child
|
||||||
|
.to_wasm(wasm_context.clone())
|
||||||
|
.map(Into::<WasmAstNode>::into)
|
||||||
|
})
|
||||||
|
.collect::<Result<Vec<_>, _>>()?;
|
||||||
|
let suffix = original
|
||||||
|
.suffix
|
||||||
|
.iter()
|
||||||
|
.map(|child| {
|
||||||
|
child
|
||||||
|
.to_wasm(wasm_context.clone())
|
||||||
|
.map(Into::<WasmAstNode>::into)
|
||||||
|
})
|
||||||
|
.collect::<Result<Vec<_>, _>>()?;
|
||||||
|
|
||||||
|
Ok((
|
||||||
|
Vec::new(),
|
||||||
|
WasmCitationReference {
|
||||||
|
key: original.key.to_owned(),
|
||||||
|
prefix: if prefix.is_empty() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(prefix)
|
||||||
|
},
|
||||||
|
suffix: if suffix.is_empty() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(suffix)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
))
|
||||||
|
}
|
||||||
|
);
|
||||||
43
src/wasm/clock.rs
Normal file
43
src/wasm/clock.rs
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
use serde::Deserialize;
|
||||||
|
use serde::Serialize;
|
||||||
|
|
||||||
|
use super::ast_node::WasmAstNode;
|
||||||
|
use super::macros::to_wasm;
|
||||||
|
use super::to_wasm::ToWasm;
|
||||||
|
use crate::types::Clock;
|
||||||
|
use crate::types::ClockStatus;
|
||||||
|
use crate::util::elisp_fact::ElispFact;
|
||||||
|
use crate::wasm::to_wasm::ToWasmStandardProperties;
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub struct WasmClock {
|
||||||
|
#[serde(rename = "value")]
|
||||||
|
pub(crate) timestamp: Box<WasmAstNode>,
|
||||||
|
pub(crate) duration: Option<String>,
|
||||||
|
pub(crate) status: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
to_wasm!(
|
||||||
|
WasmClock,
|
||||||
|
Clock<'s>,
|
||||||
|
original,
|
||||||
|
wasm_context,
|
||||||
|
{ WasmAstNode::Clock(original) },
|
||||||
|
{ "clock".into() },
|
||||||
|
{
|
||||||
|
Ok((
|
||||||
|
Vec::new(),
|
||||||
|
WasmClock {
|
||||||
|
timestamp: Box::new(Into::<WasmAstNode>::into(
|
||||||
|
original.timestamp.to_wasm(wasm_context.clone())?,
|
||||||
|
)),
|
||||||
|
duration: original.duration.map(|s| s.to_owned()),
|
||||||
|
status: match original.status {
|
||||||
|
ClockStatus::Running => "running",
|
||||||
|
ClockStatus::Closed => "closed",
|
||||||
|
}
|
||||||
|
.to_owned(),
|
||||||
|
},
|
||||||
|
))
|
||||||
|
}
|
||||||
|
);
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user