Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/build/*
*.log
139 changes: 139 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
# Makefile for tests for tools/scripts in docs-resources repository.
# Must be run in top-level directory of docs-resources repository.
#
# This work is licensed under the Creative Commons Attribution-ShareAlike 4.0
# International License. To view a copy of this license, visit
# http://creativecommons.org/licenses/by-sa/4.0/ or send a letter to
# Creative Commons, PO Box 1866, Mountain View, CA 94042, USA.
#
# SPDX-License-Identifier: CC-BY-SA-4.0
#
# This Makefile is designed to automate the process of running tests.
# Running with a preinstalled docker container is strongly recommended.
# Install by running:
# docker pull riscvintl/riscv-docs-base-container-image:latest

# Directories all relative to the top-level.
CONVERTERS_DIR := converters
TOOLS_DIR := tools
BUILD_DIR := build
TESTS_DIR := tests
NORM_RULE_TESTS_DIR := $(TESTS_DIR)/norm-rule
NORM_RULE_DEF_DIR := $(NORM_RULE_TESTS_DIR)
NORM_RULE_EXPECTED_DIR := $(NORM_RULE_TESTS_DIR)/expected

# Ruby scripts being tested.
TAGS_BACKEND := tags.rb
CREATE_NORM_RULE_TOOL := create_normative_rules.rb

# Input and output file names
TEST_ADOC_INPUT_FNAME := test.adoc
NORM_TAGS_OUTPUT_FNAME := test-norm-tags.json
NORM_RULE_OUTPUT_FNAME := test-norm-rules.json

# Built output files
BUILT_NORM_TAGS := $(BUILD_DIR)/$(NORM_TAGS_OUTPUT_FNAME)
BUILT_NORM_RULES := $(BUILD_DIR)/$(NORM_RULE_OUTPUT_FNAME)

# Copies of expected output files.
# Use make target "update-expected" to update from build dir contents.
EXPECTED_NORM_TAGS := $(NORM_RULE_EXPECTED_DIR)/$(NORM_TAGS_OUTPUT_FNAME)
EXPECTED_NORM_RULES := $(NORM_RULE_EXPECTED_DIR)/$(NORM_RULE_OUTPUT_FNAME)

DOCKER_BIN ?= docker
SKIP_DOCKER ?= $(shell if command -v ${DOCKER_BIN} >/dev/null 2>&1 ; then echo false; else echo true; fi)
DOCKER_IMG := riscvintl/riscv-docs-base-container-image:latest
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know if I would bother with the complexity of docker for this. The only reason it's needed in riscv-isa-manual is because setting up Asciidoctor and all the plugins is a right pain, but I think it's probably an acceptable pain for people wanting to run these tests (and CI). Especially because the only requirement is Asciidoctor I think?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I don't need any of the Asciidoctor plugins. Obviously I'm leveraging the docker image and Makefile from the ISA manual. If I don't do this, then as you point out, people will need to have Asciidoctor installed to run the tests. I don't have Asciidoctor installed on my Windows machine (I run this on WSL2 with docker) so that would open a whole new can of worms if I now need to have Asciidoctor installed. So, in summary, I'd like to keep this they way it is since people are already familiar with using the docker image in the ISA manual. Do you agree?

ifneq ($(SKIP_DOCKER),true)
DOCKER_IS_PODMAN = \
$(shell ! ${DOCKER_BIN} -v | grep podman >/dev/null ; echo $$?)
ifeq "$(DOCKER_IS_PODMAN)" "1"
# Modify the SELinux label for the host directory to indicate
# that it can be shared with multiple containers. This is apparently
# only required for Podman, though it is also supported by Docker.
DOCKER_VOL_SUFFIX = :z
DOCKER_EXTRA_VOL_SUFFIX = ,z
else
DOCKER_IS_ROOTLESS = \
$(shell ! ${DOCKER_BIN} info -f '{{println .SecurityOptions}}' | grep rootless >/dev/null ; echo $$?)
ifneq "$(DOCKER_IS_ROOTLESS)" "1"
# Rooted Docker needs this flag so that the files it creates are
# owned by the current user instead of root. Rootless docker does not
# require it, and Podman doesn't either since it is always rootless.
DOCKER_USER_ARG := --user $(shell id -u)
endif
endif

DOCKER_CMD = \
${DOCKER_BIN} run --rm \
-v ${PWD}/$@.workdir:/build${DOCKER_VOL_SUFFIX} \
-v ${PWD}/${CONVERTERS_DIR}:/${CONVERTERS_DIR}:ro${DOCKER_EXTRA_VOL_SUFFIX} \
-v ${PWD}/$(TOOLS_DIR):/$(TOOLS_DIR):ro${DOCKER_EXTRA_VOL_SUFFIX} \
-v ${PWD}/$(TESTS_DIR):/$(TESTS_DIR):ro${DOCKER_EXTRA_VOL_SUFFIX} \
-w /build \
$(DOCKER_USER_ARG) \
${DOCKER_IMG} \
/bin/sh -c
DOCKER_QUOTE := "
else
DOCKER_CMD = \
cd $@.workdir &&
endif

WORKDIR_SETUP = \
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can probably skip this workdir stuff too.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just being "efficient" by leveraging the ISA manual Makefile. Seems to work well so why fix it if it ain't broke?

rm -rf $@.workdir && \
mkdir -p $@.workdir && \
ln -sfn ../../converters ../../tools ../../tests $@.workdir/

WORKDIR_TEARDOWN = \
mv $@.workdir/$@ $@ && \
rm -rf $@.workdir

ASCIIDOCTOR_TAGS := asciidoctor --backend tags --require=./$(CONVERTERS_DIR)/$(TAGS_BACKEND)

OPTIONS := --trace \
-D build \
--failure-level=WARN

.PHONY: all clean tests test-tags test-norm-rules update-expected update-norm-rule-expected

all: tests
tests: test-tags test-norm-rules
test-tags: $(BUILT_NORM_TAGS)
test-norm-rules: $(BUILT_NORM_RULES)
update-expected: update-expected-norm-rule

# All normative rule definition input YAML files tracked under Git (ensure you at least stage new files).
NORM_RULE_DEF_FILES := $(shell git ls-files '$(NORM_RULE_DEF_DIR)/*.yaml')

# Add -t to each normative tag input filename and add prefix of "/" to make into absolute pathname.
NORM_TAG_FILE_ARGS := $(foreach relative_pname,$(BUILT_NORM_TAGS),-t /$(relative_pname))

# Add -d to each normative rule definition filename
NORM_RULE_DEF_ARGS := $(foreach relative_pname,$(NORM_RULE_DEF_FILES),-d $(relative_pname))

update-expected-norm-rule: $(BUILT_NORM_TAGS) $(BUILT_NORM_RULES)
cp -f $(BUILT_NORM_TAGS) $(EXPECTED_NORM_TAGS)
cp -f $(BUILT_NORM_RULES) $(EXPECTED_NORM_RULES)

$(BUILT_NORM_TAGS): $(NORM_RULE_TESTS_DIR)/$(TEST_ADOC_INPUT_FNAME) $(CONVERTERS_DIR)/$(TAGS_BACKEND)
$(WORKDIR_SETUP)
$(DOCKER_CMD) $(DOCKER_QUOTE) $(ASCIIDOCTOR_TAGS) $(OPTIONS) -a tags-match-prefix='norm:' -a tags-output-suffix='-norm-tags.json' $< $(DOCKER_QUOTE)
$(WORKDIR_TEARDOWN)
diff $(EXPECTED_NORM_TAGS) $(BUILT_NORM_TAGS)

$(BUILT_NORM_RULES): $(BUILT_NORM_TAGS) $(NORM_RULE_DEF_FILES)
$(WORKDIR_SETUP)
cp -f $(BUILT_NORM_TAGS) $@.workdir
mkdir -p $@.workdir/build
$(DOCKER_CMD) $(DOCKER_QUOTE) ruby $(TOOLS_DIR)/$(CREATE_NORM_RULE_TOOL) $(NORM_TAG_FILE_ARGS) $(NORM_RULE_DEF_ARGS) $@ $(DOCKER_QUOTE)
$(WORKDIR_TEARDOWN)
diff $(EXPECTED_NORM_RULES) $(BUILT_NORM_RULES)

# Update docker image to latest
docker-pull-latest:
${DOCKER_BIN} pull ${DOCKER_IMG}

clean:
@echo "Cleaning up generated files..."
rm -rf $(BUILD_DIR)
@echo "Cleanup completed."
10 changes: 6 additions & 4 deletions normative-rules.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,14 @@ AsciiDoc supports several styles of anchors:
>
> `This isn't part of the anchor since it is the next paragraph.`

* You must use the _paragraph anchor_ for table cells, list items, or description list terms
* For table cells and list items, put the anchor before its associated text as follows:
* You must use the _paragraph anchor_ for table cells, unordered/ordered list items or description list terms
* For table cells and unordered/ordered list items, put the anchor before its associated text as follows:
* Table cell<br>
> `| [[foo]] Here are the table cell contents | next cell`
* List item<br>
> `* [[foo]] Here is the list item`
* Unordered list item<br>
> `* [[foo]] Here is the unordered list item`
* Ordered list item<br>
> `. [[foo]] Here is the ordered list item`
* For description list terms (e.g., `Apples`, `Oranges`), put the anchor immediately after the term on its own line as follows:
> `Apples::`<br>
> `[[apple-colors]]`<br>
Expand Down
76 changes: 76 additions & 0 deletions tests/norm-rule/expected/test-norm-rules.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
{
"normative_rules": [
{
"name": "inline",
"def_filename": "tests/norm-rule/test.yaml",
"summary": "A few words",
"tags": [
{
"name": "norm:inline",
"text": "inside inline",
"tag_filename": "/build/test-norm-tags.json"
}
]
},
{
"name": "paragraph",
"def_filename": "tests/norm-rule/test.yaml",
"tags": [
{
"name": "norm:para",
"text": "Paragraph anchor",
"tag_filename": "/build/test-norm-tags.json"
}
]
},
{
"name": "note_with_2_tags",
"def_filename": "tests/norm-rule/test.yaml",
"description": "Here's a description.\nIt's got 2 lines.\n",
"tags": [
{
"name": "norm:note-1",
"text": "Multi-paragraph note 1",
"tag_filename": "/build/test-norm-tags.json"
},
{
"name": "norm:note-3",
"text": "Multi-paragraph note 3",
"tag_filename": "/build/test-norm-tags.json"
}
]
},
{
"name": "desc1",
"def_filename": "tests/norm-rule/test.yaml",
"tags": [
{
"name": "norm:description-item-1",
"text": "Item 1",
"tag_filename": "/build/test-norm-tags.json"
},
{
"name": "norm:description-item-3",
"text": "Item 3",
"tag_filename": "/build/test-norm-tags.json"
}
]
},
{
"name": "desc2",
"def_filename": "tests/norm-rule/test.yaml",
"tags": [
{
"name": "norm:description-item-1",
"text": "Item 1",
"tag_filename": "/build/test-norm-tags.json"
},
{
"name": "norm:description-item-3",
"text": "Item 3",
"tag_filename": "/build/test-norm-tags.json"
}
]
}
]
}
45 changes: 45 additions & 0 deletions tests/norm-rule/expected/test-norm-tags.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
{
"tags": {
"norm:inline": "inside inline",
"norm:para": "Paragraph anchor",
"norm:description-item-1": "Item 1",
"norm:description-item-3": "Item 3",
"norm:note-1": "Multi-paragraph note 1",
"norm:note-3": "Multi-paragraph note 3"
},
"sections": {
"title": "",
"id": "",
"children": [
{
"title": "Chapter 1",
"id": "_chapter_1",
"children": [
{
"title": "Chapter 1.1",
"id": "_chapter_1_1",
"children": [],
"tags": [
"norm:para"
]
}
],
"tags": [
"norm:inline"
]
},
{
"title": "Chapter 2",
"id": "_chapter_2",
"children": [],
"tags": [
"norm:description-item-1",
"norm:description-item-3",
"norm:note-1",
"norm:note-3"
]
}
],
"tags": []
}
}
61 changes: 61 additions & 0 deletions tests/norm-rule/test.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// This file contains test AsciiDoc to test the custom AsciiDoctor "tags" backend and the "create_normative_rules" Ruby
// script that consumes the tags to create a list of normative rules.

== Chapter 1

Before inline [#norm:inline]#inside inline# outside inline.

Before bad inline [#norm:bad-inline]#
inside bad inline# outside bad inline.#

=== Chapter 1.1

[[norm:para]]
Paragraph anchor

Next paragraph

Table:
|===

| [[norm:table-cell]] cell contents | next cell
|===

== Chapter 2

Unordered List:

* [[norm:unordered-item-1]] Item 1
* [[norm:unordered-item-2]] Item 2
* Item 3

Ordered List:

. [[norm:ordered-item-1]] Item 1
. [[norm:ordered-item-2]] Item 2
. Item 3

Description List:

Description-1::
[[norm:description-item-1]]
Item 1

Description-2:: Item 2

Description-3::
[[norm:description-item-3]]
Item 3

NOTE: [[norm-note-1]] Single paragraph note

[NOTE]
====
[[norm:note-1]]
Multi-paragraph note 1

Multi-paragraph note 2

[[norm:note-3]]
Multi-paragraph note 3
====
19 changes: 19 additions & 0 deletions tests/norm-rule/test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# yaml-language-server: $schema=../../schemas/defs-schema.json

$schema: "../../schemas/defs-schema.json#"

# Used to create normative rules for test.adoc file.

normative_rule_definitions:
- name: inline
summary: A few words
tags: ["norm:inline"]
- name: paragraph
tags: ["norm:para"]
- name: note_with_2_tags
description: |
Here's a description.
It's got 2 lines.
tags: ["norm:note-1", "norm:note-3"]
- names: [desc1, desc2]
tags: ["norm:description-item-1", "norm:description-item-3"]
Loading