metanorma-cli 1.1.6 → 1.1.7
Sign up to get free protection for your applications and to get access to all the features.
- 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
|