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.
@@ -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
@@ -1,5 +1,5 @@
1
1
  module Metanorma
2
2
  module Cli
3
- VERSION = "1.1.6"
3
+ VERSION = "1.1.7"
4
4
  end
5
5
  end
@@ -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 'rspec-core', "~> 3.4"
33
+ spec.add_development_dependency "rspec-core", "~> 3.4"
34
34
 
35
-
36
- spec.add_runtime_dependency 'metanorma-iso', "~> 1.1.0"
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,4 @@
1
+ source "https://rubygems.org"
2
+
3
+ gem "metanorma-cli"
4
+ gem "relaton-cli"
@@ -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