metanorma-cli 1.1.6 → 1.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile.lock +36 -33
- data/appveyor.yml +6 -1
- data/bin/rspec +29 -0
- data/exe/metanorma +15 -1
- data/lib/metanorma/cli.rb +35 -3
- data/lib/metanorma/cli/command.rb +75 -0
- data/lib/metanorma/cli/compiler.rb +56 -0
- data/lib/metanorma/cli/generator.rb +124 -0
- data/lib/metanorma/cli/git_template.rb +104 -0
- data/lib/metanorma/cli/ui.rb +20 -0
- data/lib/metanorma/cli/version.rb +1 -1
- data/metanorma-cli.gemspec +4 -3
- data/templates/base/Gemfile +4 -0
- data/templates/base/Makefile +126 -0
- data/templates/base/Makefile.win +63 -0
- data/templates/base/appveyor.yml +29 -0
- data/templates/base/deploy.sh +78 -0
- data/templates/csd/LICENSE +201 -0
- data/templates/csd/collection/Makefile +139 -0
- data/templates/csd/common/Gemfile +4 -0
- data/templates/csd/common/Makefile +126 -0
- data/templates/csd/common/Makefile.win +63 -0
- data/templates/csd/common/appveyor.yml +29 -0
- data/templates/csd/common/deploy.sh +78 -0
- data/tmp/my-custom-csd/Gemfile +4 -0
- data/tmp/my-custom-csd/Makefile +126 -0
- data/tmp/my-custom-csd/Makefile.win +63 -0
- data/tmp/my-custom-csd/appveyor.yml +29 -0
- data/tmp/my-custom-csd/deploy.sh +78 -0
- data/tmp/my-document/Gemfile +4 -0
- data/tmp/my-document/Makefile +126 -0
- data/tmp/my-document/Makefile.win +63 -0
- data/tmp/my-document/appveyor.yml +29 -0
- data/tmp/my-document/deploy.sh +78 -0
- metadata +58 -2
@@ -0,0 +1,56 @@
|
|
1
|
+
module Metanorma
|
2
|
+
module Cli
|
3
|
+
class Compiler
|
4
|
+
def initialize(file, options)
|
5
|
+
@file = file
|
6
|
+
@options = options
|
7
|
+
@extract = (options.delete(:extract) || "").split(",")
|
8
|
+
@extensions = (options.delete(:extensions) || "").split(",")
|
9
|
+
end
|
10
|
+
|
11
|
+
def compile
|
12
|
+
compile_file
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.compile(file, options)
|
16
|
+
new(file, options).compile
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
attr_reader :file, :options, :extract, :extensions
|
22
|
+
|
23
|
+
def compile_file
|
24
|
+
Compile.new.compile( file, serialize_options)
|
25
|
+
end
|
26
|
+
|
27
|
+
def serialize_options
|
28
|
+
serialize(options.merge(customize_options))
|
29
|
+
end
|
30
|
+
|
31
|
+
def customize_options
|
32
|
+
extract_option.merge(extension_option)
|
33
|
+
end
|
34
|
+
|
35
|
+
def extract_option
|
36
|
+
Hash.new.tap do |hash|
|
37
|
+
hash[:extract] = extract[0]
|
38
|
+
hash[:extract_type] =
|
39
|
+
extract.size > 0 ? extract[0..-1].map(&:to_sym) : []
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def extension_option
|
44
|
+
!extensions.empty? ? { extension_keys: extensions.map(&:to_sym) } : {}
|
45
|
+
end
|
46
|
+
|
47
|
+
def serialize(options)
|
48
|
+
Hash.new.tap do |hash|
|
49
|
+
options.each do |key, value|
|
50
|
+
hash[key.to_sym] = value unless value.nil?
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,124 @@
|
|
1
|
+
require "pathname"
|
2
|
+
require "fileutils"
|
3
|
+
require "metanorma/cli/ui"
|
4
|
+
|
5
|
+
module Metanorma
|
6
|
+
module Cli
|
7
|
+
class Generator
|
8
|
+
def initialize(name, type:, doctype:, **options)
|
9
|
+
@name = name
|
10
|
+
@type = type
|
11
|
+
@doctype = doctype
|
12
|
+
@options = options
|
13
|
+
end
|
14
|
+
|
15
|
+
def run
|
16
|
+
if name && document_path.exist?
|
17
|
+
return unless overwrite?(document_path)
|
18
|
+
document_path.rmtree
|
19
|
+
end
|
20
|
+
|
21
|
+
create_metanorma_document
|
22
|
+
end
|
23
|
+
|
24
|
+
# Generator.run
|
25
|
+
#
|
26
|
+
# This interface find / downloads the specified template
|
27
|
+
# and then run the generator to create a new metanorma
|
28
|
+
# document.
|
29
|
+
#
|
30
|
+
# By default it usages the default templates but user can
|
31
|
+
# also provide a remote git teplate repo using --template
|
32
|
+
# ooption, and in that case it will use that template.
|
33
|
+
#
|
34
|
+
def self.run(name, type:, doctype:, **options)
|
35
|
+
new(name, options.merge(type: type, doctype: doctype)).run
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
attr_reader :name, :type, :doctype, :options
|
41
|
+
|
42
|
+
def document_path
|
43
|
+
@document_path ||= Pathname.pwd.join(name)
|
44
|
+
end
|
45
|
+
|
46
|
+
def create_metanorma_document
|
47
|
+
type_template = type_specific_template
|
48
|
+
|
49
|
+
unless type_template.empty?
|
50
|
+
templates = base_templates.merge(type_template)
|
51
|
+
templates.each { |source, dest| create_file(source, dest) }
|
52
|
+
else
|
53
|
+
UI.say(
|
54
|
+
"Sorry, could not generate the document!\n" \
|
55
|
+
"Template's are missing, please provide valid template URL"
|
56
|
+
)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def find_template(type)
|
61
|
+
Cli::GitTemplate.find_or_download_by(type)
|
62
|
+
end
|
63
|
+
|
64
|
+
def overwrite?(document_path)
|
65
|
+
options[:overwrite] == true || ask_to_confirm(document_path) === "yes"
|
66
|
+
end
|
67
|
+
|
68
|
+
def base_templates
|
69
|
+
base_template_root = Cli.templates_path.join("base")
|
70
|
+
build_template_hash(dir_files(base_template_root), base_template_root)
|
71
|
+
end
|
72
|
+
|
73
|
+
def type_specific_template
|
74
|
+
type_template_path = custom_template || find_template(type)
|
75
|
+
doctype_templates = dir_files(type_template_path, doctype)
|
76
|
+
build_template_hash(doctype_templates, type_template_path, doctype)
|
77
|
+
end
|
78
|
+
|
79
|
+
def custom_template
|
80
|
+
if options[:template]
|
81
|
+
Cli::GitTemplate.download(type, repo: options[:template])
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def build_template_hash(elements, source_root, type = nil)
|
86
|
+
type_template_path = [source_root, type].join("/")
|
87
|
+
|
88
|
+
Hash.new.tap do |hash|
|
89
|
+
elements.each do |element|
|
90
|
+
hash[element] = element.gsub(type_template_path, "")
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def create_file(source, destination)
|
96
|
+
target_path = [document_path, destination].join("/")
|
97
|
+
target_path = Pathname.new(target_path)
|
98
|
+
|
99
|
+
unless target_path.dirname.exist?
|
100
|
+
FileUtils.mkdir_p(target_path.dirname)
|
101
|
+
end
|
102
|
+
|
103
|
+
file_creation_message(name, destination)
|
104
|
+
FileUtils.copy_entry(source, target_path)
|
105
|
+
end
|
106
|
+
|
107
|
+
def dir_files(*arguments)
|
108
|
+
paths = [*arguments, "**", "**"].join("/")
|
109
|
+
Pathname.glob(paths).reject(&:directory?).map(&:to_s)
|
110
|
+
end
|
111
|
+
|
112
|
+
def ask_to_confirm(document)
|
113
|
+
UI.ask(
|
114
|
+
"You've an existing document with the #{document.to_s}\n" \
|
115
|
+
"Still want to continue, and overwrite the existing one? (yes/no):",
|
116
|
+
).downcase
|
117
|
+
end
|
118
|
+
|
119
|
+
def file_creation_message(document, destination)
|
120
|
+
UI.say("Creating #{[document, destination].join("/").gsub("//", "/")}")
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
require "git"
|
2
|
+
|
3
|
+
module Metanorma
|
4
|
+
module Cli
|
5
|
+
class GitTemplate
|
6
|
+
def initialize(name, options = {})
|
7
|
+
@name = name
|
8
|
+
@options = options
|
9
|
+
end
|
10
|
+
|
11
|
+
def remove!
|
12
|
+
remove_template
|
13
|
+
return true
|
14
|
+
end
|
15
|
+
|
16
|
+
def download
|
17
|
+
remove!
|
18
|
+
clone_git_template(options[:repo])
|
19
|
+
|
20
|
+
rescue Git::GitExecuteError
|
21
|
+
UI.say("Invalid template reoository!")
|
22
|
+
return nil
|
23
|
+
end
|
24
|
+
|
25
|
+
def find_or_download
|
26
|
+
find_template || download_template
|
27
|
+
end
|
28
|
+
|
29
|
+
# Find or Download
|
30
|
+
#
|
31
|
+
# This interface expects a name / type, and then it will
|
32
|
+
# find that template, or if non exist then it will download
|
33
|
+
# and return the downloaded path.
|
34
|
+
#
|
35
|
+
def self.find_or_download_by(name)
|
36
|
+
new(name).find_or_download
|
37
|
+
end
|
38
|
+
|
39
|
+
# Download a template
|
40
|
+
#
|
41
|
+
# This interface expects a name, and remote repository link
|
42
|
+
# for a template, then it will download that template and it
|
43
|
+
# will return the downloaded path.
|
44
|
+
#
|
45
|
+
# By default, downloaded tempaltes will be stored in a sub
|
46
|
+
# directoy inside metanorma's tempaltes directory, but if
|
47
|
+
# you don't want then you can set the `remote` to false.
|
48
|
+
#
|
49
|
+
def self.download(name, repo:, remote: true)
|
50
|
+
new(name, repo: repo, remote: remote).download
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
attr_reader :name, :options
|
56
|
+
|
57
|
+
def find_template
|
58
|
+
if template_path.exist?
|
59
|
+
template_path
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def download_template
|
64
|
+
template_repo = git_repos[name.to_sym]
|
65
|
+
|
66
|
+
if template_repo
|
67
|
+
clone_git_template(template_repo)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def remove_template
|
72
|
+
if template_path.exist?
|
73
|
+
template_path.rmtree
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def clone_git_template(repo)
|
78
|
+
clone = Git.clone(repo, name, path: templates_path)
|
79
|
+
template_path unless clone.nil?
|
80
|
+
end
|
81
|
+
|
82
|
+
def git_repos
|
83
|
+
@git_repos ||= {
|
84
|
+
csd: "https://github.com/metanorma/mn-templates-csd",
|
85
|
+
ogc: "https://github.com/metanorma/mn-templates-ogc",
|
86
|
+
iso: "https://github.com/metanorma/mn-templates-iso",
|
87
|
+
}
|
88
|
+
end
|
89
|
+
|
90
|
+
def templates_path
|
91
|
+
@templates_path ||= build_templates_path
|
92
|
+
end
|
93
|
+
|
94
|
+
def build_templates_path
|
95
|
+
sub_directory = options[:remote] == true ? "git" : nil
|
96
|
+
Metanorma::Cli.templates_path.join(sub_directory.to_s)
|
97
|
+
end
|
98
|
+
|
99
|
+
def template_path
|
100
|
+
@template_path ||= templates_path.join(name.to_s.downcase)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require "thor"
|
2
|
+
|
3
|
+
module Metanorma
|
4
|
+
module Cli
|
5
|
+
class UI < Thor
|
6
|
+
def self.ask(message)
|
7
|
+
new.ask(message)
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.say(message)
|
11
|
+
new.say(message)
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.run(command)
|
15
|
+
require "open3"
|
16
|
+
Open3.capture3(command)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/metanorma-cli.gemspec
CHANGED
@@ -30,10 +30,10 @@ Gem::Specification.new do |spec|
|
|
30
30
|
spec.add_development_dependency "byebug", "~> 10.0"
|
31
31
|
spec.add_development_dependency "rspec-command", "~> 1.0.3"
|
32
32
|
spec.add_development_dependency "equivalent-xml", "~> 0.6"
|
33
|
-
spec.add_development_dependency
|
33
|
+
spec.add_development_dependency "rspec-core", "~> 3.4"
|
34
34
|
|
35
|
-
|
36
|
-
spec.add_runtime_dependency
|
35
|
+
spec.add_runtime_dependency "thor", "~> 0.20.3"
|
36
|
+
spec.add_runtime_dependency "metanorma-iso", "~> 1.1.0"
|
37
37
|
spec.add_runtime_dependency 'metanorma-ietf', "~> 1.0.1"
|
38
38
|
spec.add_runtime_dependency 'metanorma-gb', "~> 1.1.0"
|
39
39
|
spec.add_runtime_dependency 'metanorma-csd', "~> 1.1.0"
|
@@ -49,4 +49,5 @@ Gem::Specification.new do |spec|
|
|
49
49
|
spec.add_runtime_dependency 'isodoc', "~> 0.9.0"
|
50
50
|
spec.add_runtime_dependency 'metanorma', "~> 0.3.9"
|
51
51
|
spec.add_runtime_dependency 'nokogiri', ">= 1"
|
52
|
+
spec.add_runtime_dependency "git", "~> 1.5"
|
52
53
|
end
|
@@ -0,0 +1,126 @@
|
|
1
|
+
#!make
|
2
|
+
SHELL := /bin/bash
|
3
|
+
|
4
|
+
FORMAT_MARKER := mn-output-
|
5
|
+
FORMATS := $(shell grep "$(FORMAT_MARKER)" *.adoc | cut -f 2 -d ' ' | tr ',' '\n' | sort | uniq | tr '\n' ' ')
|
6
|
+
|
7
|
+
SRC := $(filter-out README.adoc, $(wildcard *.adoc))
|
8
|
+
XML := $(patsubst %.adoc,%.xml,$(SRC))
|
9
|
+
HTML := $(patsubst %.adoc,%.html,$(SRC))
|
10
|
+
DOC := $(patsubst %.adoc,%.doc,$(SRC))
|
11
|
+
PDF := $(patsubst %.adoc,%.pdf,$(SRC))
|
12
|
+
WSD := $(wildcard models/*.wsd)
|
13
|
+
XMI := $(patsubst models/%,xmi/%,$(patsubst %.wsd,%.xmi,$(WSD)))
|
14
|
+
PNG := $(patsubst models/%,images/%,$(patsubst %.wsd,%.png,$(WSD)))
|
15
|
+
|
16
|
+
COMPILE_CMD_LOCAL := bundle exec metanorma $$FILENAME
|
17
|
+
COMPILE_CMD_DOCKER := docker run -v "$$(pwd)":/metanorma/ ribose/metanorma "metanorma $$FILENAME"
|
18
|
+
|
19
|
+
ifdef METANORMA_DOCKER
|
20
|
+
COMPILE_CMD := echo "Compiling via docker..."; $(COMPILE_CMD_DOCKER)
|
21
|
+
else
|
22
|
+
COMPILE_CMD := echo "Compiling locally..."; $(COMPILE_CMD_LOCAL)
|
23
|
+
endif
|
24
|
+
|
25
|
+
_OUT_FILES := $(foreach FORMAT,$(FORMATS),$(shell echo $(FORMAT) | tr '[:lower:]' '[:upper:]'))
|
26
|
+
OUT_FILES := $(foreach F,$(_OUT_FILES),$($F))
|
27
|
+
|
28
|
+
all: images $(OUT_FILES)
|
29
|
+
|
30
|
+
%.xml %.html %.doc %.pdf: %.adoc | bundle
|
31
|
+
FILENAME=$^; \
|
32
|
+
${COMPILE_CMD}
|
33
|
+
|
34
|
+
images: $(PNG)
|
35
|
+
|
36
|
+
images/%.png: models/%.wsd
|
37
|
+
plantuml -tpng -o ../images/ $<
|
38
|
+
|
39
|
+
xmi: $(XMI)
|
40
|
+
|
41
|
+
xmi/%.xmi: models/%.wsd
|
42
|
+
plantuml -xmi:star -o ../xmi/ $<
|
43
|
+
|
44
|
+
define FORMAT_TASKS
|
45
|
+
OUT_FILES-$(FORMAT) := $($(shell echo $(FORMAT) | tr '[:lower:]' '[:upper:]'))
|
46
|
+
|
47
|
+
open-$(FORMAT):
|
48
|
+
open $$(OUT_FILES-$(FORMAT))
|
49
|
+
|
50
|
+
clean-$(FORMAT):
|
51
|
+
rm -f $$(OUT_FILES-$(FORMAT))
|
52
|
+
|
53
|
+
$(FORMAT): clean-$(FORMAT) $$(OUT_FILES-$(FORMAT))
|
54
|
+
|
55
|
+
.PHONY: clean-$(FORMAT)
|
56
|
+
|
57
|
+
endef
|
58
|
+
|
59
|
+
$(foreach FORMAT,$(FORMATS),$(eval $(FORMAT_TASKS)))
|
60
|
+
|
61
|
+
open: open-html
|
62
|
+
|
63
|
+
clean:
|
64
|
+
rm -f $(OUT_FILES)
|
65
|
+
|
66
|
+
bundle:
|
67
|
+
if [ "x" == "${METANORMA_DOCKER}x" ]; then bundle; fi
|
68
|
+
|
69
|
+
.PHONY: bundle all open clean
|
70
|
+
|
71
|
+
#
|
72
|
+
# Watch-related jobs
|
73
|
+
#
|
74
|
+
|
75
|
+
.PHONY: watch serve watch-serve
|
76
|
+
|
77
|
+
NODE_BINS := onchange live-serve run-p
|
78
|
+
NODE_BIN_DIR := node_modules/.bin
|
79
|
+
NODE_PACKAGE_PATHS := $(foreach PACKAGE_NAME,$(NODE_BINS),$(NODE_BIN_DIR)/$(PACKAGE_NAME))
|
80
|
+
|
81
|
+
$(NODE_PACKAGE_PATHS): package.json
|
82
|
+
npm i
|
83
|
+
|
84
|
+
watch: $(NODE_BIN_DIR)/onchange
|
85
|
+
make all
|
86
|
+
$< $(ALL_SRC) -- make all
|
87
|
+
|
88
|
+
define WATCH_TASKS
|
89
|
+
watch-$(FORMAT): $(NODE_BIN_DIR)/onchange
|
90
|
+
make $(FORMAT)
|
91
|
+
$$< $$(SRC_$(FORMAT)) -- make $(FORMAT)
|
92
|
+
|
93
|
+
.PHONY: watch-$(FORMAT)
|
94
|
+
endef
|
95
|
+
|
96
|
+
$(foreach FORMAT,$(FORMATS),$(eval $(WATCH_TASKS)))
|
97
|
+
|
98
|
+
serve: $(NODE_BIN_DIR)/live-server revealjs-css reveal.js images
|
99
|
+
export PORT=$${PORT:-8123} ; \
|
100
|
+
port=$${PORT} ; \
|
101
|
+
for html in $(HTML); do \
|
102
|
+
$< --entry-file=$$html --port=$${port} --ignore="*.html,*.xml,Makefile,Gemfile.*,package.*.json" --wait=1000 & \
|
103
|
+
port=$$(( port++ )) ;\
|
104
|
+
done
|
105
|
+
|
106
|
+
watch-serve: $(NODE_BIN_DIR)/run-p
|
107
|
+
$< watch serve
|
108
|
+
|
109
|
+
#
|
110
|
+
# Deploy jobs
|
111
|
+
#
|
112
|
+
|
113
|
+
publish:
|
114
|
+
mkdir -p published && \
|
115
|
+
cp -a $(basename $(SRC)).* published/ && \
|
116
|
+
cp $(firstword $(HTML)) published/index.html; \
|
117
|
+
if [ -d "images" ]; then cp -a images published; fi
|
118
|
+
|
119
|
+
deploy_key:
|
120
|
+
openssl aes-256-cbc -K $(encrypted_$(ENCRYPTION_LABEL)_key) \
|
121
|
+
-iv $(encrypted_$(ENCRYPTION_LABEL)_iv) -in $@.enc -out $@ -d && \
|
122
|
+
chmod 600 $@
|
123
|
+
|
124
|
+
deploy: deploy_key
|
125
|
+
export COMMIT_AUTHOR_EMAIL=$(COMMIT_AUTHOR_EMAIL); \
|
126
|
+
./deploy.sh
|