Compare commits
430 Commits
fb412bc2cd
...
v0.1.14
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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 | ||
|
|
175ff1e6c4 | ||
|
|
0b42139393 | ||
|
|
67a9103b07 | ||
|
|
f141a4e186 | ||
|
|
aba29df34c | ||
|
|
87ce7d7432 | ||
|
|
68dccd54b1 | ||
|
|
4753f4c7c6 | ||
|
|
13c62bf29f | ||
|
|
670209e9fc | ||
|
|
4af0d3141f | ||
|
|
ab281de3c6 | ||
|
|
d556d28f49 | ||
|
|
9cfb2fa052 | ||
|
|
30c03b5529 | ||
|
|
b943f90766 | ||
|
|
0108f5b0b1 | ||
|
|
50145c6cf2 | ||
|
|
4a8607726c | ||
|
|
9bcba4020d | ||
|
|
8fd9ff3848 | ||
|
|
3fb7cb82cd | ||
|
|
e0ec5c115f | ||
|
|
f0868ba3ed | ||
|
|
425bc12353 | ||
|
|
03754be71e | ||
|
|
70002800c2 | ||
|
|
281c35677b | ||
|
|
92d15c3d91 | ||
|
|
b1773ac90e | ||
|
|
645d9abf9c | ||
|
|
d2f2bdf88d | ||
|
|
90ba17b68c | ||
|
|
31406fd520 | ||
|
|
49bc51ba89 | ||
|
|
92592104a4 | ||
|
|
33f4614d28 | ||
|
|
6c197c376a | ||
|
|
bcf1b49db2 | ||
|
|
49f6e70a19 | ||
|
|
31fb815681 | ||
|
|
7dfe24ff98 | ||
|
|
a5627d0cee | ||
|
|
93cfa71df2 | ||
|
|
78320d3265 | ||
|
|
9e908935f8 | ||
|
|
b18a703529 | ||
|
|
ea52dc60be | ||
|
|
f5699ce830 | ||
|
|
10aa0956ee | ||
|
|
816c164996 | ||
|
|
ee201e1336 | ||
|
|
4897952330 | ||
|
|
e1d85c6dc2 | ||
|
|
c420ccd029 | ||
|
|
a880629831 | ||
|
|
5e2dea1f28 | ||
|
|
f47d688be4 | ||
|
|
acfc5e5e68 | ||
|
|
503db94b2c | ||
|
|
a4381e5e39 | ||
|
|
e11de60def | ||
|
|
b2479e9de8 | ||
|
|
49d1cef7ae | ||
|
|
ba72cc1b29 | ||
|
|
c58b0e7c35 | ||
|
|
f19d262825 | ||
|
|
68f3f2e159 | ||
|
|
269e23c1b1 | ||
|
|
e111b8b9b8 | ||
|
|
353ff07420 | ||
|
|
94dec31130 | ||
|
|
cf5d3ed745 | ||
|
|
b0b287cd47 | ||
|
|
bcdf1f5e9d | ||
|
|
17d8e76e05 | ||
|
|
8db9038c53 | ||
|
|
a276ba70e0 | ||
|
|
b7442c1e92 | ||
|
|
364ba79517 | ||
|
|
47408763e5 | ||
|
|
bd187ebfe7 | ||
|
|
59cb3c2bbf | ||
|
|
44f7412a5c | ||
|
|
01464057ad | ||
|
|
0208020e3e | ||
|
|
a2f53361eb | ||
|
|
17db05c2c7 | ||
|
|
6139ea328d | ||
|
|
d20b4a410b | ||
|
|
05c64f53b1 | ||
|
|
f65d0bb82d | ||
|
|
50d2831081 | ||
|
|
bc9bd4f97b | ||
|
|
369d3e8c50 | ||
|
|
7d73eb6bd4 | ||
|
|
f59f153ee7 | ||
|
|
20c4a0f8f7 | ||
|
|
e776a051ad | ||
|
|
77e6c22ad8 | ||
|
|
c9d7251e3b | ||
|
|
8417b5fc9d | ||
|
|
acc29e7977 | ||
|
|
ebc0a30035 | ||
|
|
e2d55e13d3 | ||
|
|
e4d9c5f467 | ||
|
|
d8e3a85ef7 | ||
|
|
464685b52b | ||
|
|
5fed4e80a7 | ||
|
|
e53140426f | ||
|
|
9a4d290cf8 | ||
|
|
acd24d6198 | ||
|
|
880b00ef3f | ||
|
|
3069711447 | ||
|
|
4b6c717812 | ||
|
|
1d329cc310 | ||
|
|
b4f9a3b9b6 | ||
|
|
2dd5246506 | ||
|
|
4ba0e3611b | ||
|
|
728f79b86c | ||
|
|
192a4a2891 | ||
|
|
fafd85fb30 | ||
|
|
1c23065329 | ||
|
|
ed105b04ad | ||
|
|
f10efec21d | ||
|
|
72b4cf8e71 | ||
|
|
547fc40dbe | ||
|
|
9f1671658d | ||
|
|
18d0676fad | ||
|
|
7833a58461 | ||
|
|
0020d71089 | ||
|
|
cfdf39d1fa | ||
|
|
26f1eae9a1 | ||
|
|
3eff85059a | ||
|
|
d2d0e9e5dd | ||
|
|
c86d1000c0 | ||
|
|
911634cb42 | ||
|
|
0aa746fb1e | ||
|
|
33800c4a88 | ||
|
|
909ccadfa1 | ||
|
|
e352deb989 | ||
|
|
f5a6a26c43 | ||
|
|
dd7184da54 | ||
|
|
1168ddb1fe | ||
|
|
77ab636e6a | ||
|
|
f5dcacc79d | ||
|
|
e7c3c7aab6 | ||
|
|
7603b0a1cc | ||
|
|
dea3721b1c | ||
|
|
4b54f95087 | ||
|
|
17c2e9fefe | ||
|
|
d2d8c1ffcf | ||
|
|
b9c638c280 | ||
|
|
8ac8f9fe6e | ||
|
|
ddb3144e66 | ||
|
|
ad5efc4b0f | ||
|
|
2de33b8150 | ||
|
|
e1fde88a60 | ||
|
|
123da9cca3 | ||
|
|
c20e7b5f2f | ||
|
|
74a3512038 | ||
|
|
ff04c4a131 | ||
|
|
00611e05c2 | ||
|
|
3e7e54a1bd | ||
|
|
aa35d1dc03 | ||
|
|
92afdc0ea6 | ||
|
|
f43920fc7c | ||
|
|
dde4bc7920 | ||
|
|
3d68e1fd00 | ||
|
|
8271f6b44a | ||
|
|
8a26965e14 | ||
|
|
3927889e66 | ||
|
|
5ecd7b8bef | ||
|
|
b0b795d13b | ||
|
|
182c2737cd | ||
|
|
5f93cabff5 | ||
|
|
a1f8cbe079 | ||
|
|
d7e870cba1 | ||
|
|
591b5ed382 | ||
|
|
fd141762f0 | ||
|
|
d59bbfa7d2 | ||
|
|
1d9f91cdd2 | ||
|
|
68f8e04ee8 | ||
|
|
c039e0d62c | ||
|
|
e6e3783ec6 | ||
|
|
5ae19e455d | ||
|
|
f475754a71 | ||
|
|
767f44f94d | ||
|
|
1411aca7b5 | ||
|
|
9ccdcaac24 | ||
|
|
d1223dcdb7 | ||
|
|
59448a4f2c | ||
|
|
5136880532 | ||
|
|
8654cf5507 | ||
|
|
6ca4dc8ffc | ||
|
|
a6f36ba679 | ||
|
|
176e37874e | ||
|
|
3208a04f7a | ||
|
|
0d579263cb | ||
|
|
c022b30110 | ||
|
|
7da4e4a29b | ||
|
|
8bc942a26f | ||
|
|
dff7550038 | ||
|
|
c4edcb8c24 | ||
|
|
4a44d88461 | ||
|
|
efc6bd11d9 | ||
|
|
51429e3155 | ||
|
|
b1a0fa4acf | ||
|
|
aeb2b6fe68 | ||
|
|
6679db98a8 | ||
|
|
5363324bbf | ||
|
|
dc9188dffc | ||
|
|
bd620ccd0d | ||
|
|
1947ae9f22 | ||
|
|
3fcf1b3864 | ||
|
|
d965dd6fd1 | ||
|
|
42dcd41e48 | ||
|
|
68fac7cfe8 | ||
|
|
a9f067e25a | ||
|
|
41b4b1015e | ||
|
|
9523365090 | ||
|
|
aa33fe42a8 | ||
|
|
78a9b93f22 | ||
|
|
a89339e472 | ||
|
|
f3307a8159 | ||
|
|
4bfa25dcb3 | ||
|
|
441a240c33 | ||
|
|
e767892dd5 | ||
|
|
8e0a7dea0f | ||
|
|
c4cc40f5e1 | ||
|
|
a5129199c7 | ||
|
|
c0e462944d | ||
|
|
63614841e8 | ||
|
|
bc4c09c546 | ||
|
|
0d1ab0e75a | ||
|
|
6e39029f91 | ||
|
|
d550966516 | ||
|
|
32d6b3d1ee | ||
|
|
7cb71a5a0a | ||
|
|
6b90a9bfa8 | ||
|
|
83d939bdc0 | ||
|
|
0e1ace78f4 | ||
|
|
6d4db60688 | ||
|
|
3aca01891d | ||
|
|
275ed87c3f | ||
|
|
b385270d7b |
191
.lighthouse/pipeline-clippy.yaml
Normal file
191
.lighthouse/pipeline-clippy.yaml
Normal file
@@ -0,0 +1,191 @@
|
||||
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
|
||||
@@ -137,7 +137,7 @@ spec:
|
||||
value: []
|
||||
- name: docker-image
|
||||
value: "$(params.image-name):$(tasks.fetch-repository.results.commit)"
|
||||
- name: run-image-all
|
||||
- name: run-image-tracing-compare
|
||||
taskRef:
|
||||
name: run-docker-image
|
||||
workspaces:
|
||||
@@ -152,6 +152,94 @@ spec:
|
||||
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)"
|
||||
- name: run-image-wasm
|
||||
taskRef:
|
||||
name: run-docker-image
|
||||
workspaces:
|
||||
- name: source
|
||||
workspace: git-source
|
||||
- name: cargo-cache
|
||||
workspace: cargo-cache
|
||||
runAfter:
|
||||
- run-image-all
|
||||
params:
|
||||
- name: args
|
||||
value:
|
||||
[
|
||||
"--target",
|
||||
"wasm32-unknown-unknown",
|
||||
"--profile",
|
||||
"wasm",
|
||||
"--bin",
|
||||
"wasm",
|
||||
"--no-default-features",
|
||||
"--features",
|
||||
"wasm",
|
||||
]
|
||||
- name: docker-image
|
||||
value: "$(params.image-name):$(tasks.fetch-repository.results.commit)"
|
||||
- name: run-image-wasm-test
|
||||
taskRef:
|
||||
name: run-docker-image
|
||||
workspaces:
|
||||
- name: source
|
||||
workspace: git-source
|
||||
- name: cargo-cache
|
||||
workspace: cargo-cache
|
||||
runAfter:
|
||||
- run-image-wasm
|
||||
params:
|
||||
- name: args
|
||||
value:
|
||||
[
|
||||
"--bin",
|
||||
"wasm_test",
|
||||
"--no-default-features",
|
||||
"--features",
|
||||
"wasm_test",
|
||||
]
|
||||
- name: docker-image
|
||||
value: "$(params.image-name):$(tasks.fetch-repository.results.commit)"
|
||||
finally:
|
||||
- name: report-success
|
||||
when:
|
||||
|
||||
@@ -115,7 +115,7 @@ spec:
|
||||
[
|
||||
--no-default-features,
|
||||
--features,
|
||||
compare,
|
||||
"compare,wasm_test",
|
||||
--no-fail-fast,
|
||||
--lib,
|
||||
--test,
|
||||
|
||||
@@ -127,7 +127,7 @@ spec:
|
||||
- name: command
|
||||
value: ["cargo", "fix"]
|
||||
- name: args
|
||||
value: ["--allow-dirty"]
|
||||
value: ["--all-targets", "--all-features", "--allow-dirty"]
|
||||
- name: docker-image
|
||||
value: "$(params.image-name):$(tasks.fetch-repository.results.commit)"
|
||||
- name: commit-changes
|
||||
|
||||
@@ -30,3 +30,10 @@ spec:
|
||||
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]+$"
|
||||
|
||||
45
Cargo.toml
45
Cargo.toml
@@ -1,6 +1,8 @@
|
||||
# cargo-features = ["profile-rustflags"]
|
||||
|
||||
[package]
|
||||
name = "organic"
|
||||
version = "0.1.9"
|
||||
version = "0.1.14"
|
||||
authors = ["Tom Alexander <tom@fizz.buzz>"]
|
||||
description = "An org-mode parser."
|
||||
edition = "2021"
|
||||
@@ -31,23 +33,50 @@ path = "src/lib.rs"
|
||||
path = "src/bin_compare.rs"
|
||||
required-features = ["compare"]
|
||||
|
||||
[[bin]]
|
||||
# This bin exists for development purposes only. The real target of this crate is the library.
|
||||
name = "foreign_document_test"
|
||||
path = "src/bin_foreign_document_test.rs"
|
||||
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]
|
||||
futures = { version = "0.3.28", optional = true }
|
||||
nom = "7.1.1"
|
||||
opentelemetry = { version = "0.20.0", optional = true, default-features = false, features = ["trace", "rt-tokio"] }
|
||||
opentelemetry-otlp = { version = "0.13.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"] }
|
||||
tracing = { version = "0.1.37", optional = true }
|
||||
tracing-opentelemetry = { version = "0.20.0", optional = true }
|
||||
tracing-subscriber = { version = "0.3.17", optional = true, features = ["env-filter"] }
|
||||
walkdir = { version = "2.3.3", optional = true }
|
||||
wasm-bindgen = { version = "0.2.89", optional = true }
|
||||
|
||||
[build-dependencies]
|
||||
walkdir = "2.3.3"
|
||||
|
||||
[features]
|
||||
default = []
|
||||
compare = []
|
||||
compare = ["tokio/process", "tokio/macros"]
|
||||
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"]
|
||||
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.
|
||||
[profile.release-lto]
|
||||
@@ -55,8 +84,20 @@ inherits = "release"
|
||||
lto = true
|
||||
strip = "symbols"
|
||||
|
||||
# Optimized build for local execution.
|
||||
# [profile.native]
|
||||
# inherits = "release"
|
||||
# lto = true
|
||||
# strip = "symbols"
|
||||
# rustflags = ["-C", "target-cpu=native"]
|
||||
|
||||
# Profile for performance testing with the "perf" tool. Notably keeps debug enabled and does not strip symbols to make reading the perf output easier.
|
||||
[profile.perf]
|
||||
inherits = "release"
|
||||
lto = true
|
||||
debug = true
|
||||
|
||||
[profile.wasm]
|
||||
inherits = "release"
|
||||
lto = true
|
||||
strip = true
|
||||
|
||||
26
Makefile
26
Makefile
@@ -29,6 +29,11 @@ build:
|
||||
release:
|
||||
> cargo build --release $(RELEASEFLAGS)
|
||||
|
||||
.PHONY: wasm
|
||||
wasm:
|
||||
> cargo build --target=wasm32-unknown-unknown --profile wasm --bin wasm --features wasm
|
||||
> wasm-bindgen --target web --out-dir target/wasm32-unknown-unknown/js target/wasm32-unknown-unknown/wasm/wasm.wasm
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
> cargo clean
|
||||
@@ -37,21 +42,42 @@ clean:
|
||||
format:
|
||||
> $(MAKE) -C docker/cargo_fmt run
|
||||
|
||||
.PHONY: dockerclippy
|
||||
dockerclippy:
|
||||
> $(MAKE) -C docker/organic_clippy run
|
||||
|
||||
.PHONY: clippy
|
||||
clippy:
|
||||
> cargo clippy --no-deps --all-targets --all-features -- -D warnings
|
||||
|
||||
.PHONY: test
|
||||
test:
|
||||
> cargo test --no-default-features --features compare --no-fail-fast --lib --test test_loader -- --test-threads $(TESTJOBS)
|
||||
|
||||
.PHONY: doc
|
||||
doc:
|
||||
> cargo doc --no-deps --open --lib --release --all-features
|
||||
|
||||
.PHONY: dockertest
|
||||
dockertest:
|
||||
> $(MAKE) -C docker/organic_test
|
||||
> 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: dockerwasmtest
|
||||
dockerwasmtest:
|
||||
> $(MAKE) -C docker/organic_test
|
||||
> 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: buildtest
|
||||
buildtest:
|
||||
> cargo build --no-default-features
|
||||
> cargo build --no-default-features --features compare
|
||||
> cargo build --no-default-features --features 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,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
|
||||
foreign_document_test:
|
||||
|
||||
@@ -6,14 +6,13 @@ Organic is an emacs-less implementation of an [org-mode](https://orgmode.org/) p
|
||||
|
||||
This project is still under HEAVY development. While the version remains v0.1.x the API will be changing often. Once we hit v0.2.x we will start following semver.
|
||||
|
||||
Currently, the parser is able to correctly identify the start/end bounds of all the org-mode objects and elements (except table.el tables, org-mode tables are supported) but many of the interior properties are not yet populated.
|
||||
Currently, Organic parses most documents the same as the official org-mode parser. Most of the development right now is finding documents where the parsers differ and fixing those issues.
|
||||
|
||||
### 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.
|
||||
- The parser should be fast. We're not doing anything special, but since this is written in Rust and natively compiled we should be able to beat the existing parsers.
|
||||
- The parser should have minimal dependencies. This should reduce effort w.r.t.: security audits, legal compliance, portability.
|
||||
- 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:
|
||||
- It must have a permissive license for use in proprietary code bases.
|
||||
- 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.
|
||||
- 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
|
||||
|
||||
12
build.rs
12
build.rs
@@ -14,7 +14,7 @@ use walkdir::WalkDir;
|
||||
fn main() {
|
||||
let out_dir = env::var("OUT_DIR").unwrap();
|
||||
let destination = Path::new(&out_dir).join("tests.rs");
|
||||
let mut test_file = File::create(&destination).unwrap();
|
||||
let mut test_file = File::create(destination).unwrap();
|
||||
|
||||
// Re-generate the tests if any org-mode files change
|
||||
println!("cargo:rerun-if-changed=org_mode_samples");
|
||||
@@ -51,7 +51,7 @@ fn write_test(test_file: &mut File, test: &walkdir::DirEntry) {
|
||||
.to_lowercase()
|
||||
.strip_suffix(".org")
|
||||
.expect("Should have .org extension")
|
||||
.replace("/", "_");
|
||||
.replace('/', "_");
|
||||
|
||||
write!(
|
||||
test_file,
|
||||
@@ -66,10 +66,6 @@ fn write_test(test_file: &mut File, test: &walkdir::DirEntry) {
|
||||
}
|
||||
|
||||
#[cfg(feature = "compare")]
|
||||
fn is_expect_fail(name: &str) -> Option<&str> {
|
||||
match name {
|
||||
"greater_element_drawer_drawer_with_headline_inside" => Some("Apparently lines with :end: become their own paragraph. This odd behavior needs to be investigated more."),
|
||||
"element_container_priority_footnote_definition_dynamic_block" => Some("Apparently broken begin lines become their own paragraph."),
|
||||
_ => None,
|
||||
}
|
||||
fn is_expect_fail(_name: &str) -> Option<&str> {
|
||||
None
|
||||
}
|
||||
|
||||
@@ -2,5 +2,6 @@ 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
|
||||
RUN rustup target add wasm32-unknown-unknown
|
||||
|
||||
ENTRYPOINT ["cargo", "build"]
|
||||
|
||||
5
docker/organic_clippy/Dockerfile
Normal file
5
docker/organic_clippy/Dockerfile
Normal file
@@ -0,0 +1,5 @@
|
||||
FROM rustlang/rust:nightly-alpine3.17
|
||||
|
||||
RUN apk add --no-cache musl-dev
|
||||
|
||||
ENTRYPOINT ["cargo", "clippy", "--no-deps", "--all-targets", "--all-features", "--", "-D", "warnings"]
|
||||
37
docker/organic_clippy/Makefile
Normal file
37
docker/organic_clippy/Makefile
Normal file
@@ -0,0 +1,37 @@
|
||||
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 -t --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)
|
||||
@@ -14,7 +14,7 @@ RUN make DESTDIR="/root/dist" install
|
||||
|
||||
|
||||
FROM build AS build-org-mode
|
||||
ARG ORG_VERSION=c703541ffcc14965e3567f928de1683a1c1e33f6
|
||||
ARG ORG_VERSION=abf5156096c06ee5aa05795c3dc5a065f76ada97
|
||||
COPY --from=build-emacs /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.
|
||||
@@ -93,6 +93,12 @@ ARG WORG_PATH=/foreign_documents/worg
|
||||
ARG WORG_REPO=https://git.sr.ht/~bzg/worg
|
||||
RUN mkdir -p $WORG_PATH && git -C $WORG_PATH init --initial-branch=main && git -C $WORG_PATH remote add origin $WORG_REPO && git -C $WORG_PATH fetch origin $WORG_VERSION && git -C $WORG_PATH checkout FETCH_HEAD
|
||||
|
||||
ARG LITERATE_BUILD_EMACS_VERSION=e3ac1afe1e40af601be7af12c1d13d96308ab209
|
||||
ARG LITERATE_BUILD_EMACS_PATH=/foreign_documents/literate_build_emacs
|
||||
ARG LITERATE_BUILD_EMACS_REPO=https://gitlab.com/spudlyo/orgdemo2.git
|
||||
RUN mkdir -p $LITERATE_BUILD_EMACS_PATH && git -C $LITERATE_BUILD_EMACS_PATH init --initial-branch=main && git -C $LITERATE_BUILD_EMACS_PATH remote add origin $LITERATE_BUILD_EMACS_REPO && git -C $LITERATE_BUILD_EMACS_PATH fetch origin $LITERATE_BUILD_EMACS_VERSION && git -C $LITERATE_BUILD_EMACS_PATH checkout FETCH_HEAD
|
||||
# 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
|
||||
|
||||
FROM tester as foreign-document-test
|
||||
RUN apk add --no-cache bash coreutils
|
||||
@@ -100,8 +106,7 @@ RUN mkdir /foreign_documents
|
||||
COPY --from=foreign-document-gather /foreign_documents/howardabrams /foreign_documents/howardabrams
|
||||
COPY --from=foreign-document-gather /foreign_documents/doomemacs /foreign_documents/doomemacs
|
||||
COPY --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 --from=build-org-mode /root/org-mode /foreign_documents/org-mode
|
||||
COPY --from=build-emacs /root/emacs /foreign_documents/emacs
|
||||
COPY foreign_document_test_entrypoint.sh /entrypoint.sh
|
||||
RUN chmod +x /entrypoint.sh
|
||||
ENTRYPOINT ["/entrypoint.sh"]
|
||||
ENTRYPOINT ["cargo", "run", "--bin", "foreign_document_test", "--features", "compare,foreign_document_test", "--profile", "release-lto"]
|
||||
|
||||
@@ -1,149 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# Run the Organic compare script against a series of documents sourced from exterior places.
|
||||
set -euo pipefail
|
||||
IFS=$'\n\t'
|
||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
|
||||
REALPATH=$(command -v uu-realpath || command -v realpath)
|
||||
|
||||
function log {
|
||||
(>&2 echo "${@}")
|
||||
}
|
||||
|
||||
function die {
|
||||
local status_code="$1"
|
||||
shift
|
||||
(>&2 echo "${@}")
|
||||
exit "$status_code"
|
||||
}
|
||||
|
||||
function main {
|
||||
cargo build --no-default-features --features compare --profile release-lto
|
||||
if [ "${CARGO_TARGET_DIR:-}" = "" ]; then
|
||||
CARGO_TARGET_DIR=$(realpath target/)
|
||||
fi
|
||||
PARSE="${CARGO_TARGET_DIR}/release-lto/compare"
|
||||
|
||||
local all_status=0
|
||||
set +e
|
||||
|
||||
(run_compare_function "org-mode" compare_all_org_document "/foreign_documents/org-mode")
|
||||
if [ "$?" -ne 0 ]; then all_status=1; fi
|
||||
(run_compare_function "emacs" compare_all_org_document "/foreign_documents/emacs")
|
||||
if [ "$?" -ne 0 ]; then all_status=1; fi
|
||||
(run_compare_function "worg" compare_all_org_document "/foreign_documents/worg")
|
||||
if [ "$?" -ne 0 ]; then all_status=1; fi
|
||||
(run_compare_function "howard_abrams" compare_howard_abrams)
|
||||
if [ "$?" -ne 0 ]; then all_status=1; fi
|
||||
(run_compare_function "doomemacs" compare_all_org_document "/foreign_documents/doomemacs")
|
||||
if [ "$?" -ne 0 ]; then all_status=1; fi
|
||||
|
||||
set -e
|
||||
if [ "$all_status" -ne 0 ]; then
|
||||
red_text "Some tests failed."
|
||||
else
|
||||
green_text "All tests passed."
|
||||
fi
|
||||
return "$all_status"
|
||||
}
|
||||
|
||||
function green_text {
|
||||
(IFS=' '; printf '\x1b[38;2;0;255;0m%s\x1b[0m' "${*}")
|
||||
}
|
||||
|
||||
function red_text {
|
||||
(IFS=' '; printf '\x1b[38;2;255;0;0m%s\x1b[0m' "${*}")
|
||||
}
|
||||
|
||||
function yellow_text {
|
||||
(IFS=' '; printf '\x1b[38;2;255;255;0m%s\x1b[0m' "${*}")
|
||||
}
|
||||
|
||||
function indent {
|
||||
local depth="$1"
|
||||
local scaled_depth=$((depth * 2))
|
||||
shift 1
|
||||
local prefix
|
||||
prefix=$(printf -- "%${scaled_depth}s")
|
||||
while read -r l; do
|
||||
(IFS=' '; printf -- '%s%s\n' "$prefix" "$l")
|
||||
done
|
||||
}
|
||||
|
||||
function run_compare_function {
|
||||
local name="$1"
|
||||
local stdoutput
|
||||
shift 1
|
||||
set +e
|
||||
stdoutput=$("${@}")
|
||||
local status=$?
|
||||
set -e
|
||||
if [ "$status" -eq 0 ]; then
|
||||
echo "$(green_text "GOOD") $name"
|
||||
indent 1 <<<"$stdoutput"
|
||||
else
|
||||
echo "$(red_text "FAIL") $name"
|
||||
indent 1 <<<"$stdoutput"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
function compare_all_org_document {
|
||||
local root_dir="$1"
|
||||
local target_document
|
||||
local all_status=0
|
||||
while read target_document; do
|
||||
local relative_path
|
||||
relative_path=$($REALPATH --relative-to "$root_dir" "$target_document")
|
||||
set +e
|
||||
(run_compare "$relative_path" "$target_document")
|
||||
if [ "$?" -ne 0 ]; then all_status=1; fi
|
||||
set -e
|
||||
done<<<"$(find "$root_dir" -type f -iname '*.org' | sort)"
|
||||
return "$all_status"
|
||||
}
|
||||
|
||||
function run_compare {
|
||||
local name="$1"
|
||||
local target_document="$2"
|
||||
set +e
|
||||
($PARSE "$target_document" &> /dev/null)
|
||||
local status=$?
|
||||
set -e
|
||||
if [ "$status" -eq 0 ]; then
|
||||
echo "$(green_text "GOOD") $name"
|
||||
else
|
||||
echo "$(red_text "FAIL") $name"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
function compare_howard_abrams {
|
||||
local all_status=0
|
||||
set +e
|
||||
|
||||
(run_compare_function "dot-files" compare_all_org_document "/foreign_documents/howardabrams/dot-files")
|
||||
if [ "$?" -ne 0 ]; then all_status=1; fi
|
||||
(run_compare_function "hamacs" compare_all_org_document "/foreign_documents/howardabrams/hamacs")
|
||||
if [ "$?" -ne 0 ]; then all_status=1; fi
|
||||
(run_compare_function "demo-it" compare_all_org_document "/foreign_documents/howardabrams/demo-it")
|
||||
if [ "$?" -ne 0 ]; then all_status=1; fi
|
||||
(run_compare_function "magit-demo" compare_all_org_document "/foreign_documents/howardabrams/magit-demo")
|
||||
if [ "$?" -ne 0 ]; then all_status=1; fi
|
||||
(run_compare_function "pdx-emacs-hackers" compare_all_org_document "/foreign_documents/howardabrams/pdx-emacs-hackers")
|
||||
if [ "$?" -ne 0 ]; then all_status=1; fi
|
||||
(run_compare_function "flora-simulator" compare_all_org_document "/foreign_documents/howardabrams/flora-simulator")
|
||||
if [ "$?" -ne 0 ]; then all_status=1; fi
|
||||
(run_compare_function "literate-devops-demo" compare_all_org_document "/foreign_documents/howardabrams/literate-devops-demo")
|
||||
if [ "$?" -ne 0 ]; then all_status=1; fi
|
||||
(run_compare_function "clojure-yesql-xp" compare_all_org_document "/foreign_documents/howardabrams/clojure-yesql-xp")
|
||||
if [ "$?" -ne 0 ]; then all_status=1; fi
|
||||
(run_compare_function "veep" compare_all_org_document "/foreign_documents/howardabrams/veep")
|
||||
if [ "$?" -ne 0 ]; then all_status=1; fi
|
||||
|
||||
set -e
|
||||
return "$all_status"
|
||||
}
|
||||
|
||||
main "${@}"
|
||||
42
notes/affiliated_keyword_investigation/analysis.org
Normal file
42
notes/affiliated_keyword_investigation/analysis.org
Normal file
@@ -0,0 +1,42 @@
|
||||
* Elisp Structure
|
||||
| Keyword | Single | Double | Single Optval | Double Optval |
|
||||
|---------+---------------+---------------+---------------+---------------|
|
||||
| CAPTION | objtree | objtree | objtree | objtree |
|
||||
| DATA | quoted(:name) | quoted(:name) | - | - |
|
||||
| HEADER | list(quoted) | list(quoted) | - | - |
|
||||
| NAME | quoted(:name) | quoted(:name) | - | - |
|
||||
| PLOT | quoted(:plot) | quoted(:plot) | - | - |
|
||||
| RESULTS | optional pair | optional pair | optional pair | optional pair |
|
||||
* types
|
||||
** objtree
|
||||
Outer list: 1 per keyword
|
||||
next list: first entry = list of objects for value. remaining entries = optval
|
||||
** list(quoted)
|
||||
List of quoted strings, 1 per keyword
|
||||
** quoted(NAME)
|
||||
Quoted string under the NAME property (for example quoted(:name))
|
||||
** optional pair
|
||||
When optval is supplied this is an alist with the field value being the real value and the 3nd value being the optval.
|
||||
#+begin_src elisp
|
||||
("*f*" . "*bar*")
|
||||
#+end_src
|
||||
|
||||
When optval is not supplied this is a list containing a single string of the last occurrence of this keyword.
|
||||
#+begin_src elisp
|
||||
("*c*")
|
||||
#+end_src
|
||||
* Default settings
|
||||
#+begin_src text
|
||||
org-element-dual-keywords ("CAPTION" "RESULTS")
|
||||
org-element-parsed-keywords ("CAPTION")
|
||||
org-element-multiple-keywords ("CAPTION" "HEADER")
|
||||
org-babel-results-keyword "RESULTS"
|
||||
#+end_src
|
||||
* Analysis
|
||||
We don't have an example of a parsed non-dual keyword
|
||||
|
||||
Looks like multiple triggers list 1 per keyword
|
||||
|
||||
dual triggers support for optval
|
||||
|
||||
parsed triggers objects
|
||||
31
notes/affiliated_keyword_investigation/run_test.bash
Executable file
31
notes/affiliated_keyword_investigation/run_test.bash
Executable file
@@ -0,0 +1,31 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
set -euo pipefail
|
||||
IFS=$'\n\t'
|
||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
|
||||
file_path="${DIR}/test_document.org"
|
||||
|
||||
for TARGET_VARIABLE in RESULTS CAPTION HEADER DATA NAME PLOT; do
|
||||
INIT_SCRIPT=$(cat <<EOF
|
||||
(progn
|
||||
(erase-buffer)
|
||||
(require 'org)
|
||||
(defun org-table-align () t)
|
||||
(setq vc-handled-backends nil)
|
||||
(find-file "/input/${file_path}")
|
||||
(org-mode)
|
||||
(replace-regexp-in-region "foo" "${TARGET_VARIABLE}")
|
||||
(message "%s" (pp-to-string (org-element-parse-buffer)))
|
||||
)
|
||||
EOF
|
||||
)
|
||||
docker run --init --rm -i --mount type=tmpfs,destination=/tmp -v "/:/input:ro" -w /input --entrypoint "" organic-test emacs -q --no-site-file --no-splash --batch --eval "$INIT_SCRIPT" 2> "${DIR}/${TARGET_VARIABLE}"
|
||||
done
|
||||
|
||||
# exec docker run --init --rm -i -t --mount type=tmpfs,destination=/tmp -v "/:/input:ro" -w /input --entrypoint "" organic-test emacs -q --no-site-file --no-splash --eval "$INIT_SCRIPT"
|
||||
|
||||
# org-element-dual-keywords ("CAPTION" "RESULTS")
|
||||
# org-element-parsed-keywords ("CAPTION")
|
||||
# org-element-multiple-keywords ("CAPTION" "HEADER")
|
||||
# org-babel-results-keyword "RESULTS"
|
||||
25
notes/affiliated_keyword_investigation/test_document.org
Normal file
25
notes/affiliated_keyword_investigation/test_document.org
Normal file
@@ -0,0 +1,25 @@
|
||||
# Single instance
|
||||
#+foo: *a*
|
||||
#+begin_example
|
||||
|
||||
#+end_example
|
||||
|
||||
# Two instances
|
||||
#+foo: *b*
|
||||
#+foo: *c*
|
||||
#+begin_example
|
||||
|
||||
#+end_example
|
||||
|
||||
# Single with optval
|
||||
#+foo[*bar*]: *d*
|
||||
#+begin_example
|
||||
|
||||
#+end_example
|
||||
|
||||
# Two with optval
|
||||
#+foo[*bar*]: *e*
|
||||
#+foo[*bar*]: *f*
|
||||
#+begin_example
|
||||
|
||||
#+end_example
|
||||
5
org_mode_samples/affiliated_keyword/empty_caption.org
Normal file
5
org_mode_samples/affiliated_keyword/empty_caption.org
Normal file
@@ -0,0 +1,5 @@
|
||||
#+caption:
|
||||
#+caption: *foo*
|
||||
#+caption[bar]:
|
||||
#+begin_src bash
|
||||
#+end_src
|
||||
8
org_mode_samples/affiliated_keyword/optional_value.org
Normal file
8
org_mode_samples/affiliated_keyword/optional_value.org
Normal file
@@ -0,0 +1,8 @@
|
||||
#+CAPTION[foo]: *bar*
|
||||
#+CAPTION[*lorem* ipsum]: dolar
|
||||
1. baz
|
||||
|
||||
|
||||
#+CAPTION[foo]: *bar*
|
||||
#+CAPTION[*lorem* ipsum]: dolar
|
||||
# Comments cannot have affiliated keywords so those become regular keywords.
|
||||
@@ -0,0 +1,3 @@
|
||||
foo
|
||||
:end:
|
||||
bar
|
||||
@@ -0,0 +1,2 @@
|
||||
foo
|
||||
:end:
|
||||
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
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
* Headline
|
||||
before
|
||||
#+NAME: a
|
||||
#+caption: b *lorem* ipsum
|
||||
#+results: c
|
||||
#+headers: d
|
||||
#+header: e
|
||||
#+label: f
|
||||
#+plot: g
|
||||
#+resname: h
|
||||
#+result: i
|
||||
#+source: j
|
||||
#+srcname: k
|
||||
#+tblname: l
|
||||
#+attr_latex: m
|
||||
#+attr_html: n
|
||||
#+NAME: aa
|
||||
#+caption: bb *lorem* ipsum
|
||||
#+results: cc
|
||||
#+headers: dd
|
||||
#+header: ee
|
||||
#+label: ff
|
||||
#+plot: gg
|
||||
#+resname: hh
|
||||
#+result: ii
|
||||
#+source: jj
|
||||
#+srcname: kk
|
||||
#+tblname: ll
|
||||
#+attr_latex: mm
|
||||
#+attr_html: nn
|
||||
:candle:
|
||||
inside
|
||||
|
||||
the drawer
|
||||
:end:
|
||||
|
||||
|
||||
|
||||
|
||||
#+NAME: A
|
||||
#+CAPTION: B *LOREM* IPSUM
|
||||
#+RESULTS: C
|
||||
#+HEADERS: D
|
||||
#+HEADER: E
|
||||
#+LABEL: F
|
||||
#+PLOT: G
|
||||
#+RESNAME: H
|
||||
#+RESULT: I
|
||||
#+SOURCE: J
|
||||
#+SRCNAME: K
|
||||
#+TBLNAME: L
|
||||
#+ATTR_LATEX: M
|
||||
#+ATTR_HTML: N
|
||||
#+NAME: AA
|
||||
#+CAPTION: BB *LOREM* IPSUM
|
||||
#+RESULTS: CC
|
||||
#+HEADERS: DD
|
||||
#+HEADER: EE
|
||||
#+LABEL: FF
|
||||
#+PLOT: GG
|
||||
#+RESNAME: HH
|
||||
#+RESULT: II
|
||||
#+SOURCE: JJ
|
||||
#+SRCNAME: KK
|
||||
#+TBLNAME: LL
|
||||
#+ATTR_LATEX: MM
|
||||
#+ATTR_HTML: NN
|
||||
:candle:
|
||||
inside
|
||||
|
||||
the drawer
|
||||
:end:
|
||||
|
||||
after
|
||||
@@ -1,10 +0,0 @@
|
||||
* Headline
|
||||
before
|
||||
#+NAME: foo
|
||||
:candle:
|
||||
inside
|
||||
|
||||
the drawer
|
||||
:end:
|
||||
|
||||
after
|
||||
@@ -0,0 +1,72 @@
|
||||
#+NAME: a
|
||||
#+caption: b *lorem* ipsum
|
||||
#+results: c
|
||||
#+headers: d
|
||||
#+header: e
|
||||
#+label: f
|
||||
#+plot: g
|
||||
#+resname: h
|
||||
#+result: i
|
||||
#+source: j
|
||||
#+srcname: k
|
||||
#+tblname: l
|
||||
#+attr_latex: m
|
||||
#+attr_html: n
|
||||
#+NAME: aa
|
||||
#+caption: bb *lorem* ipsum
|
||||
#+results: cc
|
||||
#+headers: dd
|
||||
#+header: ee
|
||||
#+label: ff
|
||||
#+plot: gg
|
||||
#+resname: hh
|
||||
#+result: ii
|
||||
#+source: jj
|
||||
#+srcname: kk
|
||||
#+tblname: ll
|
||||
#+attr_latex: mm
|
||||
#+attr_html: nn
|
||||
#+BEGIN: clocktable :scope file :maxlevel 2
|
||||
#+CAPTION: Clock summary at [2023-08-25 Fri 05:34]
|
||||
| Headline | Time |
|
||||
|--------------+--------|
|
||||
| *Total time* | *0:00* |
|
||||
#+END:
|
||||
|
||||
|
||||
|
||||
|
||||
#+NAME: A
|
||||
#+CAPTION: B *LOREM* IPSUM
|
||||
#+RESULTS: C
|
||||
#+HEADERS: D
|
||||
#+HEADER: E
|
||||
#+LABEL: F
|
||||
#+PLOT: G
|
||||
#+RESNAME: H
|
||||
#+RESULT: I
|
||||
#+SOURCE: J
|
||||
#+SRCNAME: K
|
||||
#+TBLNAME: L
|
||||
#+ATTR_LATEX: M
|
||||
#+ATTR_HTML: N
|
||||
#+NAME: AA
|
||||
#+CAPTION: BB *LOREM* IPSUM
|
||||
#+RESULTS: CC
|
||||
#+HEADERS: DD
|
||||
#+HEADER: EE
|
||||
#+LABEL: FF
|
||||
#+PLOT: GG
|
||||
#+RESNAME: HH
|
||||
#+RESULT: II
|
||||
#+SOURCE: JJ
|
||||
#+SRCNAME: KK
|
||||
#+TBLNAME: LL
|
||||
#+ATTR_LATEX: MM
|
||||
#+ATTR_HTML: NN
|
||||
#+BEGIN: clocktable :scope file :maxlevel 2
|
||||
#+CAPTION: Clock summary at [2023-08-25 Fri 05:34]
|
||||
| Headline | Time |
|
||||
|--------------+--------|
|
||||
| *Total time* | *0:00* |
|
||||
#+END:
|
||||
@@ -1,7 +0,0 @@
|
||||
#+NAME: foo
|
||||
#+BEGIN: clocktable :scope file :maxlevel 2
|
||||
#+CAPTION: Clock summary at [2023-08-25 Fri 05:34]
|
||||
| Headline | Time |
|
||||
|--------------+--------|
|
||||
| *Total time* | *0:00* |
|
||||
#+END:
|
||||
@@ -0,0 +1,63 @@
|
||||
#+NAME: a
|
||||
#+caption: b *lorem* ipsum
|
||||
#+results: c
|
||||
#+headers: d
|
||||
#+header: e
|
||||
#+label: f
|
||||
#+plot: g
|
||||
#+resname: h
|
||||
#+result: i
|
||||
#+source: j
|
||||
#+srcname: k
|
||||
#+tblname: l
|
||||
#+attr_latex: m
|
||||
#+attr_html: n
|
||||
#+NAME: aa
|
||||
#+caption: bb *lorem* ipsum
|
||||
#+results: cc
|
||||
#+headers: dd
|
||||
#+header: ee
|
||||
#+label: ff
|
||||
#+plot: gg
|
||||
#+resname: hh
|
||||
#+result: ii
|
||||
#+source: jj
|
||||
#+srcname: kk
|
||||
#+tblname: ll
|
||||
#+attr_latex: mm
|
||||
#+attr_html: nn
|
||||
[fn:1] A footnote.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#+NAME: A
|
||||
#+CAPTION: B *LOREM* IPSUM
|
||||
#+RESULTS: C
|
||||
#+HEADERS: D
|
||||
#+HEADER: E
|
||||
#+LABEL: F
|
||||
#+PLOT: G
|
||||
#+RESNAME: H
|
||||
#+RESULT: I
|
||||
#+SOURCE: J
|
||||
#+SRCNAME: K
|
||||
#+TBLNAME: L
|
||||
#+ATTR_LATEX: M
|
||||
#+ATTR_HTML: N
|
||||
#+NAME: AA
|
||||
#+CAPTION: BB *LOREM* IPSUM
|
||||
#+RESULTS: CC
|
||||
#+HEADERS: DD
|
||||
#+HEADER: EE
|
||||
#+LABEL: FF
|
||||
#+PLOT: GG
|
||||
#+RESNAME: HH
|
||||
#+RESULT: II
|
||||
#+SOURCE: JJ
|
||||
#+SRCNAME: KK
|
||||
#+TBLNAME: LL
|
||||
#+ATTR_LATEX: MM
|
||||
#+ATTR_HTML: NN
|
||||
[fn:1] A footnote.
|
||||
@@ -0,0 +1,67 @@
|
||||
#+NAME: a
|
||||
#+caption: b *lorem* ipsum
|
||||
#+results: c
|
||||
#+headers: d
|
||||
#+header: e
|
||||
#+label: f
|
||||
#+plot: g
|
||||
#+resname: h
|
||||
#+result: i
|
||||
#+source: j
|
||||
#+srcname: k
|
||||
#+tblname: l
|
||||
#+attr_latex: m
|
||||
#+attr_html: n
|
||||
#+NAME: aa
|
||||
#+caption: bb *lorem* ipsum
|
||||
#+results: cc
|
||||
#+headers: dd
|
||||
#+header: ee
|
||||
#+label: ff
|
||||
#+plot: gg
|
||||
#+resname: hh
|
||||
#+result: ii
|
||||
#+source: jj
|
||||
#+srcname: kk
|
||||
#+tblname: ll
|
||||
#+attr_latex: mm
|
||||
#+attr_html: nn
|
||||
#+begin_center
|
||||
|
||||
#+end_center
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#+NAME: A
|
||||
#+CAPTION: B *LOREM* IPSUM
|
||||
#+RESULTS: C
|
||||
#+HEADERS: D
|
||||
#+HEADER: E
|
||||
#+LABEL: F
|
||||
#+PLOT: G
|
||||
#+RESNAME: H
|
||||
#+RESULT: I
|
||||
#+SOURCE: J
|
||||
#+SRCNAME: K
|
||||
#+TBLNAME: L
|
||||
#+ATTR_LATEX: M
|
||||
#+ATTR_HTML: N
|
||||
#+NAME: AA
|
||||
#+CAPTION: BB *LOREM* IPSUM
|
||||
#+RESULTS: CC
|
||||
#+HEADERS: DD
|
||||
#+HEADER: EE
|
||||
#+LABEL: FF
|
||||
#+PLOT: GG
|
||||
#+RESNAME: HH
|
||||
#+RESULT: II
|
||||
#+SOURCE: JJ
|
||||
#+SRCNAME: KK
|
||||
#+TBLNAME: LL
|
||||
#+ATTR_LATEX: MM
|
||||
#+ATTR_HTML: NN
|
||||
#+begin_center
|
||||
|
||||
#+end_center
|
||||
@@ -1,4 +0,0 @@
|
||||
#+NAME: foo
|
||||
#+begin_center
|
||||
|
||||
#+end_center
|
||||
@@ -0,0 +1,67 @@
|
||||
#+NAME: a
|
||||
#+caption: b *lorem* ipsum
|
||||
#+results: c
|
||||
#+headers: d
|
||||
#+header: e
|
||||
#+label: f
|
||||
#+plot: g
|
||||
#+resname: h
|
||||
#+result: i
|
||||
#+source: j
|
||||
#+srcname: k
|
||||
#+tblname: l
|
||||
#+attr_latex: m
|
||||
#+attr_html: n
|
||||
#+NAME: aa
|
||||
#+caption: bb *lorem* ipsum
|
||||
#+results: cc
|
||||
#+headers: dd
|
||||
#+header: ee
|
||||
#+label: ff
|
||||
#+plot: gg
|
||||
#+resname: hh
|
||||
#+result: ii
|
||||
#+source: jj
|
||||
#+srcname: kk
|
||||
#+tblname: ll
|
||||
#+attr_latex: mm
|
||||
#+attr_html: nn
|
||||
#+begin_quote
|
||||
|
||||
#+end_quote
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#+NAME: A
|
||||
#+CAPTION: B *LOREM* IPSUM
|
||||
#+RESULTS: C
|
||||
#+HEADERS: D
|
||||
#+HEADER: E
|
||||
#+LABEL: F
|
||||
#+PLOT: G
|
||||
#+RESNAME: H
|
||||
#+RESULT: I
|
||||
#+SOURCE: J
|
||||
#+SRCNAME: K
|
||||
#+TBLNAME: L
|
||||
#+ATTR_LATEX: M
|
||||
#+ATTR_HTML: N
|
||||
#+NAME: AA
|
||||
#+CAPTION: BB *LOREM* IPSUM
|
||||
#+RESULTS: CC
|
||||
#+HEADERS: DD
|
||||
#+HEADER: EE
|
||||
#+LABEL: FF
|
||||
#+PLOT: GG
|
||||
#+RESNAME: HH
|
||||
#+RESULT: II
|
||||
#+SOURCE: JJ
|
||||
#+SRCNAME: KK
|
||||
#+TBLNAME: LL
|
||||
#+ATTR_LATEX: MM
|
||||
#+ATTR_HTML: NN
|
||||
#+begin_quote
|
||||
|
||||
#+end_quote
|
||||
@@ -1,4 +0,0 @@
|
||||
#+NAME: foo
|
||||
#+begin_quote
|
||||
|
||||
#+end_quote
|
||||
@@ -0,0 +1,71 @@
|
||||
#+NAME: a
|
||||
#+caption: b *lorem* ipsum
|
||||
#+results: c
|
||||
#+headers: d
|
||||
#+header: e
|
||||
#+label: f
|
||||
#+plot: g
|
||||
#+resname: h
|
||||
#+result: i
|
||||
#+source: j
|
||||
#+srcname: k
|
||||
#+tblname: l
|
||||
#+attr_latex: m
|
||||
#+attr_html: n
|
||||
#+NAME: aa
|
||||
#+caption: bb *lorem* ipsum
|
||||
#+results: cc
|
||||
#+headers: dd
|
||||
#+header: ee
|
||||
#+label: ff
|
||||
#+plot: gg
|
||||
#+resname: hh
|
||||
#+result: ii
|
||||
#+source: jj
|
||||
#+srcname: kk
|
||||
#+tblname: ll
|
||||
#+attr_latex: mm
|
||||
#+attr_html: nn
|
||||
#+begin_defun
|
||||
foo
|
||||
|
||||
{{{bar(baz)}}}
|
||||
#+end_defun
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#+NAME: A
|
||||
#+CAPTION: B *LOREM* IPSUM
|
||||
#+RESULTS: C
|
||||
#+HEADERS: D
|
||||
#+HEADER: E
|
||||
#+LABEL: F
|
||||
#+PLOT: G
|
||||
#+RESNAME: H
|
||||
#+RESULT: I
|
||||
#+SOURCE: J
|
||||
#+SRCNAME: K
|
||||
#+TBLNAME: L
|
||||
#+ATTR_LATEX: M
|
||||
#+ATTR_HTML: N
|
||||
#+NAME: AA
|
||||
#+CAPTION: BB *LOREM* IPSUM
|
||||
#+RESULTS: CC
|
||||
#+HEADERS: DD
|
||||
#+HEADER: EE
|
||||
#+LABEL: FF
|
||||
#+PLOT: GG
|
||||
#+RESNAME: HH
|
||||
#+RESULT: II
|
||||
#+SOURCE: JJ
|
||||
#+SRCNAME: KK
|
||||
#+TBLNAME: LL
|
||||
#+ATTR_LATEX: MM
|
||||
#+ATTR_HTML: NN
|
||||
#+begin_defun
|
||||
foo
|
||||
|
||||
{{{bar(baz)}}}
|
||||
#+end_defun
|
||||
@@ -1,6 +0,0 @@
|
||||
#+NAME: foo
|
||||
#+begin_defun
|
||||
foo
|
||||
|
||||
{{{bar(baz)}}}
|
||||
#+end_defun
|
||||
@@ -0,0 +1,63 @@
|
||||
#+NAME: a
|
||||
#+caption: b *lorem* ipsum
|
||||
#+results: c
|
||||
#+headers: d
|
||||
#+header: e
|
||||
#+label: f
|
||||
#+plot: g
|
||||
#+resname: h
|
||||
#+result: i
|
||||
#+source: j
|
||||
#+srcname: k
|
||||
#+tblname: l
|
||||
#+attr_latex: m
|
||||
#+attr_html: n
|
||||
#+NAME: aa
|
||||
#+caption: bb *lorem* ipsum
|
||||
#+results: cc
|
||||
#+headers: dd
|
||||
#+header: ee
|
||||
#+label: ff
|
||||
#+plot: gg
|
||||
#+resname: hh
|
||||
#+result: ii
|
||||
#+source: jj
|
||||
#+srcname: kk
|
||||
#+tblname: ll
|
||||
#+attr_latex: mm
|
||||
#+attr_html: nn
|
||||
1. bar
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#+NAME: A
|
||||
#+CAPTION: B *LOREM* IPSUM
|
||||
#+RESULTS: C
|
||||
#+HEADERS: D
|
||||
#+HEADER: E
|
||||
#+LABEL: F
|
||||
#+PLOT: G
|
||||
#+RESNAME: H
|
||||
#+RESULT: I
|
||||
#+SOURCE: J
|
||||
#+SRCNAME: K
|
||||
#+TBLNAME: L
|
||||
#+ATTR_LATEX: M
|
||||
#+ATTR_HTML: N
|
||||
#+NAME: AA
|
||||
#+CAPTION: BB *LOREM* IPSUM
|
||||
#+RESULTS: CC
|
||||
#+HEADERS: DD
|
||||
#+HEADER: EE
|
||||
#+LABEL: FF
|
||||
#+PLOT: GG
|
||||
#+RESNAME: HH
|
||||
#+RESULT: II
|
||||
#+SOURCE: JJ
|
||||
#+SRCNAME: KK
|
||||
#+TBLNAME: LL
|
||||
#+ATTR_LATEX: MM
|
||||
#+ATTR_HTML: NN
|
||||
1. BAR
|
||||
@@ -0,0 +1,3 @@
|
||||
1. foo
|
||||
#+NAME: bar
|
||||
2. baz
|
||||
@@ -1,2 +0,0 @@
|
||||
#+NAME: foo
|
||||
1. bar
|
||||
@@ -1,3 +1,32 @@
|
||||
* Empty
|
||||
:PROPERTIES:
|
||||
:END:
|
||||
* Single new line
|
||||
: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:
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
* baz
|
||||
# lorem
|
||||
:PROPERTIES:
|
||||
:FOO: bar
|
||||
:END:
|
||||
@@ -0,0 +1,6 @@
|
||||
* baz
|
||||
# lorem
|
||||
|
||||
:PROPERTIES:
|
||||
:FOO: bar
|
||||
:END:
|
||||
@@ -0,0 +1,4 @@
|
||||
* baz
|
||||
:PROPERTIES:
|
||||
:FOO: bar
|
||||
:END:
|
||||
@@ -0,0 +1,7 @@
|
||||
** Foo
|
||||
DEADLINE: <2023-10-16 Mon>
|
||||
:PROPERTIES:
|
||||
:foo: *a*
|
||||
:Bar: *b*
|
||||
:BAZ: *c*
|
||||
:END:
|
||||
@@ -0,0 +1,5 @@
|
||||
* baz
|
||||
|
||||
:PROPERTIES:
|
||||
:FOO: bar
|
||||
:END:
|
||||
@@ -0,0 +1,13 @@
|
||||
* baz
|
||||
|
||||
|
||||
|
||||
|
||||
# lorem
|
||||
|
||||
|
||||
|
||||
|
||||
:PROPERTIES:
|
||||
:FOO: bar
|
||||
:END:
|
||||
@@ -0,0 +1,19 @@
|
||||
:PROPERTIES:
|
||||
:foo: bar
|
||||
:foo+: baz
|
||||
:cat: dog
|
||||
:END:
|
||||
|
||||
# Even though these are inheriting the properties and overwriting and/or appending to them, this is not represented in the parser AST so Organic does not do any special handling of this.
|
||||
|
||||
* Overwrite
|
||||
:PROPERTIES:
|
||||
:foo: lorem
|
||||
:bat: car
|
||||
:END:
|
||||
|
||||
* Append
|
||||
:PROPERTIES:
|
||||
:foo+: ipsum
|
||||
:cake: lie
|
||||
:END:
|
||||
@@ -0,0 +1,5 @@
|
||||
* Overwrite
|
||||
#+NAME: foo
|
||||
:PROPERTIES:
|
||||
:header-args: :var foo="lorem"
|
||||
:END:
|
||||
@@ -1,25 +0,0 @@
|
||||
|
||||
|
||||
|
||||
|
||||
# Blank lines and comments can come before property drawers in the zeroth section
|
||||
:PROPERTIES:
|
||||
:FOO: bar
|
||||
:END:
|
||||
|
||||
|
||||
|
||||
* Spaces turn property drawers into regular drawers
|
||||
|
||||
:PROPERTIES:
|
||||
:FOO: bar
|
||||
:END:
|
||||
* Comments turn property drawers into regular drawers
|
||||
# Comment
|
||||
:PROPERTIES:
|
||||
:FOO: bar
|
||||
:END:
|
||||
* Baseline
|
||||
:PROPERTIES:
|
||||
:FOO: bar
|
||||
:END:
|
||||
@@ -0,0 +1,4 @@
|
||||
# lorem
|
||||
:PROPERTIES:
|
||||
:FOO: bar
|
||||
:END:
|
||||
@@ -0,0 +1,5 @@
|
||||
# lorem
|
||||
|
||||
:PROPERTIES:
|
||||
:FOO: bar
|
||||
:END:
|
||||
@@ -0,0 +1,3 @@
|
||||
:PROPERTIES:
|
||||
:FOO: bar
|
||||
:END:
|
||||
@@ -0,0 +1,4 @@
|
||||
|
||||
:PROPERTIES:
|
||||
:FOO: bar
|
||||
:END:
|
||||
@@ -0,0 +1,12 @@
|
||||
|
||||
|
||||
|
||||
|
||||
# lorem
|
||||
|
||||
|
||||
|
||||
|
||||
:PROPERTIES:
|
||||
:FOO: bar
|
||||
:END:
|
||||
@@ -1,12 +0,0 @@
|
||||
|
||||
|
||||
|
||||
|
||||
# Blank lines and comments can come before property drawers in the zeroth section
|
||||
|
||||
|
||||
|
||||
|
||||
:PROPERTIES:
|
||||
:FOO: bar
|
||||
:END:
|
||||
@@ -0,0 +1,63 @@
|
||||
#+NAME: a
|
||||
#+caption: b *lorem* ipsum
|
||||
#+results: c
|
||||
#+headers: d
|
||||
#+header: e
|
||||
#+label: f
|
||||
#+plot: g
|
||||
#+resname: h
|
||||
#+result: i
|
||||
#+source: j
|
||||
#+srcname: k
|
||||
#+tblname: l
|
||||
#+attr_latex: m
|
||||
#+attr_html: n
|
||||
#+NAME: aa
|
||||
#+caption: bb *lorem* ipsum
|
||||
#+results: cc
|
||||
#+headers: dd
|
||||
#+header: ee
|
||||
#+label: ff
|
||||
#+plot: gg
|
||||
#+resname: hh
|
||||
#+result: ii
|
||||
#+source: jj
|
||||
#+srcname: kk
|
||||
#+tblname: ll
|
||||
#+attr_latex: mm
|
||||
#+attr_html: nn
|
||||
| foo | bar |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#+NAME: A
|
||||
#+CAPTION: B *LOREM* IPSUM
|
||||
#+RESULTS: C
|
||||
#+HEADERS: D
|
||||
#+HEADER: E
|
||||
#+LABEL: F
|
||||
#+PLOT: G
|
||||
#+RESNAME: H
|
||||
#+RESULT: I
|
||||
#+SOURCE: J
|
||||
#+SRCNAME: K
|
||||
#+TBLNAME: L
|
||||
#+ATTR_LATEX: M
|
||||
#+ATTR_HTML: N
|
||||
#+NAME: AA
|
||||
#+CAPTION: BB *LOREM* IPSUM
|
||||
#+RESULTS: CC
|
||||
#+HEADERS: DD
|
||||
#+HEADER: EE
|
||||
#+LABEL: FF
|
||||
#+PLOT: GG
|
||||
#+RESNAME: HH
|
||||
#+RESULT: II
|
||||
#+SOURCE: JJ
|
||||
#+SRCNAME: KK
|
||||
#+TBLNAME: LL
|
||||
#+ATTR_LATEX: MM
|
||||
#+ATTR_HTML: NN
|
||||
| foo | bar |
|
||||
@@ -1,2 +0,0 @@
|
||||
#+NAME: foo
|
||||
| foo | bar |
|
||||
3
org_mode_samples/greater_element/table/row/name.org
Normal file
3
org_mode_samples/greater_element/table/row/name.org
Normal file
@@ -0,0 +1,3 @@
|
||||
|foo|
|
||||
#+NAME: bar
|
||||
|baz |
|
||||
@@ -0,0 +1,63 @@
|
||||
#+NAME: a
|
||||
#+caption: b *lorem* ipsum
|
||||
#+results: c
|
||||
#+headers: d
|
||||
#+header: e
|
||||
#+label: f
|
||||
#+plot: g
|
||||
#+resname: h
|
||||
#+result: i
|
||||
#+source: j
|
||||
#+srcname: k
|
||||
#+tblname: l
|
||||
#+attr_latex: m
|
||||
#+attr_html: n
|
||||
#+NAME: aa
|
||||
#+caption: bb *lorem* ipsum
|
||||
#+results: cc
|
||||
#+headers: dd
|
||||
#+header: ee
|
||||
#+label: ff
|
||||
#+plot: gg
|
||||
#+resname: hh
|
||||
#+result: ii
|
||||
#+source: jj
|
||||
#+srcname: kk
|
||||
#+tblname: ll
|
||||
#+attr_latex: mm
|
||||
#+attr_html: nn
|
||||
#+call: foo(bar="baz")
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#+NAME: A
|
||||
#+CAPTION: B *LOREM* IPSUM
|
||||
#+RESULTS: C
|
||||
#+HEADERS: D
|
||||
#+HEADER: E
|
||||
#+LABEL: F
|
||||
#+PLOT: G
|
||||
#+RESNAME: H
|
||||
#+RESULT: I
|
||||
#+SOURCE: J
|
||||
#+SRCNAME: K
|
||||
#+TBLNAME: L
|
||||
#+ATTR_LATEX: M
|
||||
#+ATTR_HTML: N
|
||||
#+NAME: AA
|
||||
#+CAPTION: BB *LOREM* IPSUM
|
||||
#+RESULTS: CC
|
||||
#+HEADERS: DD
|
||||
#+HEADER: EE
|
||||
#+LABEL: FF
|
||||
#+PLOT: GG
|
||||
#+RESNAME: HH
|
||||
#+RESULT: II
|
||||
#+SOURCE: JJ
|
||||
#+SRCNAME: KK
|
||||
#+TBLNAME: LL
|
||||
#+ATTR_LATEX: MM
|
||||
#+ATTR_HTML: NN
|
||||
#+call: foo(bar="baz")
|
||||
@@ -1,2 +0,0 @@
|
||||
#+NAME: foo
|
||||
#+call: foo(bar="baz")
|
||||
@@ -5,3 +5,5 @@
|
||||
#+call: dolar cat(dog)
|
||||
|
||||
#+call: (bat)
|
||||
|
||||
#+call:
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
#+NAME: a
|
||||
#+caption: b *lorem* ipsum
|
||||
#+results: c
|
||||
#+headers: d
|
||||
#+header: e
|
||||
#+label: f
|
||||
#+plot: g
|
||||
#+resname: h
|
||||
#+result: i
|
||||
#+source: j
|
||||
#+srcname: k
|
||||
#+tblname: l
|
||||
#+attr_latex: m
|
||||
#+attr_html: n
|
||||
#+NAME: aa
|
||||
#+caption: bb *lorem* ipsum
|
||||
#+results: cc
|
||||
#+headers: dd
|
||||
#+header: ee
|
||||
#+label: ff
|
||||
#+plot: gg
|
||||
#+resname: hh
|
||||
#+result: ii
|
||||
#+source: jj
|
||||
#+srcname: kk
|
||||
#+tblname: ll
|
||||
#+attr_latex: mm
|
||||
#+attr_html: nn
|
||||
%%(foo)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#+NAME: A
|
||||
#+CAPTION: B *LOREM* IPSUM
|
||||
#+RESULTS: C
|
||||
#+HEADERS: D
|
||||
#+HEADER: E
|
||||
#+LABEL: F
|
||||
#+PLOT: G
|
||||
#+RESNAME: H
|
||||
#+RESULT: I
|
||||
#+SOURCE: J
|
||||
#+SRCNAME: K
|
||||
#+TBLNAME: L
|
||||
#+ATTR_LATEX: M
|
||||
#+ATTR_HTML: N
|
||||
#+NAME: AA
|
||||
#+CAPTION: BB *LOREM* IPSUM
|
||||
#+RESULTS: CC
|
||||
#+HEADERS: DD
|
||||
#+HEADER: EE
|
||||
#+LABEL: FF
|
||||
#+PLOT: GG
|
||||
#+RESNAME: HH
|
||||
#+RESULT: II
|
||||
#+SOURCE: JJ
|
||||
#+SRCNAME: KK
|
||||
#+TBLNAME: LL
|
||||
#+ATTR_LATEX: MM
|
||||
#+ATTR_HTML: NN
|
||||
%%(foo)
|
||||
@@ -1,2 +0,0 @@
|
||||
#+NAME: foo
|
||||
%%(foo)
|
||||
@@ -0,0 +1,63 @@
|
||||
#+NAME: a
|
||||
#+caption: b *lorem* ipsum
|
||||
#+results: c
|
||||
#+headers: d
|
||||
#+header: e
|
||||
#+label: f
|
||||
#+plot: g
|
||||
#+resname: h
|
||||
#+result: i
|
||||
#+source: j
|
||||
#+srcname: k
|
||||
#+tblname: l
|
||||
#+attr_latex: m
|
||||
#+attr_html: n
|
||||
#+NAME: aa
|
||||
#+caption: bb *lorem* ipsum
|
||||
#+results: cc
|
||||
#+headers: dd
|
||||
#+header: ee
|
||||
#+label: ff
|
||||
#+plot: gg
|
||||
#+resname: hh
|
||||
#+result: ii
|
||||
#+source: jj
|
||||
#+srcname: kk
|
||||
#+tblname: ll
|
||||
#+attr_latex: mm
|
||||
#+attr_html: nn
|
||||
: bar
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#+NAME: A
|
||||
#+CAPTION: B *LOREM* IPSUM
|
||||
#+RESULTS: C
|
||||
#+HEADERS: D
|
||||
#+HEADER: E
|
||||
#+LABEL: F
|
||||
#+PLOT: G
|
||||
#+RESNAME: H
|
||||
#+RESULT: I
|
||||
#+SOURCE: J
|
||||
#+SRCNAME: K
|
||||
#+TBLNAME: L
|
||||
#+ATTR_LATEX: M
|
||||
#+ATTR_HTML: N
|
||||
#+NAME: AA
|
||||
#+CAPTION: BB *LOREM* IPSUM
|
||||
#+RESULTS: CC
|
||||
#+HEADERS: DD
|
||||
#+HEADER: EE
|
||||
#+LABEL: FF
|
||||
#+PLOT: GG
|
||||
#+RESNAME: HH
|
||||
#+RESULT: II
|
||||
#+SOURCE: JJ
|
||||
#+SRCNAME: KK
|
||||
#+TBLNAME: LL
|
||||
#+ATTR_LATEX: MM
|
||||
#+ATTR_HTML: NN
|
||||
: bar
|
||||
@@ -0,0 +1,3 @@
|
||||
: foo
|
||||
:
|
||||
: bar
|
||||
@@ -0,0 +1,6 @@
|
||||
1. foo
|
||||
#+begin_src text
|
||||
|
||||
#+end_src
|
||||
|
||||
2. baz
|
||||
@@ -1,2 +0,0 @@
|
||||
#+NAME: foo
|
||||
: bar
|
||||
@@ -0,0 +1,63 @@
|
||||
#+NAME: a
|
||||
#+caption: b *lorem* ipsum
|
||||
#+results: c
|
||||
#+headers: d
|
||||
#+header: e
|
||||
#+label: f
|
||||
#+plot: g
|
||||
#+resname: h
|
||||
#+result: i
|
||||
#+source: j
|
||||
#+srcname: k
|
||||
#+tblname: l
|
||||
#+attr_latex: m
|
||||
#+attr_html: n
|
||||
#+NAME: aa
|
||||
#+caption: bb *lorem* ipsum
|
||||
#+results: cc
|
||||
#+headers: dd
|
||||
#+header: ee
|
||||
#+label: ff
|
||||
#+plot: gg
|
||||
#+resname: hh
|
||||
#+result: ii
|
||||
#+source: jj
|
||||
#+srcname: kk
|
||||
#+tblname: ll
|
||||
#+attr_latex: mm
|
||||
#+attr_html: nn
|
||||
-----
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#+NAME: A
|
||||
#+CAPTION: B *LOREM* IPSUM
|
||||
#+RESULTS: C
|
||||
#+HEADERS: D
|
||||
#+HEADER: E
|
||||
#+LABEL: F
|
||||
#+PLOT: G
|
||||
#+RESNAME: H
|
||||
#+RESULT: I
|
||||
#+SOURCE: J
|
||||
#+SRCNAME: K
|
||||
#+TBLNAME: L
|
||||
#+ATTR_LATEX: M
|
||||
#+ATTR_HTML: N
|
||||
#+NAME: AA
|
||||
#+CAPTION: BB *LOREM* IPSUM
|
||||
#+RESULTS: CC
|
||||
#+HEADERS: DD
|
||||
#+HEADER: EE
|
||||
#+LABEL: FF
|
||||
#+PLOT: GG
|
||||
#+RESNAME: HH
|
||||
#+RESULT: II
|
||||
#+SOURCE: JJ
|
||||
#+SRCNAME: KK
|
||||
#+TBLNAME: LL
|
||||
#+ATTR_LATEX: MM
|
||||
#+ATTR_HTML: NN
|
||||
-----
|
||||
@@ -1,2 +0,0 @@
|
||||
#+NAME: foo
|
||||
-----
|
||||
@@ -1,8 +1,63 @@
|
||||
#+name: foo
|
||||
#+caption: bar
|
||||
#+caption: baz
|
||||
[[file:lorem/ipsum.png]]
|
||||
#+NAME: a
|
||||
#+caption: b *lorem* ipsum
|
||||
#+results: c
|
||||
#+headers: d
|
||||
#+header: e
|
||||
#+label: f
|
||||
#+plot: g
|
||||
#+resname: h
|
||||
#+result: i
|
||||
#+source: j
|
||||
#+srcname: k
|
||||
#+tblname: l
|
||||
#+attr_latex: m
|
||||
#+attr_html: n
|
||||
#+NAME: aa
|
||||
#+caption: bb *lorem* ipsum
|
||||
#+results: cc
|
||||
#+headers: dd
|
||||
#+header: ee
|
||||
#+label: ff
|
||||
#+plot: gg
|
||||
#+resname: hh
|
||||
#+result: ii
|
||||
#+source: jj
|
||||
#+srcname: kk
|
||||
#+tblname: ll
|
||||
#+attr_latex: mm
|
||||
#+attr_html: nn
|
||||
#+foo: bar
|
||||
|
||||
#+name: cat
|
||||
#+caption: dog
|
||||
[[file:lorem/ipsum.png]]
|
||||
|
||||
|
||||
|
||||
|
||||
#+NAME: A
|
||||
#+CAPTION: B *LOREM* IPSUM
|
||||
#+RESULTS: C
|
||||
#+HEADERS: D
|
||||
#+HEADER: E
|
||||
#+LABEL: F
|
||||
#+PLOT: G
|
||||
#+RESNAME: H
|
||||
#+RESULT: I
|
||||
#+SOURCE: J
|
||||
#+SRCNAME: K
|
||||
#+TBLNAME: L
|
||||
#+ATTR_LATEX: M
|
||||
#+ATTR_HTML: N
|
||||
#+NAME: AA
|
||||
#+CAPTION: BB *LOREM* IPSUM
|
||||
#+RESULTS: CC
|
||||
#+HEADERS: DD
|
||||
#+HEADER: EE
|
||||
#+LABEL: FF
|
||||
#+PLOT: GG
|
||||
#+RESNAME: HH
|
||||
#+RESULT: II
|
||||
#+SOURCE: JJ
|
||||
#+SRCNAME: KK
|
||||
#+TBLNAME: LL
|
||||
#+ATTR_LATEX: MM
|
||||
#+ATTR_HTML: NN
|
||||
#+foo: bar
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
# This test is to prove that the parser works with affiliated keywords that have both a shorter and longer version.
|
||||
|
||||
#+results:
|
||||
#+result:
|
||||
#+begin_latex
|
||||
\foo
|
||||
#+end_latex
|
||||
@@ -1,2 +0,0 @@
|
||||
#+NAME: foo
|
||||
#+FOO: BAR
|
||||
@@ -0,0 +1,67 @@
|
||||
#+NAME: a
|
||||
#+caption: b *lorem* ipsum
|
||||
#+results: c
|
||||
#+headers: d
|
||||
#+header: e
|
||||
#+label: f
|
||||
#+plot: g
|
||||
#+resname: h
|
||||
#+result: i
|
||||
#+source: j
|
||||
#+srcname: k
|
||||
#+tblname: l
|
||||
#+attr_latex: m
|
||||
#+attr_html: n
|
||||
#+NAME: aa
|
||||
#+caption: bb *lorem* ipsum
|
||||
#+results: cc
|
||||
#+headers: dd
|
||||
#+header: ee
|
||||
#+label: ff
|
||||
#+plot: gg
|
||||
#+resname: hh
|
||||
#+result: ii
|
||||
#+source: jj
|
||||
#+srcname: kk
|
||||
#+tblname: ll
|
||||
#+attr_latex: mm
|
||||
#+attr_html: nn
|
||||
\begin{foo}
|
||||
bar
|
||||
\end{foo}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#+NAME: A
|
||||
#+CAPTION: B *LOREM* IPSUM
|
||||
#+RESULTS: C
|
||||
#+HEADERS: D
|
||||
#+HEADER: E
|
||||
#+LABEL: F
|
||||
#+PLOT: G
|
||||
#+RESNAME: H
|
||||
#+RESULT: I
|
||||
#+SOURCE: J
|
||||
#+SRCNAME: K
|
||||
#+TBLNAME: L
|
||||
#+ATTR_LATEX: M
|
||||
#+ATTR_HTML: N
|
||||
#+NAME: AA
|
||||
#+CAPTION: BB *LOREM* IPSUM
|
||||
#+RESULTS: CC
|
||||
#+HEADERS: DD
|
||||
#+HEADER: EE
|
||||
#+LABEL: FF
|
||||
#+PLOT: GG
|
||||
#+RESNAME: HH
|
||||
#+RESULT: II
|
||||
#+SOURCE: JJ
|
||||
#+SRCNAME: KK
|
||||
#+TBLNAME: LL
|
||||
#+ATTR_LATEX: MM
|
||||
#+ATTR_HTML: NN
|
||||
\begin{foo}
|
||||
bar
|
||||
\end{foo}
|
||||
@@ -1,4 +0,0 @@
|
||||
#+NAME: foo
|
||||
\begin{foo}
|
||||
bar
|
||||
\end{foo}
|
||||
@@ -0,0 +1,67 @@
|
||||
#+NAME: a
|
||||
#+caption: b *lorem* ipsum
|
||||
#+results: c
|
||||
#+headers: d
|
||||
#+header: e
|
||||
#+label: f
|
||||
#+plot: g
|
||||
#+resname: h
|
||||
#+result: i
|
||||
#+source: j
|
||||
#+srcname: k
|
||||
#+tblname: l
|
||||
#+attr_latex: m
|
||||
#+attr_html: n
|
||||
#+NAME: aa
|
||||
#+caption: bb *lorem* ipsum
|
||||
#+results: cc
|
||||
#+headers: dd
|
||||
#+header: ee
|
||||
#+label: ff
|
||||
#+plot: gg
|
||||
#+resname: hh
|
||||
#+result: ii
|
||||
#+source: jj
|
||||
#+srcname: kk
|
||||
#+tblname: ll
|
||||
#+attr_latex: mm
|
||||
#+attr_html: nn
|
||||
#+begin_comment text
|
||||
bar
|
||||
#+end_comment
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#+NAME: A
|
||||
#+CAPTION: B *LOREM* IPSUM
|
||||
#+RESULTS: C
|
||||
#+HEADERS: D
|
||||
#+HEADER: E
|
||||
#+LABEL: F
|
||||
#+PLOT: G
|
||||
#+RESNAME: H
|
||||
#+RESULT: I
|
||||
#+SOURCE: J
|
||||
#+SRCNAME: K
|
||||
#+TBLNAME: L
|
||||
#+ATTR_LATEX: M
|
||||
#+ATTR_HTML: N
|
||||
#+NAME: AA
|
||||
#+CAPTION: BB *LOREM* IPSUM
|
||||
#+RESULTS: CC
|
||||
#+HEADERS: DD
|
||||
#+HEADER: EE
|
||||
#+LABEL: FF
|
||||
#+PLOT: GG
|
||||
#+RESNAME: HH
|
||||
#+RESULT: II
|
||||
#+SOURCE: JJ
|
||||
#+SRCNAME: KK
|
||||
#+TBLNAME: LL
|
||||
#+ATTR_LATEX: MM
|
||||
#+ATTR_HTML: NN
|
||||
#+begin_comment text
|
||||
bar
|
||||
#+end_comment
|
||||
@@ -1,4 +0,0 @@
|
||||
#+NAME: foo
|
||||
#+begin_comment text
|
||||
bar
|
||||
#+end_comment
|
||||
@@ -0,0 +1,67 @@
|
||||
#+NAME: a
|
||||
#+caption: b *lorem* ipsum
|
||||
#+results: c
|
||||
#+headers: d
|
||||
#+header: e
|
||||
#+label: f
|
||||
#+plot: g
|
||||
#+resname: h
|
||||
#+result: i
|
||||
#+source: j
|
||||
#+srcname: k
|
||||
#+tblname: l
|
||||
#+attr_latex: m
|
||||
#+attr_html: n
|
||||
#+NAME: aa
|
||||
#+caption: bb *lorem* ipsum
|
||||
#+results: cc
|
||||
#+headers: dd
|
||||
#+header: ee
|
||||
#+label: ff
|
||||
#+plot: gg
|
||||
#+resname: hh
|
||||
#+result: ii
|
||||
#+source: jj
|
||||
#+srcname: kk
|
||||
#+tblname: ll
|
||||
#+attr_latex: mm
|
||||
#+attr_html: nn
|
||||
#+begin_example text
|
||||
bar
|
||||
#+end_example
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#+NAME: A
|
||||
#+CAPTION: B *LOREM* IPSUM
|
||||
#+RESULTS: C
|
||||
#+HEADERS: D
|
||||
#+HEADER: E
|
||||
#+LABEL: F
|
||||
#+PLOT: G
|
||||
#+RESNAME: H
|
||||
#+RESULT: I
|
||||
#+SOURCE: J
|
||||
#+SRCNAME: K
|
||||
#+TBLNAME: L
|
||||
#+ATTR_LATEX: M
|
||||
#+ATTR_HTML: N
|
||||
#+NAME: AA
|
||||
#+CAPTION: BB *LOREM* IPSUM
|
||||
#+RESULTS: CC
|
||||
#+HEADERS: DD
|
||||
#+HEADER: EE
|
||||
#+LABEL: FF
|
||||
#+PLOT: GG
|
||||
#+RESNAME: HH
|
||||
#+RESULT: II
|
||||
#+SOURCE: JJ
|
||||
#+SRCNAME: KK
|
||||
#+TBLNAME: LL
|
||||
#+ATTR_LATEX: MM
|
||||
#+ATTR_HTML: NN
|
||||
#+begin_example text
|
||||
bar
|
||||
#+end_example
|
||||
@@ -0,0 +1,16 @@
|
||||
#+results[foo]: bar
|
||||
#+results[lorem]: ipsum
|
||||
#+begin_example
|
||||
baz
|
||||
#+end_example
|
||||
|
||||
#+caption[lorem]: ipsum
|
||||
#+caption[foo]: bar
|
||||
#+begin_example
|
||||
baz
|
||||
#+end_example
|
||||
|
||||
#+header[foo]: bar
|
||||
#+begin_example
|
||||
baz
|
||||
#+end_example
|
||||
@@ -1,4 +0,0 @@
|
||||
#+NAME: foo
|
||||
#+begin_example text
|
||||
bar
|
||||
#+end_example
|
||||
@@ -0,0 +1,67 @@
|
||||
#+NAME: a
|
||||
#+caption: b *lorem* ipsum
|
||||
#+results: c
|
||||
#+headers: d
|
||||
#+header: e
|
||||
#+label: f
|
||||
#+plot: g
|
||||
#+resname: h
|
||||
#+result: i
|
||||
#+source: j
|
||||
#+srcname: k
|
||||
#+tblname: l
|
||||
#+attr_latex: m
|
||||
#+attr_html: n
|
||||
#+NAME: aa
|
||||
#+caption: bb *lorem* ipsum
|
||||
#+results: cc
|
||||
#+headers: dd
|
||||
#+header: ee
|
||||
#+label: ff
|
||||
#+plot: gg
|
||||
#+resname: hh
|
||||
#+result: ii
|
||||
#+source: jj
|
||||
#+srcname: kk
|
||||
#+tblname: ll
|
||||
#+attr_latex: mm
|
||||
#+attr_html: nn
|
||||
#+begin_export text
|
||||
bar
|
||||
#+end_export
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#+NAME: A
|
||||
#+CAPTION: B *LOREM* IPSUM
|
||||
#+RESULTS: C
|
||||
#+HEADERS: D
|
||||
#+HEADER: E
|
||||
#+LABEL: F
|
||||
#+PLOT: G
|
||||
#+RESNAME: H
|
||||
#+RESULT: I
|
||||
#+SOURCE: J
|
||||
#+SRCNAME: K
|
||||
#+TBLNAME: L
|
||||
#+ATTR_LATEX: M
|
||||
#+ATTR_HTML: N
|
||||
#+NAME: AA
|
||||
#+CAPTION: BB *LOREM* IPSUM
|
||||
#+RESULTS: CC
|
||||
#+HEADERS: DD
|
||||
#+HEADER: EE
|
||||
#+LABEL: FF
|
||||
#+PLOT: GG
|
||||
#+RESNAME: HH
|
||||
#+RESULT: II
|
||||
#+SOURCE: JJ
|
||||
#+SRCNAME: KK
|
||||
#+TBLNAME: LL
|
||||
#+ATTR_LATEX: MM
|
||||
#+ATTR_HTML: NN
|
||||
#+begin_export text
|
||||
bar
|
||||
#+end_export
|
||||
@@ -1,4 +0,0 @@
|
||||
#+NAME: foo
|
||||
#+begin_export text
|
||||
bar
|
||||
#+end_export
|
||||
@@ -0,0 +1,67 @@
|
||||
#+NAME: a
|
||||
#+caption: b *lorem* ipsum
|
||||
#+results: c
|
||||
#+headers: d
|
||||
#+header: e
|
||||
#+label: f
|
||||
#+plot: g
|
||||
#+resname: h
|
||||
#+result: i
|
||||
#+source: j
|
||||
#+srcname: k
|
||||
#+tblname: l
|
||||
#+attr_latex: m
|
||||
#+attr_html: n
|
||||
#+NAME: aa
|
||||
#+caption: bb *lorem* ipsum
|
||||
#+results: cc
|
||||
#+headers: dd
|
||||
#+header: ee
|
||||
#+label: ff
|
||||
#+plot: gg
|
||||
#+resname: hh
|
||||
#+result: ii
|
||||
#+source: jj
|
||||
#+srcname: kk
|
||||
#+tblname: ll
|
||||
#+attr_latex: mm
|
||||
#+attr_html: nn
|
||||
#+begin_src text
|
||||
bar
|
||||
#+end_src
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#+NAME: A
|
||||
#+CAPTION: B *LOREM* IPSUM
|
||||
#+RESULTS: C
|
||||
#+HEADERS: D
|
||||
#+HEADER: E
|
||||
#+LABEL: F
|
||||
#+PLOT: G
|
||||
#+RESNAME: H
|
||||
#+RESULT: I
|
||||
#+SOURCE: J
|
||||
#+SRCNAME: K
|
||||
#+TBLNAME: L
|
||||
#+ATTR_LATEX: M
|
||||
#+ATTR_HTML: N
|
||||
#+NAME: AA
|
||||
#+CAPTION: BB *LOREM* IPSUM
|
||||
#+RESULTS: CC
|
||||
#+HEADERS: DD
|
||||
#+HEADER: EE
|
||||
#+LABEL: FF
|
||||
#+PLOT: GG
|
||||
#+RESNAME: HH
|
||||
#+RESULT: II
|
||||
#+SOURCE: JJ
|
||||
#+SRCNAME: KK
|
||||
#+TBLNAME: LL
|
||||
#+ATTR_LATEX: MM
|
||||
#+ATTR_HTML: NN
|
||||
#+begin_src text
|
||||
bar
|
||||
#+end_src
|
||||
@@ -1,4 +0,0 @@
|
||||
#+NAME: foo
|
||||
#+begin_src text
|
||||
bar
|
||||
#+end_src
|
||||
@@ -0,0 +1,67 @@
|
||||
#+NAME: a
|
||||
#+caption: b *lorem* ipsum
|
||||
#+results: c
|
||||
#+headers: d
|
||||
#+header: e
|
||||
#+label: f
|
||||
#+plot: g
|
||||
#+resname: h
|
||||
#+result: i
|
||||
#+source: j
|
||||
#+srcname: k
|
||||
#+tblname: l
|
||||
#+attr_latex: m
|
||||
#+attr_html: n
|
||||
#+NAME: aa
|
||||
#+caption: bb *lorem* ipsum
|
||||
#+results: cc
|
||||
#+headers: dd
|
||||
#+header: ee
|
||||
#+label: ff
|
||||
#+plot: gg
|
||||
#+resname: hh
|
||||
#+result: ii
|
||||
#+source: jj
|
||||
#+srcname: kk
|
||||
#+tblname: ll
|
||||
#+attr_latex: mm
|
||||
#+attr_html: nn
|
||||
#+begin_verse text
|
||||
bar
|
||||
#+end_verse
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#+NAME: A
|
||||
#+CAPTION: B *LOREM* IPSUM
|
||||
#+RESULTS: C
|
||||
#+HEADERS: D
|
||||
#+HEADER: E
|
||||
#+LABEL: F
|
||||
#+PLOT: G
|
||||
#+RESNAME: H
|
||||
#+RESULT: I
|
||||
#+SOURCE: J
|
||||
#+SRCNAME: K
|
||||
#+TBLNAME: L
|
||||
#+ATTR_LATEX: M
|
||||
#+ATTR_HTML: N
|
||||
#+NAME: AA
|
||||
#+CAPTION: BB *LOREM* IPSUM
|
||||
#+RESULTS: CC
|
||||
#+HEADERS: DD
|
||||
#+HEADER: EE
|
||||
#+LABEL: FF
|
||||
#+PLOT: GG
|
||||
#+RESNAME: HH
|
||||
#+RESULT: II
|
||||
#+SOURCE: JJ
|
||||
#+SRCNAME: KK
|
||||
#+TBLNAME: LL
|
||||
#+ATTR_LATEX: MM
|
||||
#+ATTR_HTML: NN
|
||||
#+begin_verse text
|
||||
bar
|
||||
#+end_verse
|
||||
@@ -1,4 +0,0 @@
|
||||
#+NAME: foo
|
||||
#+begin_verse text
|
||||
bar
|
||||
#+end_verse
|
||||
@@ -0,0 +1,63 @@
|
||||
#+NAME: a
|
||||
#+caption: b *lorem* ipsum
|
||||
#+results: c
|
||||
#+headers: d
|
||||
#+header: e
|
||||
#+label: f
|
||||
#+plot: g
|
||||
#+resname: h
|
||||
#+result: i
|
||||
#+source: j
|
||||
#+srcname: k
|
||||
#+tblname: l
|
||||
#+attr_latex: m
|
||||
#+attr_html: n
|
||||
#+NAME: aa
|
||||
#+caption: bb *lorem* ipsum
|
||||
#+results: cc
|
||||
#+headers: dd
|
||||
#+header: ee
|
||||
#+label: ff
|
||||
#+plot: gg
|
||||
#+resname: hh
|
||||
#+result: ii
|
||||
#+source: jj
|
||||
#+srcname: kk
|
||||
#+tblname: ll
|
||||
#+attr_latex: mm
|
||||
#+attr_html: nn
|
||||
bar
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#+NAME: A
|
||||
#+CAPTION: B *LOREM* IPSUM
|
||||
#+RESULTS: C
|
||||
#+HEADERS: D
|
||||
#+HEADER: E
|
||||
#+LABEL: F
|
||||
#+PLOT: G
|
||||
#+RESNAME: H
|
||||
#+RESULT: I
|
||||
#+SOURCE: J
|
||||
#+SRCNAME: K
|
||||
#+TBLNAME: L
|
||||
#+ATTR_LATEX: M
|
||||
#+ATTR_HTML: N
|
||||
#+NAME: AA
|
||||
#+CAPTION: BB *LOREM* IPSUM
|
||||
#+RESULTS: CC
|
||||
#+HEADERS: DD
|
||||
#+HEADER: EE
|
||||
#+LABEL: FF
|
||||
#+PLOT: GG
|
||||
#+RESNAME: HH
|
||||
#+RESULT: II
|
||||
#+SOURCE: JJ
|
||||
#+SRCNAME: KK
|
||||
#+TBLNAME: LL
|
||||
#+ATTR_LATEX: MM
|
||||
#+ATTR_HTML: NN
|
||||
bar
|
||||
@@ -1,2 +0,0 @@
|
||||
#+NAME: foo
|
||||
bar
|
||||
@@ -1,3 +1,3 @@
|
||||
foo <<bar>> baz
|
||||
<<FOO>> bar
|
||||
|
||||
lorem << ipsum >> dolar
|
||||
[[FOO][baz]]
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
* foo
|
||||
|
||||
** bar
|
||||
|
||||
* baz
|
||||
3
org_mode_samples/sections_and_headings/name.org
Normal file
3
org_mode_samples/sections_and_headings/name.org
Normal file
@@ -0,0 +1,3 @@
|
||||
#+NAME: foo
|
||||
* bar
|
||||
#+NAME: 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 "${@}"
|
||||
58
scripts/dump_ast.bash
Executable file
58
scripts/dump_ast.bash
Executable file
@@ -0,0 +1,58 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# Dump the AST of an org-mode document from emacs
|
||||
set -euo pipefail
|
||||
IFS=$'\n\t'
|
||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
|
||||
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 {
|
||||
if [ $# -eq 0 ]; then
|
||||
dump_ast_stdin "${@}"
|
||||
else
|
||||
dump_ast_file "${@}"
|
||||
fi
|
||||
}
|
||||
|
||||
function dump_ast_stdin {
|
||||
# Until we can find a good way to encode stdin as an elisp string in bash, I cannot operate on stdin.
|
||||
die 1 "This script only works on files."
|
||||
}
|
||||
|
||||
function dump_ast_file {
|
||||
local target_file mounted_file elisp_script
|
||||
target_file=$($REALPATH "$1")
|
||||
mounted_file="/input${target_file}"
|
||||
elisp_script=$(cat <<EOF
|
||||
(progn
|
||||
(erase-buffer)
|
||||
(require 'org)
|
||||
(defun org-table-align () t)
|
||||
(find-file-read-only "${mounted_file}")
|
||||
(org-mode)
|
||||
(message "%s" (pp-to-string (org-element-parse-buffer)))
|
||||
)
|
||||
EOF
|
||||
)
|
||||
exec docker run --init --rm -i --mount type=tmpfs,destination=/tmp -v "/:/input:ro" --entrypoint "" organic-test emacs -q --no-site-file --no-splash --batch --eval "$elisp_script"
|
||||
}
|
||||
|
||||
|
||||
main "${@}"
|
||||
@@ -14,7 +14,7 @@ function main {
|
||||
additional_flags+=(--profile "$PROFILE")
|
||||
fi
|
||||
(cd "$DIR/../" && cargo build --no-default-features "${additional_flags[@]}")
|
||||
perf record --freq=2000 --call-graph dwarf --output="$DIR/../perf.data" "$DIR/../target/${PROFILE}/parse" "${@}"
|
||||
perf record --freq=70000 --call-graph dwarf --output="$DIR/../perf.data" "$DIR/../target/${PROFILE}/parse" "${@}"
|
||||
|
||||
# Convert to a format firefox will read
|
||||
# flags to consider --show-info
|
||||
|
||||
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(exact_size_is_empty)]
|
||||
use std::io::Read;
|
||||
@@ -14,30 +15,40 @@ mod init_tracing;
|
||||
|
||||
#[cfg(not(feature = "tracing"))]
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
main_body()
|
||||
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()?;
|
||||
let result = rt.block_on(async {
|
||||
rt.block_on(async {
|
||||
init_telemetry()?;
|
||||
let main_body_result = main_body();
|
||||
let main_body_result = main_body().await;
|
||||
shutdown_telemetry()?;
|
||||
main_body_result
|
||||
});
|
||||
result
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn main_body() -> Result<(), Box<dyn std::error::Error>> {
|
||||
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()?;
|
||||
run_anonymous_compare(org_contents)
|
||||
if run_anonymous_compare(org_contents).await? {
|
||||
} else {
|
||||
Err("Diff results do not match.")?;
|
||||
}
|
||||
Ok(())
|
||||
} else {
|
||||
for arg in args {
|
||||
run_compare_on_file(arg)?
|
||||
if run_compare_on_file(arg).await? {
|
||||
} else {
|
||||
Err("Diff results do not match.")?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
397
src/bin_foreign_document_test.rs
Normal file
397
src/bin_foreign_document_test.rs
Normal file
@@ -0,0 +1,397 @@
|
||||
#![feature(round_char_boundary)]
|
||||
#![feature(exact_size_is_empty)]
|
||||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
use std::process::ExitCode;
|
||||
|
||||
use futures::future::BoxFuture;
|
||||
use futures::future::FutureExt;
|
||||
use organic::compare::silent_compare_on_file;
|
||||
use tokio::sync::Semaphore;
|
||||
use tokio::task::JoinError;
|
||||
use walkdir::WalkDir;
|
||||
|
||||
#[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<ExitCode, 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<ExitCode, 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<ExitCode, Box<dyn std::error::Error>> {
|
||||
let layer = compare_group("org-mode", || {
|
||||
compare_all_org_document("/foreign_documents/org-mode")
|
||||
});
|
||||
let layer = layer.chain(compare_group("emacs", || {
|
||||
compare_all_org_document("/foreign_documents/emacs")
|
||||
}));
|
||||
let layer = layer.chain(compare_group("worg", || {
|
||||
compare_all_org_document("/foreign_documents/worg")
|
||||
}));
|
||||
let layer = layer.chain(compare_group("howard_abrams", compare_howard_abrams));
|
||||
let layer = layer.chain(compare_group("doomemacs", || {
|
||||
compare_all_org_document("/foreign_documents/doomemacs")
|
||||
}));
|
||||
let layer = layer.chain(compare_group("literate_build_emacs", || {
|
||||
compare_all_org_document("/foreign_documents/literate_build_emacs")
|
||||
}));
|
||||
|
||||
let running_tests: Vec<_> = layer.map(|c| tokio::spawn(c.run_test())).collect();
|
||||
let mut any_failed = false;
|
||||
for test in running_tests.into_iter() {
|
||||
let test_result = test.await??;
|
||||
if test_result.is_immediately_bad() || test_result.has_bad_children() {
|
||||
any_failed = true;
|
||||
}
|
||||
test_result.print();
|
||||
}
|
||||
|
||||
if any_failed {
|
||||
println!(
|
||||
"{color}Some tests failed.{reset}",
|
||||
color = TestResult::foreground_color(255, 0, 0),
|
||||
reset = TestResult::reset_color(),
|
||||
);
|
||||
Ok(ExitCode::FAILURE)
|
||||
} else {
|
||||
println!(
|
||||
"{color}All tests passed.{reset}",
|
||||
color = TestResult::foreground_color(0, 255, 0),
|
||||
reset = TestResult::reset_color(),
|
||||
);
|
||||
Ok(ExitCode::SUCCESS)
|
||||
}
|
||||
}
|
||||
|
||||
fn compare_howard_abrams() -> impl Iterator<Item = TestConfig> {
|
||||
let layer = compare_group("dot-files", || {
|
||||
compare_all_org_document("/foreign_documents/howardabrams/dot-files")
|
||||
});
|
||||
let layer = layer.chain(compare_group("hamacs", || {
|
||||
compare_all_org_document("/foreign_documents/howardabrams/hamacs")
|
||||
}));
|
||||
let layer = layer.chain(compare_group("demo-it", || {
|
||||
compare_all_org_document("/foreign_documents/howardabrams/demo-it")
|
||||
}));
|
||||
let layer = layer.chain(compare_group("magit-demo", || {
|
||||
compare_all_org_document("/foreign_documents/howardabrams/magit-demo")
|
||||
}));
|
||||
let layer = layer.chain(compare_group("pdx-emacs-hackers", || {
|
||||
compare_all_org_document("/foreign_documents/howardabrams/pdx-emacs-hackers")
|
||||
}));
|
||||
let layer = layer.chain(compare_group("flora-simulator", || {
|
||||
compare_all_org_document("/foreign_documents/howardabrams/flora-simulator")
|
||||
}));
|
||||
let layer = layer.chain(compare_group("literate-devops-demo", || {
|
||||
compare_all_org_document("/foreign_documents/howardabrams/literate-devops-demo")
|
||||
}));
|
||||
let layer = layer.chain(compare_group("clojure-yesql-xp", || {
|
||||
compare_all_org_document("/foreign_documents/howardabrams/clojure-yesql-xp")
|
||||
}));
|
||||
layer.chain(compare_group("veep", || {
|
||||
compare_all_org_document("/foreign_documents/howardabrams/veep")
|
||||
}))
|
||||
}
|
||||
|
||||
fn compare_group<N: Into<String>, F: Fn() -> I, I: Iterator<Item = TestConfig>>(
|
||||
name: N,
|
||||
inner: F,
|
||||
) -> impl Iterator<Item = TestConfig> {
|
||||
std::iter::once(TestConfig::TestLayer(TestLayer {
|
||||
name: name.into(),
|
||||
children: inner().collect(),
|
||||
}))
|
||||
}
|
||||
|
||||
fn compare_all_org_document<P: AsRef<Path>>(root_dir: P) -> impl Iterator<Item = TestConfig> {
|
||||
let root_dir = root_dir.as_ref();
|
||||
let mut test_files = WalkDir::new(root_dir)
|
||||
.into_iter()
|
||||
.filter(|e| match e {
|
||||
Ok(dir_entry) => {
|
||||
dir_entry.file_type().is_file()
|
||||
&& Path::new(dir_entry.file_name())
|
||||
.extension()
|
||||
.map(|ext| ext.to_ascii_lowercase() == "org")
|
||||
.unwrap_or(false)
|
||||
}
|
||||
Err(_) => true,
|
||||
})
|
||||
.collect::<Result<Vec<_>, _>>()
|
||||
.unwrap();
|
||||
test_files.sort_by_cached_key(|test_file| PathBuf::from(test_file.path()));
|
||||
let test_configs: Vec<_> = test_files
|
||||
.into_iter()
|
||||
.map(|test_file| {
|
||||
let name = test_file
|
||||
.path()
|
||||
.strip_prefix(root_dir)
|
||||
.expect("Result is from walkdir so it must be below the root directory.")
|
||||
.as_os_str()
|
||||
.to_string_lossy()
|
||||
.into_owned();
|
||||
TestConfig::SingleFile(SingleFile {
|
||||
name,
|
||||
file_path: test_file.into_path(),
|
||||
})
|
||||
})
|
||||
.collect();
|
||||
test_configs.into_iter()
|
||||
}
|
||||
|
||||
static TEST_PERMITS: Semaphore = Semaphore::const_new(8);
|
||||
|
||||
#[derive(Debug)]
|
||||
enum TestConfig {
|
||||
TestLayer(TestLayer),
|
||||
SingleFile(SingleFile),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct TestLayer {
|
||||
name: String,
|
||||
children: Vec<TestConfig>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct SingleFile {
|
||||
name: String,
|
||||
file_path: PathBuf,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
enum TestResult {
|
||||
ResultLayer(ResultLayer),
|
||||
SingleFileResult(SingleFileResult),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct ResultLayer {
|
||||
name: String,
|
||||
children: Vec<TestResult>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct SingleFileResult {
|
||||
name: String,
|
||||
status: TestStatus,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) enum TestStatus {
|
||||
Pass,
|
||||
Fail,
|
||||
}
|
||||
|
||||
impl TestConfig {
|
||||
fn run_test(self) -> BoxFuture<'static, Result<TestResult, JoinError>> {
|
||||
async move {
|
||||
match self {
|
||||
TestConfig::TestLayer(test) => Ok(TestResult::ResultLayer(test.run_test().await?)),
|
||||
TestConfig::SingleFile(test) => {
|
||||
Ok(TestResult::SingleFileResult(test.run_test().await?))
|
||||
}
|
||||
}
|
||||
}
|
||||
.boxed()
|
||||
}
|
||||
}
|
||||
|
||||
impl SingleFile {
|
||||
async fn run_test(self) -> Result<SingleFileResult, JoinError> {
|
||||
let _permit = TEST_PERMITS.acquire().await.unwrap();
|
||||
let result = silent_compare_on_file(&self.file_path).await;
|
||||
Ok(SingleFileResult {
|
||||
name: self.name,
|
||||
status: if let Ok(true) = result {
|
||||
TestStatus::Pass
|
||||
} else {
|
||||
TestStatus::Fail
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl TestLayer {
|
||||
async fn run_test(self) -> Result<ResultLayer, JoinError> {
|
||||
let running_children: Vec<_> = self
|
||||
.children
|
||||
.into_iter()
|
||||
.map(|c| tokio::spawn(c.run_test()))
|
||||
.collect();
|
||||
let mut children = Vec::with_capacity(running_children.len());
|
||||
for c in running_children {
|
||||
children.push(c.await??);
|
||||
}
|
||||
Ok(ResultLayer {
|
||||
name: self.name,
|
||||
children,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl TestResult {
|
||||
pub fn print(&self) {
|
||||
self.print_indented(0);
|
||||
}
|
||||
|
||||
fn print_indented(&self, indentation: usize) {
|
||||
match self {
|
||||
TestResult::ResultLayer(result) => result.print_indented(indentation),
|
||||
TestResult::SingleFileResult(result) => result.print_indented(indentation),
|
||||
}
|
||||
}
|
||||
|
||||
fn has_bad_children(&self) -> bool {
|
||||
match self {
|
||||
TestResult::ResultLayer(result) => result.has_bad_children(),
|
||||
TestResult::SingleFileResult(result) => result.has_bad_children(),
|
||||
}
|
||||
}
|
||||
|
||||
fn is_immediately_bad(&self) -> bool {
|
||||
match self {
|
||||
TestResult::ResultLayer(result) => result.is_immediately_bad(),
|
||||
TestResult::SingleFileResult(result) => result.is_immediately_bad(),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn foreground_color(red: u8, green: u8, blue: u8) -> String {
|
||||
if TestResult::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 TestResult::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 TestResult::should_use_color() {
|
||||
"\x1b[0m"
|
||||
} else {
|
||||
""
|
||||
}
|
||||
}
|
||||
|
||||
fn should_use_color() -> bool {
|
||||
!std::env::var("NO_COLOR").is_ok_and(|val| !val.is_empty())
|
||||
}
|
||||
}
|
||||
|
||||
impl SingleFileResult {
|
||||
fn print_indented(&self, indentation: usize) {
|
||||
match self.status {
|
||||
TestStatus::Pass => {
|
||||
println!(
|
||||
"{indentation}{color}PASS{reset} {name}",
|
||||
indentation = " ".repeat(indentation),
|
||||
color = TestResult::foreground_color(0, 255, 0),
|
||||
reset = TestResult::reset_color(),
|
||||
name = self.name
|
||||
);
|
||||
}
|
||||
TestStatus::Fail => {
|
||||
println!(
|
||||
"{indentation}{color}FAIL{reset} {name}",
|
||||
indentation = " ".repeat(indentation),
|
||||
color = TestResult::foreground_color(255, 0, 0),
|
||||
reset = TestResult::reset_color(),
|
||||
name = self.name
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn has_bad_children(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn is_immediately_bad(&self) -> bool {
|
||||
match self.status {
|
||||
TestStatus::Pass => false,
|
||||
TestStatus::Fail => true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ResultLayer {
|
||||
fn print_indented(&self, indentation: usize) {
|
||||
if self.is_immediately_bad() {
|
||||
println!(
|
||||
"{indentation}{color}FAIL{reset} {name}",
|
||||
indentation = " ".repeat(indentation),
|
||||
color = TestResult::foreground_color(255, 0, 0),
|
||||
reset = TestResult::reset_color(),
|
||||
name = self.name
|
||||
);
|
||||
} else if self.has_bad_children() {
|
||||
println!(
|
||||
"{indentation}{color}BADCHILD{reset} {name}",
|
||||
indentation = " ".repeat(indentation),
|
||||
color = TestResult::foreground_color(255, 255, 0),
|
||||
reset = TestResult::reset_color(),
|
||||
name = self.name
|
||||
);
|
||||
} else {
|
||||
println!(
|
||||
"{indentation}{color}PASS{reset} {name}",
|
||||
indentation = " ".repeat(indentation),
|
||||
color = TestResult::foreground_color(0, 255, 0),
|
||||
reset = TestResult::reset_color(),
|
||||
name = self.name
|
||||
);
|
||||
}
|
||||
self.children
|
||||
.iter()
|
||||
.for_each(|result| result.print_indented(indentation + 1));
|
||||
}
|
||||
|
||||
fn has_bad_children(&self) -> bool {
|
||||
self.children
|
||||
.iter()
|
||||
.any(|result| result.is_immediately_bad() || result.has_bad_children())
|
||||
}
|
||||
|
||||
fn is_immediately_bad(&self) -> bool {
|
||||
false
|
||||
}
|
||||
}
|
||||
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,66 +1,90 @@
|
||||
use std::path::Path;
|
||||
|
||||
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::LocalFileAccessInterface;
|
||||
use crate::parser::parse_file_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 fn run_anonymous_compare<P: AsRef<str>>(
|
||||
pub async fn run_anonymous_compare<P: AsRef<str>>(
|
||||
org_contents: P,
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
run_anonymous_compare_with_settings(org_contents, &GlobalSettings::default())
|
||||
) -> Result<bool, Box<dyn std::error::Error>> {
|
||||
run_anonymous_compare_with_settings(org_contents, &GlobalSettings::default(), false).await
|
||||
}
|
||||
|
||||
pub fn run_compare_on_file<P: AsRef<Path>>(org_path: P) -> Result<(), Box<dyn std::error::Error>> {
|
||||
run_compare_on_file_with_settings(org_path, &GlobalSettings::default())
|
||||
pub async fn run_compare_on_file<P: AsRef<Path>>(
|
||||
org_path: P,
|
||||
) -> Result<bool, Box<dyn std::error::Error>> {
|
||||
run_compare_on_file_with_settings(org_path, &GlobalSettings::default(), false).await
|
||||
}
|
||||
|
||||
pub fn run_anonymous_compare_with_settings<P: AsRef<str>>(
|
||||
pub async fn silent_anonymous_compare<P: AsRef<str>>(
|
||||
org_contents: P,
|
||||
global_settings: &GlobalSettings,
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
) -> Result<bool, Box<dyn std::error::Error>> {
|
||||
run_anonymous_compare_with_settings(org_contents, &GlobalSettings::default(), true).await
|
||||
}
|
||||
|
||||
pub async fn silent_compare_on_file<P: AsRef<Path>>(
|
||||
org_path: P,
|
||||
) -> Result<bool, Box<dyn std::error::Error>> {
|
||||
run_compare_on_file_with_settings(org_path, &GlobalSettings::default(), true).await
|
||||
}
|
||||
|
||||
pub async fn run_anonymous_compare_with_settings<'g, 's, P: AsRef<str>>(
|
||||
org_contents: P,
|
||||
global_settings: &GlobalSettings<'g, 's>,
|
||||
silent: bool,
|
||||
) -> Result<bool, Box<dyn std::error::Error>> {
|
||||
// TODO: This is a work-around to pretend that dos line endings do not exist. It would be better to handle the difference in line endings.
|
||||
let org_contents = org_contents.as_ref().replace("\r\n", "\n");
|
||||
let org_contents = org_contents.as_str();
|
||||
print_versions()?;
|
||||
if !silent {
|
||||
print_versions().await?;
|
||||
}
|
||||
let rust_parsed = parse_with_settings(org_contents, global_settings)?;
|
||||
let org_sexp = emacs_parse_anonymous_org_document(org_contents, global_settings)?;
|
||||
let org_sexp = emacs_parse_anonymous_org_document(org_contents, global_settings).await?;
|
||||
let (_remaining, parsed_sexp) = sexp(org_sexp.as_str()).map_err(|e| e.to_string())?;
|
||||
|
||||
println!("{}\n\n\n", org_contents);
|
||||
println!("{}", org_sexp);
|
||||
println!("{:#?}", rust_parsed);
|
||||
if !silent {
|
||||
println!("{}\n\n\n", org_contents);
|
||||
println!("{}", org_sexp);
|
||||
println!("{:#?}", rust_parsed);
|
||||
}
|
||||
|
||||
// We do the diffing after printing out both parsed forms in case the diffing panics
|
||||
let diff_result = compare_document(&parsed_sexp, &rust_parsed)?;
|
||||
diff_result.print(org_contents)?;
|
||||
if !silent {
|
||||
diff_result.print(org_contents)?;
|
||||
}
|
||||
|
||||
if diff_result.is_bad() {
|
||||
Err("Diff results do not match.")?;
|
||||
} else {
|
||||
return Ok(false);
|
||||
} else if !silent {
|
||||
println!(
|
||||
"{color}Entire document passes.{reset}",
|
||||
color = DiffResult::foreground_color(0, 255, 0),
|
||||
reset = DiffResult::reset_color(),
|
||||
color = foreground_color(0, 255, 0),
|
||||
reset = reset_color(),
|
||||
);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
Ok(true)
|
||||
}
|
||||
|
||||
pub fn run_compare_on_file_with_settings<P: AsRef<Path>>(
|
||||
pub async fn run_compare_on_file_with_settings<'g, 's, P: AsRef<Path>>(
|
||||
org_path: P,
|
||||
global_settings: &GlobalSettings,
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
global_settings: &GlobalSettings<'g, 's>,
|
||||
silent: bool,
|
||||
) -> Result<bool, Box<dyn std::error::Error>> {
|
||||
let org_path = org_path.as_ref();
|
||||
print_versions()?;
|
||||
if !silent {
|
||||
print_versions().await?;
|
||||
}
|
||||
let parent_directory = org_path
|
||||
.parent()
|
||||
.ok_or("Should be contained inside a directory.")?;
|
||||
@@ -77,32 +101,30 @@ pub fn run_compare_on_file_with_settings<P: AsRef<Path>>(
|
||||
global_settings
|
||||
};
|
||||
let rust_parsed = parse_file_with_settings(org_contents, &global_settings, Some(org_path))?;
|
||||
let org_sexp = emacs_parse_file_org_document(org_path, &global_settings)?;
|
||||
let org_sexp = emacs_parse_file_org_document(org_path, &global_settings).await?;
|
||||
let (_remaining, parsed_sexp) = sexp(org_sexp.as_str()).map_err(|e| e.to_string())?;
|
||||
|
||||
println!("{}\n\n\n", org_contents);
|
||||
println!("{}", org_sexp);
|
||||
println!("{:#?}", rust_parsed);
|
||||
if !silent {
|
||||
println!("{}\n\n\n", org_contents);
|
||||
println!("{}", org_sexp);
|
||||
println!("{:#?}", rust_parsed);
|
||||
}
|
||||
|
||||
// We do the diffing after printing out both parsed forms in case the diffing panics
|
||||
let diff_result = compare_document(&parsed_sexp, &rust_parsed)?;
|
||||
diff_result.print(org_contents)?;
|
||||
if !silent {
|
||||
diff_result.print(org_contents)?;
|
||||
}
|
||||
|
||||
if diff_result.is_bad() {
|
||||
Err("Diff results do not match.")?;
|
||||
} else {
|
||||
return Ok(false);
|
||||
} else if !silent {
|
||||
println!(
|
||||
"{color}Entire document passes.{reset}",
|
||||
color = DiffResult::foreground_color(0, 255, 0),
|
||||
reset = DiffResult::reset_color(),
|
||||
color = foreground_color(0, 255, 0),
|
||||
reset = reset_color(),
|
||||
);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn print_versions() -> Result<(), Box<dyn std::error::Error>> {
|
||||
eprintln!("Using emacs version: {}", get_emacs_version()?.trim());
|
||||
eprintln!("Using org-mode version: {}", get_org_mode_version()?.trim());
|
||||
Ok(())
|
||||
Ok(true)
|
||||
}
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
use std::borrow::Borrow;
|
||||
use std::borrow::Cow;
|
||||
use std::collections::BTreeSet;
|
||||
use std::fmt::Debug;
|
||||
use std::str::FromStr;
|
||||
|
||||
use super::diff::artificial_diff_scope;
|
||||
use super::diff::artificial_owned_diff_scope;
|
||||
use super::diff::compare_ast_node;
|
||||
use super::diff::DiffEntry;
|
||||
use super::diff::DiffStatus;
|
||||
use super::sexp::unquote;
|
||||
use super::sexp::Token;
|
||||
use super::util::get_property;
|
||||
use super::util::get_property_numeric;
|
||||
use super::util::get_property_quoted_string;
|
||||
@@ -17,6 +18,8 @@ use crate::types::CharOffsetInLine;
|
||||
use crate::types::LineNumber;
|
||||
use crate::types::RetainLabels;
|
||||
use crate::types::SwitchNumberLines;
|
||||
use crate::util::elisp::unquote;
|
||||
use crate::util::elisp::Token;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) enum EmacsField<'s> {
|
||||
@@ -32,14 +35,34 @@ pub(crate) enum ComparePropertiesResult<'b, 's> {
|
||||
DiffEntry(DiffEntry<'b, 's>),
|
||||
}
|
||||
|
||||
impl<'b, 's> ComparePropertiesResult<'b, 's> {
|
||||
pub(crate) fn apply(
|
||||
self,
|
||||
child_status: &mut Vec<DiffEntry<'b, 's>>,
|
||||
this_status: &mut DiffStatus,
|
||||
message: &mut Option<String>,
|
||||
) {
|
||||
match self {
|
||||
ComparePropertiesResult::NoChange => {}
|
||||
ComparePropertiesResult::SelfChange(new_status, new_message) => {
|
||||
*this_status = new_status;
|
||||
*message = new_message
|
||||
}
|
||||
ComparePropertiesResult::DiffEntry(diff_entry) => child_status.push(diff_entry),
|
||||
}
|
||||
|
||||
// foo
|
||||
}
|
||||
}
|
||||
|
||||
/// Do no comparison.
|
||||
///
|
||||
/// This is for when you want to acknowledge that a field exists in the emacs token, but you do not have any validation for it when using the compare_properties!() macro. Ideally, this should be kept to a minimum since this represents untested values.
|
||||
pub(crate) fn compare_noop<'b, 's, 'x, R, RG>(
|
||||
pub(crate) fn compare_noop<'b, 's, R, RG>(
|
||||
_source: &'s str,
|
||||
_emacs: &'b Token<'s>,
|
||||
_rust_node: R,
|
||||
_emacs_field: &'x str,
|
||||
_emacs_field: &str,
|
||||
_rust_value_getter: RG,
|
||||
) -> Result<ComparePropertiesResult<'b, 's>, Box<dyn std::error::Error>> {
|
||||
Ok(ComparePropertiesResult::NoChange)
|
||||
@@ -48,18 +71,16 @@ pub(crate) fn compare_noop<'b, 's, 'x, R, RG>(
|
||||
/// Do no comparison.
|
||||
///
|
||||
/// This is for when you want to acknowledge that a field exists in the emacs token, but you do not have any validation for it when using the compare_properties!() macro. Ideally, this should be kept to a minimum since this represents untested values.
|
||||
pub(crate) fn compare_identity() -> () {
|
||||
()
|
||||
}
|
||||
pub(crate) fn compare_identity() {}
|
||||
|
||||
/// Assert that the emacs value is always nil or absent.
|
||||
///
|
||||
/// This is usually used for fields which, in my testing, are always nil. Using this compare function instead of simply doing a compare_noop will enable us to be alerted when we finally come across an org-mode document that has a value other than nil for the property.
|
||||
pub(crate) fn compare_property_always_nil<'b, 's, 'x, R, RG>(
|
||||
pub(crate) fn compare_property_always_nil<'b, 's, R, RG>(
|
||||
_source: &'s str,
|
||||
emacs: &'b Token<'s>,
|
||||
_rust_node: R,
|
||||
emacs_field: &'x str,
|
||||
emacs_field: &str,
|
||||
_rust_value_getter: RG,
|
||||
) -> Result<ComparePropertiesResult<'b, 's>, Box<dyn std::error::Error>> {
|
||||
let value = get_property(emacs, emacs_field)?;
|
||||
@@ -78,7 +99,6 @@ pub(crate) fn compare_property_always_nil<'b, 's, 'x, R, RG>(
|
||||
pub(crate) fn compare_property_quoted_string<
|
||||
'b,
|
||||
's,
|
||||
'x,
|
||||
R,
|
||||
RV: AsRef<str> + std::fmt::Debug,
|
||||
RG: Fn(R) -> Option<RV>,
|
||||
@@ -86,12 +106,12 @@ pub(crate) fn compare_property_quoted_string<
|
||||
_source: &'s str,
|
||||
emacs: &'b Token<'s>,
|
||||
rust_node: R,
|
||||
emacs_field: &'x str,
|
||||
emacs_field: &str,
|
||||
rust_value_getter: RG,
|
||||
) -> Result<ComparePropertiesResult<'b, 's>, Box<dyn std::error::Error>> {
|
||||
let value = get_property_quoted_string(emacs, emacs_field)?;
|
||||
let rust_value = rust_value_getter(rust_node);
|
||||
if rust_value.as_ref().map(|s| s.as_ref()) != value.as_ref().map(String::as_str) {
|
||||
if rust_value.as_ref().map(|s| s.as_ref()) != value.as_deref() {
|
||||
let this_status = DiffStatus::Bad;
|
||||
let message = Some(format!(
|
||||
"{} mismatch (emacs != rust) {:?} != {:?}",
|
||||
@@ -159,7 +179,6 @@ where
|
||||
pub(crate) fn compare_property_list_of_quoted_string<
|
||||
'b,
|
||||
's,
|
||||
'x,
|
||||
R,
|
||||
RV: AsRef<str> + std::fmt::Debug,
|
||||
RI: Iterator<Item = RV>,
|
||||
@@ -168,7 +187,7 @@ pub(crate) fn compare_property_list_of_quoted_string<
|
||||
_source: &'s str,
|
||||
emacs: &'b Token<'s>,
|
||||
rust_node: R,
|
||||
emacs_field: &'x str,
|
||||
emacs_field: &str,
|
||||
rust_value_getter: RG,
|
||||
) -> Result<ComparePropertiesResult<'b, 's>, Box<dyn std::error::Error>> {
|
||||
let value = get_property(emacs, emacs_field)?
|
||||
@@ -245,15 +264,12 @@ pub(crate) fn compare_property_set_of_quoted_string<
|
||||
.iter()
|
||||
.map(|e| e.as_atom())
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
let value: Vec<String> = value
|
||||
let value: Vec<Cow<'_, str>> = value
|
||||
.into_iter()
|
||||
.map(unquote)
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
let value: BTreeSet<&str> = value.iter().map(|e| e.as_str()).collect();
|
||||
let mismatched: Vec<_> = value
|
||||
.symmetric_difference(&rust_value)
|
||||
.map(|val| *val)
|
||||
.collect();
|
||||
let value: BTreeSet<&str> = value.iter().map(|e| e.borrow()).collect();
|
||||
let mismatched: Vec<_> = value.symmetric_difference(&rust_value).copied().collect();
|
||||
if !mismatched.is_empty() {
|
||||
let this_status = DiffStatus::Bad;
|
||||
let message = Some(format!(
|
||||
@@ -266,11 +282,111 @@ pub(crate) fn compare_property_set_of_quoted_string<
|
||||
Ok(ComparePropertiesResult::NoChange)
|
||||
}
|
||||
|
||||
pub(crate) fn compare_property_boolean<'b, 's, 'x, R, RG: Fn(R) -> bool>(
|
||||
pub(crate) fn compare_property_optional_pair<
|
||||
'b,
|
||||
's,
|
||||
R,
|
||||
RV: AsRef<str> + std::fmt::Debug,
|
||||
ROV: AsRef<str> + std::fmt::Debug,
|
||||
RG: Fn(R) -> Option<(Option<ROV>, RV)>,
|
||||
>(
|
||||
_source: &'s str,
|
||||
emacs: &'b Token<'s>,
|
||||
rust_node: R,
|
||||
emacs_field: &'x str,
|
||||
emacs_field: &str,
|
||||
rust_value_getter: RG,
|
||||
) -> Result<ComparePropertiesResult<'b, 's>, Box<dyn std::error::Error>> {
|
||||
let value = get_property(emacs, emacs_field)?
|
||||
.map(Token::as_list)
|
||||
.map_or(Ok(None), |r| r.map(Some))?;
|
||||
let rust_value = rust_value_getter(rust_node);
|
||||
match (value, &rust_value) {
|
||||
(None, None) => {}
|
||||
(None, Some(_)) | (Some(_), None) => {
|
||||
let this_status = DiffStatus::Bad;
|
||||
let message = Some(format!(
|
||||
"{} mismatch (emacs != rust) {:?} != {:?}",
|
||||
emacs_field, value, rust_value
|
||||
));
|
||||
return Ok(ComparePropertiesResult::SelfChange(this_status, message));
|
||||
}
|
||||
(Some(el), Some((Some(_), _))) if el.len() != 3 => {
|
||||
let this_status = DiffStatus::Bad;
|
||||
let message = Some(format!(
|
||||
"{} mismatch (emacs != rust) {:?} != {:?}",
|
||||
emacs_field, value, rust_value
|
||||
));
|
||||
return Ok(ComparePropertiesResult::SelfChange(this_status, message));
|
||||
}
|
||||
(Some(el), Some((None, _))) if el.len() != 1 => {
|
||||
let this_status = DiffStatus::Bad;
|
||||
let message = Some(format!(
|
||||
"{} mismatch (emacs != rust) {:?} != {:?}",
|
||||
emacs_field, value, rust_value
|
||||
));
|
||||
return Ok(ComparePropertiesResult::SelfChange(this_status, message));
|
||||
}
|
||||
(Some(el), Some((Some(orl), rl))) => {
|
||||
let e = el
|
||||
.first()
|
||||
.map(Token::as_atom)
|
||||
.map_or(Ok(None), |r| r.map(Some))?
|
||||
.map(unquote)
|
||||
.map_or(Ok(None), |r| r.map(Some))?
|
||||
.expect("Above match proved length to be 3.");
|
||||
let oe = el
|
||||
.get(2)
|
||||
.map(Token::as_atom)
|
||||
.map_or(Ok(None), |r| r.map(Some))?
|
||||
.map(unquote)
|
||||
.map_or(Ok(None), |r| r.map(Some))?
|
||||
.expect("Above match proved length to be 3.");
|
||||
let r = rl.as_ref();
|
||||
let or = orl.as_ref();
|
||||
if e != r {
|
||||
let this_status = DiffStatus::Bad;
|
||||
let message = Some(format!(
|
||||
"{} mismatch (emacs != rust) {:?} != {:?}. Full list: {:?} != {:?}",
|
||||
emacs_field, e, r, value, rust_value
|
||||
));
|
||||
return Ok(ComparePropertiesResult::SelfChange(this_status, message));
|
||||
}
|
||||
if oe != or {
|
||||
let this_status = DiffStatus::Bad;
|
||||
let message = Some(format!(
|
||||
"{} mismatch (emacs != rust) {:?} != {:?}. Full list: {:?} != {:?}",
|
||||
emacs_field, e, r, value, rust_value
|
||||
));
|
||||
return Ok(ComparePropertiesResult::SelfChange(this_status, message));
|
||||
}
|
||||
}
|
||||
(Some(el), Some((None, rl))) => {
|
||||
let e = el
|
||||
.first()
|
||||
.map(Token::as_atom)
|
||||
.map_or(Ok(None), |r| r.map(Some))?
|
||||
.map(unquote)
|
||||
.map_or(Ok(None), |r| r.map(Some))?
|
||||
.expect("Above match proved length to be 1.");
|
||||
let r = rl.as_ref();
|
||||
if e != r {
|
||||
let this_status = DiffStatus::Bad;
|
||||
let message = Some(format!(
|
||||
"{} mismatch (emacs != rust) {:?} != {:?}. Full list: {:?} != {:?}",
|
||||
emacs_field, e, r, value, rust_value
|
||||
));
|
||||
return Ok(ComparePropertiesResult::SelfChange(this_status, message));
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(ComparePropertiesResult::NoChange)
|
||||
}
|
||||
|
||||
pub(crate) fn compare_property_boolean<'b, 's, R, RG: Fn(R) -> bool>(
|
||||
_source: &'s str,
|
||||
emacs: &'b Token<'s>,
|
||||
rust_node: R,
|
||||
emacs_field: &str,
|
||||
rust_value_getter: RG,
|
||||
) -> Result<ComparePropertiesResult<'b, 's>, Box<dyn std::error::Error>> {
|
||||
// get_property already converts nil to None.
|
||||
@@ -353,6 +469,8 @@ where
|
||||
let rust_value: Option<Vec<RV>> = rust_value.map(|it| it.collect());
|
||||
match (value, rust_value) {
|
||||
(None, None) => {}
|
||||
(Some(el), None)
|
||||
if el.len() == 1 && el.iter().all(|t| matches!(t.as_atom(), Ok(r#""""#))) => {}
|
||||
(None, rv @ Some(_)) | (Some(_), rv @ None) => {
|
||||
let this_status = DiffStatus::Bad;
|
||||
let message = Some(format!(
|
||||
@@ -381,6 +499,169 @@ where
|
||||
Ok(ComparePropertiesResult::NoChange)
|
||||
}
|
||||
|
||||
pub(crate) fn compare_property_object_tree<
|
||||
'b,
|
||||
's,
|
||||
'x,
|
||||
R,
|
||||
RV: std::fmt::Debug + 'b,
|
||||
ROV: std::fmt::Debug + 'b,
|
||||
RI: Iterator<Item = &'b (Option<Vec<ROV>>, Vec<RV>)> + ExactSizeIterator + std::fmt::Debug,
|
||||
RG: Fn(R) -> Option<RI>,
|
||||
>(
|
||||
source: &'s str,
|
||||
emacs: &'b Token<'s>,
|
||||
rust_node: R,
|
||||
emacs_field: &'x str,
|
||||
rust_value_getter: RG,
|
||||
) -> Result<ComparePropertiesResult<'b, 's>, Box<dyn std::error::Error>>
|
||||
where
|
||||
AstNode<'b, 's>: From<&'b RV>,
|
||||
AstNode<'b, 's>: From<&'b ROV>,
|
||||
{
|
||||
let value = get_property(emacs, emacs_field)?
|
||||
.map(Token::as_list)
|
||||
.map_or(Ok(None), |r| r.map(Some))?;
|
||||
let rust_value = rust_value_getter(rust_node);
|
||||
let (outer_emacs_list, outer_rust_list) = match (value, rust_value) {
|
||||
(None, None) => {
|
||||
return Ok(ComparePropertiesResult::NoChange);
|
||||
}
|
||||
(None, rv @ Some(_)) | (Some(_), rv @ None) => {
|
||||
let this_status = DiffStatus::Bad;
|
||||
let message = Some(format!(
|
||||
"{} mismatch (emacs != rust) {:?} != {:?}",
|
||||
emacs_field, value, rv
|
||||
));
|
||||
return Ok(ComparePropertiesResult::SelfChange(this_status, message));
|
||||
}
|
||||
(Some(el), Some(rl)) if el.len() != rl.len() => {
|
||||
let this_status = DiffStatus::Bad;
|
||||
let message = Some(format!(
|
||||
"{} mismatch (emacs != rust) {:?} != {:?}",
|
||||
emacs_field, el, rl
|
||||
));
|
||||
return Ok(ComparePropertiesResult::SelfChange(this_status, message));
|
||||
}
|
||||
(Some(el), Some(rl)) => (el, rl),
|
||||
};
|
||||
let mut full_status: Vec<DiffEntry<'b, 's>> = Vec::with_capacity(outer_rust_list.len());
|
||||
|
||||
for (kw_e, kw_r) in outer_emacs_list.iter().zip(outer_rust_list) {
|
||||
match (kw_e.as_atom(), kw_r) {
|
||||
(Ok("nil"), (None, mandatory_value)) if mandatory_value.is_empty() => {
|
||||
// If its an empty keyword then it becomes nil in the elisp.
|
||||
continue;
|
||||
}
|
||||
(Ok("nil"), _) => {
|
||||
let this_status = DiffStatus::Bad;
|
||||
let message = Some(format!(
|
||||
"{} mismatch (emacs != rust) {:?} != {:?}",
|
||||
emacs_field, kw_e, kw_r
|
||||
));
|
||||
return Ok(ComparePropertiesResult::SelfChange(this_status, message));
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
let kw_e = kw_e.as_list()?;
|
||||
let child_status_length = kw_r.1.len() + kw_r.0.as_ref().map(|opt| opt.len()).unwrap_or(0);
|
||||
let mut child_status: Vec<DiffEntry<'b, 's>> = Vec::with_capacity(child_status_length);
|
||||
if let Some(or) = &kw_r.0 {
|
||||
// if optional value
|
||||
let mut kw_e = kw_e.iter();
|
||||
// First element is a list representing the mandatory value.
|
||||
if let Some(val_e) = kw_e.next() {
|
||||
match (val_e.as_atom(), kw_r) {
|
||||
(Ok("nil"), (_, mandatory_value)) if mandatory_value.is_empty() => {}
|
||||
(Ok("nil"), _) => {
|
||||
let this_status = DiffStatus::Bad;
|
||||
let message = Some(format!(
|
||||
"{} mismatch (emacs != rust) {:?} != {:?}",
|
||||
emacs_field, kw_e, kw_r
|
||||
));
|
||||
return Ok(ComparePropertiesResult::SelfChange(this_status, message));
|
||||
}
|
||||
_ => {
|
||||
let el = val_e.as_list()?;
|
||||
if el.len() != kw_r.1.len() {
|
||||
let this_status = DiffStatus::Bad;
|
||||
let message = Some(format!(
|
||||
"{} mismatch (emacs != rust) {:?} != {:?}",
|
||||
emacs_field, kw_e, kw_r
|
||||
));
|
||||
return Ok(ComparePropertiesResult::SelfChange(this_status, message));
|
||||
}
|
||||
for (e, r) in el.iter().zip(kw_r.1.iter()) {
|
||||
child_status.push(compare_ast_node(source, e, r.into())?);
|
||||
}
|
||||
}
|
||||
};
|
||||
} else {
|
||||
let this_status = DiffStatus::Bad;
|
||||
let message = Some(format!(
|
||||
"{} mismatch (emacs != rust) {:?} != {:?}",
|
||||
emacs_field, kw_e, kw_r
|
||||
));
|
||||
return Ok(ComparePropertiesResult::SelfChange(this_status, message));
|
||||
}
|
||||
// Remaining elements are the optional value.
|
||||
if kw_e.len() != or.len() {
|
||||
let this_status = DiffStatus::Bad;
|
||||
let message = Some(format!(
|
||||
"{} mismatch (emacs != rust) {:?} != {:?}",
|
||||
emacs_field, kw_e, kw_r
|
||||
));
|
||||
return Ok(ComparePropertiesResult::SelfChange(this_status, message));
|
||||
}
|
||||
for (e, r) in kw_e.zip(or.iter()) {
|
||||
child_status.push(compare_ast_node(source, e, r.into())?);
|
||||
}
|
||||
} else {
|
||||
// if no optional value
|
||||
if !kw_e.len() == 1 {
|
||||
let this_status = DiffStatus::Bad;
|
||||
let message = Some(format!(
|
||||
"{} mismatch (emacs != rust) {:?} != {:?}",
|
||||
emacs_field, kw_e, kw_r
|
||||
));
|
||||
return Ok(ComparePropertiesResult::SelfChange(this_status, message));
|
||||
}
|
||||
|
||||
let e = kw_e
|
||||
.first()
|
||||
.map(Token::as_list)
|
||||
.map_or(Ok(None), |r| r.map(Some))?
|
||||
.expect("The above if-statement proves this will be Some.")
|
||||
.iter();
|
||||
let r = kw_r.1.iter();
|
||||
|
||||
if e.len() != r.len() {
|
||||
let this_status = DiffStatus::Bad;
|
||||
let message = Some(format!(
|
||||
"{} mismatch (emacs != rust) {:?} != {:?}",
|
||||
emacs_field, kw_e, kw_r
|
||||
));
|
||||
return Ok(ComparePropertiesResult::SelfChange(this_status, message));
|
||||
}
|
||||
|
||||
for (e, r) in e.zip(r) {
|
||||
child_status.push(compare_ast_node(source, e, r.into())?);
|
||||
}
|
||||
}
|
||||
if !child_status.is_empty() {
|
||||
let diff_scope = artificial_diff_scope("mandatory value", child_status)?;
|
||||
full_status.push(diff_scope);
|
||||
}
|
||||
}
|
||||
|
||||
if full_status.is_empty() {
|
||||
Ok(ComparePropertiesResult::NoChange)
|
||||
} else {
|
||||
let diff_scope = artificial_owned_diff_scope(emacs_field, full_status)?;
|
||||
Ok(ComparePropertiesResult::DiffEntry(diff_scope))
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn compare_property_number_lines<
|
||||
'b,
|
||||
's,
|
||||
@@ -402,7 +683,7 @@ pub(crate) fn compare_property_number_lines<
|
||||
(Some(number_lines), Some(rust_number_lines)) => {
|
||||
let token_list = number_lines.as_list()?;
|
||||
let number_type = token_list
|
||||
.get(0)
|
||||
.first()
|
||||
.map(Token::as_atom)
|
||||
.map_or(Ok(None), |r| r.map(Some))?
|
||||
.ok_or(":number-lines should have a type.")?;
|
||||
|
||||
@@ -2,7 +2,6 @@ use std::borrow::Cow;
|
||||
// TODO: Update all to use the macro to assert there are no unexpected keys.
|
||||
// TODO: Check all compare funtions for whether they correctly iterate children.
|
||||
use std::collections::BTreeSet;
|
||||
use std::collections::HashSet;
|
||||
|
||||
use super::compare_field::compare_identity;
|
||||
use super::compare_field::compare_noop;
|
||||
@@ -17,17 +16,13 @@ use super::compare_field::compare_property_retain_labels;
|
||||
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_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::assert_no_children;
|
||||
use super::util::compare_additional_properties;
|
||||
use super::util::compare_affiliated_keywords;
|
||||
use super::util::compare_children;
|
||||
use super::util::compare_children_iter;
|
||||
use super::util::compare_standard_properties;
|
||||
use super::util::get_property;
|
||||
use super::util::get_property_boolean;
|
||||
use super::util::get_property_quoted_string;
|
||||
use crate::compare::compare_field::ComparePropertiesResult;
|
||||
use crate::compare::compare_field::EmacsField;
|
||||
use crate::compare::macros::compare_properties;
|
||||
@@ -48,7 +43,6 @@ use crate::types::Date;
|
||||
use crate::types::DayOfMonth;
|
||||
use crate::types::DiarySexp;
|
||||
use crate::types::Document;
|
||||
use crate::types::DocumentElement;
|
||||
use crate::types::Drawer;
|
||||
use crate::types::DynamicBlock;
|
||||
use crate::types::Entity;
|
||||
@@ -59,7 +53,6 @@ use crate::types::FixedWidthArea;
|
||||
use crate::types::FootnoteDefinition;
|
||||
use crate::types::FootnoteReference;
|
||||
use crate::types::FootnoteReferenceType;
|
||||
use crate::types::GetStandardProperties;
|
||||
use crate::types::Heading;
|
||||
use crate::types::HorizontalRule;
|
||||
use crate::types::Hour;
|
||||
@@ -82,7 +75,6 @@ use crate::types::PlainListItem;
|
||||
use crate::types::PlainListType;
|
||||
use crate::types::PlainText;
|
||||
use crate::types::Planning;
|
||||
use crate::types::PriorityCookie;
|
||||
use crate::types::PropertyDrawer;
|
||||
use crate::types::QuoteBlock;
|
||||
use crate::types::RadioLink;
|
||||
@@ -113,6 +105,12 @@ use crate::types::Verbatim;
|
||||
use crate::types::VerseBlock;
|
||||
use crate::types::WarningDelayType;
|
||||
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)]
|
||||
pub enum DiffEntry<'b, 's> {
|
||||
@@ -131,7 +129,7 @@ pub struct DiffResult<'b, 's> {
|
||||
emacs_token: &'b Token<'s>,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
#[derive(Debug)]
|
||||
pub(crate) enum DiffStatus {
|
||||
Good,
|
||||
Bad,
|
||||
@@ -167,7 +165,7 @@ impl<'b, 's> DiffEntry<'b, 's> {
|
||||
|
||||
fn is_immediately_bad(&self) -> bool {
|
||||
match self {
|
||||
DiffEntry::DiffResult(diff) => diff.status == DiffStatus::Bad,
|
||||
DiffEntry::DiffResult(diff) => matches!(diff.status, DiffStatus::Bad),
|
||||
DiffEntry::DiffLayer(_) => false,
|
||||
}
|
||||
}
|
||||
@@ -204,21 +202,21 @@ impl<'b, 's> DiffResult<'b, 's> {
|
||||
if self.has_bad_children() {
|
||||
format!(
|
||||
"{color}BADCHILD{reset}",
|
||||
color = DiffResult::foreground_color(255, 255, 0),
|
||||
reset = DiffResult::reset_color(),
|
||||
color = foreground_color(255, 255, 0),
|
||||
reset = reset_color(),
|
||||
)
|
||||
} else {
|
||||
format!(
|
||||
"{color}GOOD{reset}",
|
||||
color = DiffResult::foreground_color(0, 255, 0),
|
||||
reset = DiffResult::reset_color(),
|
||||
color = foreground_color(0, 255, 0),
|
||||
reset = reset_color(),
|
||||
)
|
||||
}
|
||||
}
|
||||
DiffStatus::Bad => format!(
|
||||
"{color}BAD{reset}",
|
||||
color = DiffResult::foreground_color(255, 0, 0),
|
||||
reset = DiffResult::reset_color(),
|
||||
color = foreground_color(255, 0, 0),
|
||||
reset = reset_color(),
|
||||
),
|
||||
}
|
||||
};
|
||||
@@ -230,7 +228,7 @@ impl<'b, 's> DiffResult<'b, 's> {
|
||||
status_text = status_text,
|
||||
name = self.name,
|
||||
char_offset = preceding_text.chars().count() + 1,
|
||||
message = self.message.as_ref().map(|m| m.as_str()).unwrap_or("")
|
||||
message = self.message.as_deref().unwrap_or("")
|
||||
);
|
||||
for child in self.children.iter() {
|
||||
child.print_indented(indentation + 1, original_document)?;
|
||||
@@ -243,45 +241,6 @@ impl<'b, 's> DiffResult<'b, 's> {
|
||||
.iter()
|
||||
.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> {
|
||||
@@ -299,14 +258,14 @@ impl<'b, 's> DiffLayer<'b, 's> {
|
||||
let status_text = if self.has_bad_children() {
|
||||
format!(
|
||||
"{color}BADCHILD{reset}",
|
||||
color = DiffResult::foreground_color(255, 255, 0),
|
||||
reset = DiffResult::reset_color(),
|
||||
color = foreground_color(255, 255, 0),
|
||||
reset = reset_color(),
|
||||
)
|
||||
} else {
|
||||
format!(
|
||||
"{color}GOOD{reset}",
|
||||
color = DiffResult::foreground_color(0, 255, 0),
|
||||
reset = DiffResult::reset_color(),
|
||||
color = foreground_color(0, 255, 0),
|
||||
reset = reset_color(),
|
||||
)
|
||||
};
|
||||
println!(
|
||||
@@ -333,6 +292,17 @@ pub(crate) fn artificial_diff_scope<'b, 's>(
|
||||
.into())
|
||||
}
|
||||
|
||||
pub(crate) fn artificial_owned_diff_scope<'b, 's>(
|
||||
name: &str,
|
||||
children: Vec<DiffEntry<'b, 's>>,
|
||||
) -> Result<DiffEntry<'b, 's>, Box<dyn std::error::Error>> {
|
||||
Ok(DiffLayer {
|
||||
name: name.to_string().into(),
|
||||
children,
|
||||
}
|
||||
.into())
|
||||
}
|
||||
|
||||
pub(crate) fn compare_ast_node<'b, 's>(
|
||||
source: &'s str,
|
||||
emacs: &'b Token<'s>,
|
||||
@@ -405,7 +375,7 @@ pub(crate) fn compare_ast_node<'b, 's>(
|
||||
name: rust.get_elisp_fact().get_elisp_name(),
|
||||
message: Some(e.to_string()),
|
||||
children: Vec::new(),
|
||||
rust_source: rust.get_standard_properties().get_source(),
|
||||
rust_source: rust.get_source(),
|
||||
emacs_token: emacs,
|
||||
}
|
||||
.into()
|
||||
@@ -418,14 +388,9 @@ pub(crate) fn compare_ast_node<'b, 's>(
|
||||
|
||||
// PlainText is a special case because upstream Org-Mode uses relative values for the bounds in plaintext rather than absolute so the below checks do not account for that.
|
||||
if let AstNode::PlainText(_) = rust {
|
||||
} else {
|
||||
match compare_standard_properties(source, emacs, &rust) {
|
||||
Err(err) => {
|
||||
compare_result.status = DiffStatus::Bad;
|
||||
compare_result.message = Some(err.to_string())
|
||||
}
|
||||
Ok(_) => {}
|
||||
}
|
||||
} else if let Err(err) = compare_standard_properties(source, emacs, &rust) {
|
||||
compare_result.status = DiffStatus::Bad;
|
||||
compare_result.message = Some(err.to_string())
|
||||
}
|
||||
|
||||
Ok(compare_result.into())
|
||||
@@ -447,6 +412,27 @@ fn _compare_document<'b, 's>(
|
||||
let mut child_status = Vec::new();
|
||||
let mut message = None;
|
||||
|
||||
let additional_property_names: Vec<String> = rust
|
||||
.get_additional_properties()
|
||||
.map(|node_property| format!(":{}", node_property.property_name.to_uppercase()))
|
||||
.collect();
|
||||
|
||||
let additional_properties: Vec<(String, &str)> = rust
|
||||
.get_additional_properties()
|
||||
.map(|node_property| {
|
||||
(
|
||||
format!(":{}", node_property.property_name.to_uppercase()),
|
||||
node_property.value.unwrap_or(""),
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
|
||||
compare_additional_properties(emacs, additional_properties.into_iter())?.apply(
|
||||
&mut child_status,
|
||||
&mut this_status,
|
||||
&mut message,
|
||||
);
|
||||
|
||||
compare_children_iter(
|
||||
source,
|
||||
emacs,
|
||||
@@ -460,9 +446,13 @@ fn _compare_document<'b, 's>(
|
||||
source,
|
||||
emacs,
|
||||
rust,
|
||||
additional_property_names
|
||||
.iter()
|
||||
.map(String::as_str)
|
||||
.map(EmacsField::Required),
|
||||
(
|
||||
EmacsField::Required(":path"),
|
||||
|r| r.path.as_ref().map(|p| p.to_str()).flatten(),
|
||||
|r| r.path.as_ref().and_then(|p| p.to_str()),
|
||||
compare_property_quoted_string
|
||||
),
|
||||
(
|
||||
@@ -533,7 +523,7 @@ fn compare_section<'b, 's>(
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn new_compare_heading<'b, 's>(
|
||||
fn compare_heading<'b, 's>(
|
||||
source: &'s str,
|
||||
emacs: &'b Token<'s>,
|
||||
rust: &'b Heading<'s>,
|
||||
@@ -542,7 +532,26 @@ fn new_compare_heading<'b, 's>(
|
||||
let mut child_status = Vec::new();
|
||||
let mut message = None;
|
||||
|
||||
// TODO: This needs to support additional properties from the property drawer
|
||||
let additional_property_names: Vec<String> = rust
|
||||
.get_additional_properties()
|
||||
.map(|node_property| format!(":{}", node_property.property_name.to_uppercase()))
|
||||
.collect();
|
||||
|
||||
let additional_properties: Vec<(String, &str)> = rust
|
||||
.get_additional_properties()
|
||||
.map(|node_property| {
|
||||
(
|
||||
format!(":{}", node_property.property_name.to_uppercase()),
|
||||
node_property.value.unwrap_or(""),
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
|
||||
compare_additional_properties(emacs, additional_properties.into_iter())?.apply(
|
||||
&mut child_status,
|
||||
&mut this_status,
|
||||
&mut message,
|
||||
);
|
||||
|
||||
compare_children(
|
||||
source,
|
||||
@@ -557,6 +566,10 @@ fn new_compare_heading<'b, 's>(
|
||||
source,
|
||||
emacs,
|
||||
rust,
|
||||
additional_property_names
|
||||
.iter()
|
||||
.map(String::as_str)
|
||||
.map(EmacsField::Required),
|
||||
(
|
||||
EmacsField::Required(":level"),
|
||||
|r| Some(r.level),
|
||||
@@ -664,278 +677,6 @@ fn new_compare_heading<'b, 's>(
|
||||
.into())
|
||||
}
|
||||
|
||||
fn compare_heading<'b, 's>(
|
||||
source: &'s str,
|
||||
emacs: &'b Token<'s>,
|
||||
rust: &'b Heading<'s>,
|
||||
) -> Result<DiffEntry<'b, 's>, Box<dyn std::error::Error>> {
|
||||
let children = emacs.as_list()?;
|
||||
let mut child_status = Vec::new();
|
||||
let mut this_status = DiffStatus::Good;
|
||||
let mut message = None;
|
||||
|
||||
// Compare level
|
||||
let level = get_property(emacs, ":level")?
|
||||
.ok_or("Level should not be nil")?
|
||||
.as_atom()?;
|
||||
if rust.level.to_string() != level {
|
||||
this_status = DiffStatus::Bad;
|
||||
message = Some(format!(
|
||||
"Headline level do not match (emacs != rust): {} != {}",
|
||||
level, rust.level
|
||||
))
|
||||
}
|
||||
|
||||
// Compare tags
|
||||
let emacs_tags = get_tags_from_heading(emacs)?;
|
||||
let emacs_tags: HashSet<_> = emacs_tags.iter().map(|val| val.as_str()).collect();
|
||||
let rust_tags: HashSet<&str> = rust.tags.iter().map(|val| *val).collect();
|
||||
let difference: Vec<&str> = emacs_tags
|
||||
.symmetric_difference(&rust_tags)
|
||||
.map(|val| *val)
|
||||
.collect();
|
||||
if !difference.is_empty() {
|
||||
this_status = DiffStatus::Bad;
|
||||
message = Some(format!("Mismatched tags: {}", difference.join(", ")));
|
||||
}
|
||||
|
||||
// Compare todo-keyword
|
||||
let todo_keyword = get_property(emacs, ":todo-keyword")?
|
||||
.map(Token::as_atom)
|
||||
.map_or(Ok(None), |r| r.map(Some))?
|
||||
.unwrap_or("nil");
|
||||
match (todo_keyword, &rust.todo_keyword, unquote(todo_keyword)) {
|
||||
("nil", None, _) => {}
|
||||
(_, Some((_rust_todo_type, rust_todo)), Ok(emacs_todo)) if emacs_todo == *rust_todo => {}
|
||||
(emacs_todo, rust_todo, _) => {
|
||||
this_status = DiffStatus::Bad;
|
||||
message = Some(format!(
|
||||
"(emacs != rust) {:?} != {:?}",
|
||||
emacs_todo, rust_todo
|
||||
));
|
||||
}
|
||||
};
|
||||
// Compare todo-type
|
||||
let todo_type = get_property(emacs, ":todo-type")?
|
||||
.map(Token::as_atom)
|
||||
.map_or(Ok(None), |r| r.map(Some))?
|
||||
.unwrap_or("nil");
|
||||
// todo-type is an unquoted string either todo, done, or nil
|
||||
match (todo_type, &rust.todo_keyword) {
|
||||
("nil", None) => {}
|
||||
("todo", Some((TodoKeywordType::Todo, _))) => {}
|
||||
("done", Some((TodoKeywordType::Done, _))) => {}
|
||||
(emacs_todo, rust_todo) => {
|
||||
this_status = DiffStatus::Bad;
|
||||
message = Some(format!(
|
||||
"(emacs != rust) {:?} != {:?}",
|
||||
emacs_todo, rust_todo
|
||||
));
|
||||
}
|
||||
};
|
||||
|
||||
// Compare title
|
||||
let title = get_property(emacs, ":title")?;
|
||||
match (title, rust.title.len()) {
|
||||
(None, 0) => {}
|
||||
(None, _) => {
|
||||
this_status = DiffStatus::Bad;
|
||||
message = Some(format!(
|
||||
"Titles do not match (emacs != rust): {:?} != {:?}",
|
||||
title, rust.title
|
||||
))
|
||||
}
|
||||
(Some(title), _) => {
|
||||
let title_status = title
|
||||
.as_list()?
|
||||
.iter()
|
||||
.zip(rust.title.iter())
|
||||
.map(|(emacs_child, rust_child)| {
|
||||
compare_ast_node(source, emacs_child, rust_child.into())
|
||||
})
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
child_status.push(artificial_diff_scope("title", title_status)?);
|
||||
}
|
||||
};
|
||||
|
||||
// Compare priority
|
||||
let priority = get_property(emacs, ":priority")?;
|
||||
match (priority, rust.priority_cookie) {
|
||||
(None, None) => {}
|
||||
(None, Some(_)) | (Some(_), None) => {
|
||||
this_status = DiffStatus::Bad;
|
||||
message = Some(format!(
|
||||
"Priority cookie mismatch (emacs != rust) {:?} != {:?}",
|
||||
priority, rust.priority_cookie
|
||||
));
|
||||
}
|
||||
(Some(emacs_priority_cookie), Some(rust_priority_cookie)) => {
|
||||
let emacs_priority_cookie =
|
||||
emacs_priority_cookie.as_atom()?.parse::<PriorityCookie>()?;
|
||||
if emacs_priority_cookie != rust_priority_cookie {
|
||||
this_status = DiffStatus::Bad;
|
||||
message = Some(format!(
|
||||
"Priority cookie mismatch (emacs != rust) {:?} != {:?}",
|
||||
emacs_priority_cookie, rust_priority_cookie
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Compare archived
|
||||
let archived = get_property(emacs, ":archivedp")?;
|
||||
match (archived, rust.is_archived) {
|
||||
(None, true) | (Some(_), false) => {
|
||||
this_status = DiffStatus::Bad;
|
||||
message = Some(format!(
|
||||
"archived mismatch (emacs != rust) {:?} != {:?}",
|
||||
archived, rust.is_archived
|
||||
));
|
||||
}
|
||||
(None, false) | (Some(_), true) => {}
|
||||
}
|
||||
|
||||
// Compare commented
|
||||
let commented = get_property(emacs, ":commentedp")?;
|
||||
match (commented, rust.is_comment) {
|
||||
(None, true) | (Some(_), false) => {
|
||||
this_status = DiffStatus::Bad;
|
||||
message = Some(format!(
|
||||
"commented mismatch (emacs != rust) {:?} != {:?}",
|
||||
commented, rust.is_comment
|
||||
));
|
||||
}
|
||||
(None, false) | (Some(_), true) => {}
|
||||
}
|
||||
|
||||
// Compare raw-value
|
||||
let raw_value = get_property_quoted_string(emacs, ":raw-value")?
|
||||
.ok_or("Headlines should have :raw-value.")?;
|
||||
let rust_raw_value = rust.get_raw_value();
|
||||
if raw_value != rust_raw_value {
|
||||
this_status = DiffStatus::Bad;
|
||||
message = Some(format!(
|
||||
"raw-value mismatch (emacs != rust) {:?} != {:?}",
|
||||
raw_value, rust_raw_value
|
||||
));
|
||||
}
|
||||
|
||||
// Compare footnote-section-p
|
||||
let footnote_section = get_property_boolean(emacs, ":footnote-section-p")?;
|
||||
if footnote_section != rust.is_footnote_section {
|
||||
this_status = DiffStatus::Bad;
|
||||
message = Some(format!(
|
||||
"footnote section mismatch (emacs != rust) {:?} != {:?}",
|
||||
footnote_section, rust.is_footnote_section
|
||||
));
|
||||
}
|
||||
|
||||
// Compare scheduled
|
||||
let scheduled = get_property(emacs, ":scheduled")?;
|
||||
match (scheduled, &rust.scheduled) {
|
||||
(None, None) => {}
|
||||
(None, Some(_)) | (Some(_), None) => {
|
||||
this_status = DiffStatus::Bad;
|
||||
message = Some(format!(
|
||||
"Scheduled mismatch (emacs != rust) {:?} != {:?}",
|
||||
scheduled, rust.scheduled
|
||||
));
|
||||
}
|
||||
(Some(emacs_child), Some(rust_child)) => {
|
||||
let result = compare_ast_node(source, emacs_child, rust_child.into())?;
|
||||
child_status.push(artificial_diff_scope("scheduled", vec![result])?);
|
||||
}
|
||||
}
|
||||
|
||||
// Compare deadline
|
||||
let deadline = get_property(emacs, ":deadline")?;
|
||||
match (deadline, &rust.deadline) {
|
||||
(None, None) => {}
|
||||
(None, Some(_)) | (Some(_), None) => {
|
||||
this_status = DiffStatus::Bad;
|
||||
message = Some(format!(
|
||||
"Deadline mismatch (emacs != rust) {:?} != {:?}",
|
||||
deadline, rust.deadline
|
||||
));
|
||||
}
|
||||
(Some(emacs_child), Some(rust_child)) => {
|
||||
let result = compare_ast_node(source, emacs_child, rust_child.into())?;
|
||||
child_status.push(artificial_diff_scope("deadline", vec![result])?);
|
||||
}
|
||||
}
|
||||
|
||||
// Compare closed
|
||||
let closed = get_property(emacs, ":closed")?;
|
||||
match (closed, &rust.closed) {
|
||||
(None, None) => {}
|
||||
(None, Some(_)) | (Some(_), None) => {
|
||||
this_status = DiffStatus::Bad;
|
||||
message = Some(format!(
|
||||
"Closed mismatch (emacs != rust) {:?} != {:?}",
|
||||
closed, rust.closed
|
||||
));
|
||||
}
|
||||
(Some(emacs_child), Some(rust_child)) => {
|
||||
let result = compare_ast_node(source, emacs_child, rust_child.into())?;
|
||||
child_status.push(artificial_diff_scope("closed", vec![result])?);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Compare :pre-blank
|
||||
|
||||
// Compare section
|
||||
let section_status = children
|
||||
.iter()
|
||||
.skip(2)
|
||||
.zip(rust.children.iter())
|
||||
.map(|(emacs_child, rust_child)| match rust_child {
|
||||
DocumentElement::Heading(rust_heading) => {
|
||||
compare_ast_node(source, emacs_child, rust_heading.into())
|
||||
}
|
||||
DocumentElement::Section(rust_section) => {
|
||||
compare_ast_node(source, emacs_child, rust_section.into())
|
||||
}
|
||||
})
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
child_status.push(artificial_diff_scope("section", section_status)?);
|
||||
|
||||
Ok(DiffResult {
|
||||
status: this_status,
|
||||
name: rust.get_elisp_name(),
|
||||
message,
|
||||
children: child_status,
|
||||
rust_source: rust.get_source(),
|
||||
emacs_token: emacs,
|
||||
}
|
||||
.into())
|
||||
}
|
||||
|
||||
fn get_tags_from_heading<'b, 's>(
|
||||
emacs: &'b Token<'s>,
|
||||
) -> Result<HashSet<String>, Box<dyn std::error::Error>> {
|
||||
let tags = match get_property(emacs, ":tags")? {
|
||||
Some(prop) => prop,
|
||||
None => return Ok(HashSet::new()),
|
||||
};
|
||||
|
||||
match tags.as_atom() {
|
||||
Ok(val) => panic!("Unexpected value for tags: {:?}", val),
|
||||
Err(_) => {}
|
||||
};
|
||||
let tags = {
|
||||
let tags = tags.as_list()?;
|
||||
let strings = tags
|
||||
.iter()
|
||||
.map(Token::as_atom)
|
||||
.collect::<Result<Vec<&str>, _>>()?;
|
||||
strings
|
||||
.into_iter()
|
||||
.map(unquote)
|
||||
.collect::<Result<HashSet<String>, _>>()?
|
||||
};
|
||||
Ok(tags)
|
||||
}
|
||||
|
||||
fn compare_paragraph<'b, 's>(
|
||||
source: &'s str,
|
||||
emacs: &'b Token<'s>,
|
||||
@@ -954,21 +695,7 @@ fn compare_paragraph<'b, 's>(
|
||||
&mut message,
|
||||
)?;
|
||||
|
||||
for diff in compare_properties!(
|
||||
source,
|
||||
emacs,
|
||||
rust,
|
||||
(
|
||||
EmacsField::Optional(":name"),
|
||||
|r| r.name,
|
||||
compare_property_quoted_string
|
||||
),
|
||||
(
|
||||
EmacsField::Optional(":caption"),
|
||||
compare_identity,
|
||||
compare_noop
|
||||
)
|
||||
) {
|
||||
for diff in compare_properties!(source, emacs, rust, [],) {
|
||||
match diff {
|
||||
ComparePropertiesResult::NoChange => {}
|
||||
ComparePropertiesResult::SelfChange(new_status, new_message) => {
|
||||
@@ -1012,16 +739,7 @@ fn compare_plain_list<'b, 's>(
|
||||
source,
|
||||
emacs,
|
||||
rust,
|
||||
(
|
||||
EmacsField::Optional(":name"),
|
||||
|r| r.name,
|
||||
compare_property_quoted_string
|
||||
),
|
||||
(
|
||||
EmacsField::Optional(":caption"),
|
||||
compare_identity,
|
||||
compare_noop
|
||||
),
|
||||
[],
|
||||
(
|
||||
EmacsField::Required(":type"),
|
||||
|r| Some(match r.list_type {
|
||||
@@ -1139,24 +857,28 @@ fn compare_center_block<'b, 's>(
|
||||
emacs: &'b Token<'s>,
|
||||
rust: &'b CenterBlock<'s>,
|
||||
) -> Result<DiffEntry<'b, 's>, Box<dyn std::error::Error>> {
|
||||
let children = emacs.as_list()?;
|
||||
let mut child_status = Vec::new();
|
||||
let mut this_status = DiffStatus::Good;
|
||||
let mut child_status = Vec::new();
|
||||
let mut message = None;
|
||||
|
||||
// TODO: Compare :caption
|
||||
// Compare name
|
||||
let name = get_property_quoted_string(emacs, ":name")?;
|
||||
if name.as_ref().map(String::as_str) != rust.name {
|
||||
this_status = DiffStatus::Bad;
|
||||
message = Some(format!(
|
||||
"Name mismatch (emacs != rust) {:?} != {:?}",
|
||||
name, rust.name
|
||||
));
|
||||
}
|
||||
compare_children(
|
||||
source,
|
||||
emacs,
|
||||
&rust.children,
|
||||
&mut child_status,
|
||||
&mut this_status,
|
||||
&mut message,
|
||||
)?;
|
||||
|
||||
for (emacs_child, rust_child) in children.iter().skip(2).zip(rust.children.iter()) {
|
||||
child_status.push(compare_ast_node(source, emacs_child, rust_child.into())?);
|
||||
for diff in compare_properties!(source, emacs, rust, [],) {
|
||||
match diff {
|
||||
ComparePropertiesResult::NoChange => {}
|
||||
ComparePropertiesResult::SelfChange(new_status, new_message) => {
|
||||
this_status = new_status;
|
||||
message = new_message
|
||||
}
|
||||
ComparePropertiesResult::DiffEntry(diff_entry) => child_status.push(diff_entry),
|
||||
}
|
||||
}
|
||||
|
||||
Ok(DiffResult {
|
||||
@@ -1188,21 +910,7 @@ fn compare_quote_block<'b, 's>(
|
||||
&mut message,
|
||||
)?;
|
||||
|
||||
for diff in compare_properties!(
|
||||
source,
|
||||
emacs,
|
||||
rust,
|
||||
(
|
||||
EmacsField::Optional(":name"),
|
||||
|r| r.name,
|
||||
compare_property_quoted_string
|
||||
),
|
||||
(
|
||||
EmacsField::Optional(":caption"),
|
||||
compare_identity,
|
||||
compare_noop
|
||||
)
|
||||
) {
|
||||
for diff in compare_properties!(source, emacs, rust, [],) {
|
||||
match diff {
|
||||
ComparePropertiesResult::NoChange => {}
|
||||
ComparePropertiesResult::SelfChange(new_status, new_message) => {
|
||||
@@ -1246,16 +954,7 @@ fn compare_special_block<'b, 's>(
|
||||
source,
|
||||
emacs,
|
||||
rust,
|
||||
(
|
||||
EmacsField::Optional(":name"),
|
||||
|r| r.name,
|
||||
compare_property_quoted_string
|
||||
),
|
||||
(
|
||||
EmacsField::Optional(":caption"),
|
||||
compare_identity,
|
||||
compare_noop
|
||||
),
|
||||
[],
|
||||
(
|
||||
EmacsField::Required(":type"),
|
||||
|r| Some(r.block_type),
|
||||
@@ -1315,16 +1014,7 @@ fn compare_dynamic_block<'b, 's>(
|
||||
source,
|
||||
emacs,
|
||||
rust,
|
||||
(
|
||||
EmacsField::Optional(":name"),
|
||||
|r| r.name,
|
||||
compare_property_quoted_string
|
||||
),
|
||||
(
|
||||
EmacsField::Optional(":caption"),
|
||||
compare_identity,
|
||||
compare_noop
|
||||
),
|
||||
[],
|
||||
(
|
||||
EmacsField::Required(":block-name"),
|
||||
|r| Some(r.block_name),
|
||||
@@ -1379,16 +1069,7 @@ fn compare_footnote_definition<'b, 's>(
|
||||
source,
|
||||
emacs,
|
||||
rust,
|
||||
(
|
||||
EmacsField::Optional(":name"),
|
||||
|r| r.name,
|
||||
compare_property_quoted_string
|
||||
),
|
||||
(
|
||||
EmacsField::Optional(":caption"),
|
||||
compare_identity,
|
||||
compare_noop
|
||||
),
|
||||
[],
|
||||
(
|
||||
EmacsField::Required(":label"),
|
||||
|r| Some(r.label),
|
||||
@@ -1485,16 +1166,7 @@ fn compare_drawer<'b, 's>(
|
||||
source,
|
||||
emacs,
|
||||
rust,
|
||||
(
|
||||
EmacsField::Optional(":name"),
|
||||
|r| r.name,
|
||||
compare_property_quoted_string
|
||||
),
|
||||
(
|
||||
EmacsField::Optional(":caption"),
|
||||
compare_identity,
|
||||
compare_noop
|
||||
),
|
||||
[],
|
||||
(
|
||||
EmacsField::Required(":drawer-name"),
|
||||
|r| Some(r.drawer_name),
|
||||
@@ -1631,16 +1303,7 @@ fn compare_table<'b, 's>(
|
||||
source,
|
||||
emacs,
|
||||
rust,
|
||||
(
|
||||
EmacsField::Optional(":name"),
|
||||
|r| r.name,
|
||||
compare_property_quoted_string
|
||||
),
|
||||
(
|
||||
EmacsField::Optional(":caption"),
|
||||
compare_identity,
|
||||
compare_noop
|
||||
),
|
||||
[],
|
||||
(
|
||||
EmacsField::Required(":tblfm"),
|
||||
|r| if r.formulas.is_empty() {
|
||||
@@ -1792,21 +1455,7 @@ fn compare_verse_block<'b, 's>(
|
||||
&mut message,
|
||||
)?;
|
||||
|
||||
for diff in compare_properties!(
|
||||
source,
|
||||
emacs,
|
||||
rust,
|
||||
(
|
||||
EmacsField::Optional(":name"),
|
||||
|r| r.name,
|
||||
compare_property_quoted_string
|
||||
),
|
||||
(
|
||||
EmacsField::Optional(":caption"),
|
||||
compare_identity,
|
||||
compare_noop
|
||||
)
|
||||
) {
|
||||
for diff in compare_properties!(source, emacs, rust, [],) {
|
||||
match diff {
|
||||
ComparePropertiesResult::NoChange => {}
|
||||
ComparePropertiesResult::SelfChange(new_status, new_message) => {
|
||||
@@ -1843,16 +1492,7 @@ fn compare_comment_block<'b, 's>(
|
||||
source,
|
||||
emacs,
|
||||
rust,
|
||||
(
|
||||
EmacsField::Optional(":name"),
|
||||
|r| r.name,
|
||||
compare_property_quoted_string
|
||||
),
|
||||
(
|
||||
EmacsField::Optional(":caption"),
|
||||
compare_identity,
|
||||
compare_noop
|
||||
),
|
||||
[],
|
||||
(
|
||||
EmacsField::Required(":value"),
|
||||
|r| Some(r.contents),
|
||||
@@ -1895,19 +1535,10 @@ fn compare_example_block<'b, 's>(
|
||||
source,
|
||||
emacs,
|
||||
rust,
|
||||
(
|
||||
EmacsField::Optional(":name"),
|
||||
|r| r.name,
|
||||
compare_property_quoted_string
|
||||
),
|
||||
(
|
||||
EmacsField::Optional(":caption"),
|
||||
compare_identity,
|
||||
compare_noop
|
||||
),
|
||||
[],
|
||||
(
|
||||
EmacsField::Required(":value"),
|
||||
|r| Some(r.contents.as_str()),
|
||||
|r| Some(r.get_value()),
|
||||
compare_property_quoted_string
|
||||
),
|
||||
(
|
||||
@@ -1977,16 +1608,7 @@ fn compare_export_block<'b, 's>(
|
||||
source,
|
||||
emacs,
|
||||
rust,
|
||||
(
|
||||
EmacsField::Optional(":name"),
|
||||
|r| r.name,
|
||||
compare_property_quoted_string
|
||||
),
|
||||
(
|
||||
EmacsField::Optional(":caption"),
|
||||
compare_identity,
|
||||
compare_noop
|
||||
),
|
||||
[],
|
||||
(
|
||||
EmacsField::Required(":type"),
|
||||
|r| r.get_export_type(),
|
||||
@@ -1994,7 +1616,7 @@ fn compare_export_block<'b, 's>(
|
||||
),
|
||||
(
|
||||
EmacsField::Required(":value"),
|
||||
|r| Some(r.contents.as_str()),
|
||||
|r| Some(r.get_value()),
|
||||
compare_property_quoted_string
|
||||
)
|
||||
) {
|
||||
@@ -2034,16 +1656,7 @@ fn compare_src_block<'b, 's>(
|
||||
source,
|
||||
emacs,
|
||||
rust,
|
||||
(
|
||||
EmacsField::Optional(":name"),
|
||||
|r| r.name,
|
||||
compare_property_quoted_string
|
||||
),
|
||||
(
|
||||
EmacsField::Optional(":caption"),
|
||||
compare_identity,
|
||||
compare_noop
|
||||
),
|
||||
[],
|
||||
(
|
||||
EmacsField::Required(":language"),
|
||||
|r| r.language,
|
||||
@@ -2051,7 +1664,7 @@ fn compare_src_block<'b, 's>(
|
||||
),
|
||||
(
|
||||
EmacsField::Required(":value"),
|
||||
|r| Some(r.contents.as_str()),
|
||||
|r| Some(r.get_value()),
|
||||
compare_property_quoted_string
|
||||
),
|
||||
(
|
||||
@@ -2181,16 +1794,7 @@ fn compare_diary_sexp<'b, 's>(
|
||||
source,
|
||||
emacs,
|
||||
rust,
|
||||
(
|
||||
EmacsField::Optional(":name"),
|
||||
|r| r.name,
|
||||
compare_property_quoted_string
|
||||
),
|
||||
(
|
||||
EmacsField::Optional(":caption"),
|
||||
compare_identity,
|
||||
compare_noop
|
||||
),
|
||||
[],
|
||||
(
|
||||
EmacsField::Required(":value"),
|
||||
|r| Some(r.value),
|
||||
@@ -2285,16 +1889,7 @@ fn compare_fixed_width_area<'b, 's>(
|
||||
source,
|
||||
emacs,
|
||||
rust,
|
||||
(
|
||||
EmacsField::Optional(":name"),
|
||||
|r| r.name,
|
||||
compare_property_quoted_string
|
||||
),
|
||||
(
|
||||
EmacsField::Optional(":caption"),
|
||||
compare_identity,
|
||||
compare_noop
|
||||
),
|
||||
[],
|
||||
(
|
||||
EmacsField::Required(":value"),
|
||||
|r| Some(r.get_value()),
|
||||
@@ -2333,21 +1928,7 @@ fn compare_horizontal_rule<'b, 's>(
|
||||
|
||||
assert_no_children(emacs, &mut this_status, &mut message)?;
|
||||
|
||||
for diff in compare_properties!(
|
||||
source,
|
||||
emacs,
|
||||
rust,
|
||||
(
|
||||
EmacsField::Optional(":name"),
|
||||
|r| r.name,
|
||||
compare_property_quoted_string
|
||||
),
|
||||
(
|
||||
EmacsField::Optional(":caption"),
|
||||
compare_identity,
|
||||
compare_noop
|
||||
)
|
||||
) {
|
||||
for diff in compare_properties!(source, emacs, rust, [],) {
|
||||
match diff {
|
||||
ComparePropertiesResult::NoChange => {}
|
||||
ComparePropertiesResult::SelfChange(new_status, new_message) => {
|
||||
@@ -2384,16 +1965,7 @@ fn compare_keyword<'b, 's>(
|
||||
source,
|
||||
emacs,
|
||||
rust,
|
||||
(
|
||||
EmacsField::Optional(":name"),
|
||||
|r| r.name,
|
||||
compare_property_quoted_string
|
||||
),
|
||||
(
|
||||
EmacsField::Optional(":caption"),
|
||||
compare_identity,
|
||||
compare_noop
|
||||
),
|
||||
[],
|
||||
(
|
||||
EmacsField::Required(":key"),
|
||||
|r| Some(r.key.to_uppercase()),
|
||||
@@ -2441,16 +2013,7 @@ fn compare_babel_call<'b, 's>(
|
||||
source,
|
||||
emacs,
|
||||
rust,
|
||||
(
|
||||
EmacsField::Optional(":name"),
|
||||
|r| r.name,
|
||||
compare_property_quoted_string
|
||||
),
|
||||
(
|
||||
EmacsField::Optional(":caption"),
|
||||
compare_identity,
|
||||
compare_noop
|
||||
),
|
||||
[],
|
||||
(
|
||||
EmacsField::Required(":value"),
|
||||
|r| Some(r.value),
|
||||
@@ -2513,16 +2076,7 @@ fn compare_latex_environment<'b, 's>(
|
||||
source,
|
||||
emacs,
|
||||
rust,
|
||||
(
|
||||
EmacsField::Optional(":name"),
|
||||
|r| r.name,
|
||||
compare_property_quoted_string
|
||||
),
|
||||
(
|
||||
EmacsField::Optional(":caption"),
|
||||
compare_identity,
|
||||
compare_noop
|
||||
),
|
||||
[],
|
||||
(
|
||||
EmacsField::Required(":value"),
|
||||
|r| Some(r.value),
|
||||
@@ -2561,7 +2115,7 @@ fn compare_plain_text<'b, 's>(
|
||||
let text = emacs.as_text()?;
|
||||
let start_ind: usize = text
|
||||
.properties
|
||||
.get(0)
|
||||
.first()
|
||||
.expect("Should have start index.")
|
||||
.as_atom()?
|
||||
.parse()?;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user