astroboa-cli 0.3.0
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.
- data/.gitignore +5 -0
- data/CHANGELOG.rdoc +1 -0
- data/COPYING +675 -0
- data/COPYING.LESSER +166 -0
- data/Gemfile +4 -0
- data/LICENSE +47 -0
- data/README.md +185 -0
- data/Rakefile +1 -0
- data/astroboa-cli.gemspec +32 -0
- data/bin/astroboa-cli +18 -0
- data/lib/astroboa-cli/cli.rb +16 -0
- data/lib/astroboa-cli/command/base.rb +173 -0
- data/lib/astroboa-cli/command/help.rb +95 -0
- data/lib/astroboa-cli/command/model.rb +181 -0
- data/lib/astroboa-cli/command/repository.rb +443 -0
- data/lib/astroboa-cli/command/server.rb +651 -0
- data/lib/astroboa-cli/command/service.rb +224 -0
- data/lib/astroboa-cli/command/version.rb +21 -0
- data/lib/astroboa-cli/command.rb +158 -0
- data/lib/astroboa-cli/util.rb +594 -0
- data/lib/astroboa-cli/version.rb +3 -0
- data/lib/astroboa-cli.rb +9 -0
- data/test/features/astroboa-cli.feature +4 -0
- metadata +139 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
require "astroboa-cli/command"
|
|
4
|
+
|
|
5
|
+
module AstroboaCLI
|
|
6
|
+
|
|
7
|
+
class CLI
|
|
8
|
+
def self.start(*args)
|
|
9
|
+
command = args.shift.strip rescue "help"
|
|
10
|
+
AstroboaCLI::Command.load
|
|
11
|
+
AstroboaCLI::Command.run(command, args)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
end
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
# encoding: UTF-8
|
|
2
|
+
|
|
3
|
+
# This file contains modifications of work covered by the following copyright and
|
|
4
|
+
# permission notice:
|
|
5
|
+
#
|
|
6
|
+
# The MIT License (MIT)
|
|
7
|
+
#
|
|
8
|
+
# Copyright © Heroku 2008 - 2012
|
|
9
|
+
#
|
|
10
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
|
11
|
+
# a copy of this software and associated documentation files (the
|
|
12
|
+
# "Software"), to deal in the Software without restriction, including
|
|
13
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
|
14
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
|
15
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
|
16
|
+
# the following conditions:
|
|
17
|
+
#
|
|
18
|
+
# The above copyright notice and this permission notice shall be
|
|
19
|
+
# included in all copies or substantial portions of the Software.
|
|
20
|
+
#
|
|
21
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
22
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
23
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
24
|
+
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
25
|
+
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
26
|
+
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
27
|
+
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
require 'logger'
|
|
31
|
+
|
|
32
|
+
module AstroboaCLI::Command
|
|
33
|
+
|
|
34
|
+
class Base
|
|
35
|
+
include AstroboaCLI::Util
|
|
36
|
+
|
|
37
|
+
def self.namespace
|
|
38
|
+
self.to_s.split("::").last.downcase
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
attr_reader :args
|
|
42
|
+
attr_reader :options
|
|
43
|
+
attr_reader :log
|
|
44
|
+
attr_reader :log_file
|
|
45
|
+
|
|
46
|
+
def initialize(args=[], options={})
|
|
47
|
+
@args = args
|
|
48
|
+
@options = options
|
|
49
|
+
|
|
50
|
+
@log_file = '/tmp/astroboa-cli-log.txt'
|
|
51
|
+
@log = Logger.new(@log_file)
|
|
52
|
+
@log.level = Logger::INFO
|
|
53
|
+
|
|
54
|
+
# Check if the proper version of ruby is running
|
|
55
|
+
ruby_ok?
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
protected
|
|
59
|
+
def self.inherited(klass)
|
|
60
|
+
return if klass == AstroboaCLI::Command::Base
|
|
61
|
+
|
|
62
|
+
help = extract_help_from_caller(caller.first)
|
|
63
|
+
|
|
64
|
+
AstroboaCLI::Command.register_namespace(
|
|
65
|
+
:name => klass.namespace,
|
|
66
|
+
:description => help.split("\n").first,
|
|
67
|
+
:long_description => help.split("\n")
|
|
68
|
+
)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def self.method_added(method)
|
|
72
|
+
return if self == AstroboaCLI::Command::Base
|
|
73
|
+
return if private_method_defined?(method)
|
|
74
|
+
return if protected_method_defined?(method)
|
|
75
|
+
|
|
76
|
+
help = extract_help_from_caller(caller.first)
|
|
77
|
+
|
|
78
|
+
resolved_method = (method.to_s == "default") ? nil : method.to_s
|
|
79
|
+
command = [ self.namespace, resolved_method ].compact.join(":")
|
|
80
|
+
banner = extract_banner(help) || command
|
|
81
|
+
permute = !banner.index("*")
|
|
82
|
+
banner.gsub!("*", "")
|
|
83
|
+
|
|
84
|
+
AstroboaCLI::Command.register_command(
|
|
85
|
+
:klass => self,
|
|
86
|
+
:method => method,
|
|
87
|
+
:namespace => self.namespace,
|
|
88
|
+
:command => command,
|
|
89
|
+
:banner => banner,
|
|
90
|
+
:help => help,
|
|
91
|
+
:summary => extract_summary(help),
|
|
92
|
+
:description => extract_description(help),
|
|
93
|
+
:options => extract_options(help),
|
|
94
|
+
:permute => permute
|
|
95
|
+
)
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
# Parse the caller format and identify the file and line number as identified
|
|
99
|
+
# in : http://www.ruby-doc.org/core/classes/Kernel.html#M001397. This will
|
|
100
|
+
# look for a colon followed by a digit as the delimiter. The biggest
|
|
101
|
+
# complication is windows paths, which have a color after the drive letter.
|
|
102
|
+
# This regex will match paths as anything from the beginning to a colon
|
|
103
|
+
# directly followed by a number (the line number).
|
|
104
|
+
#
|
|
105
|
+
# Examples of the caller format :
|
|
106
|
+
# * c:/Ruby192/lib/.../lib/astroboa-cli/command/server.rb:8:in `<module:Command>'
|
|
107
|
+
#
|
|
108
|
+
def self.extract_help_from_caller(line)
|
|
109
|
+
# pull out of the caller the information for the file path and line number
|
|
110
|
+
if line =~ /^(.+?):(\d+)/
|
|
111
|
+
return extract_help($1, $2)
|
|
112
|
+
end
|
|
113
|
+
raise "unable to extract help from caller: #{line}"
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def self.extract_help(file, line)
|
|
117
|
+
buffer = []
|
|
118
|
+
lines = File.read(file).split("\n")
|
|
119
|
+
|
|
120
|
+
catch(:done) do
|
|
121
|
+
(line.to_i-2).downto(0) do |i|
|
|
122
|
+
case lines[i].strip[0..0]
|
|
123
|
+
when "", "#" then buffer << lines[i]
|
|
124
|
+
else throw(:done)
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
buffer.map! do |line|
|
|
130
|
+
line.strip.gsub(/^#/, "")
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
buffer.reverse.join("\n").strip
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def self.extract_banner(help)
|
|
137
|
+
help.split("\n").first
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def self.extract_summary(help)
|
|
141
|
+
extract_description(help).split("\n").first
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def self.extract_description(help)
|
|
145
|
+
lines = help.split("\n").map { |l| l.strip }
|
|
146
|
+
lines.shift
|
|
147
|
+
lines.reject do |line|
|
|
148
|
+
line =~ /^-(.+)#(.+)/
|
|
149
|
+
end.join("\n").strip
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
def self.extract_options(help)
|
|
153
|
+
help.split("\n").map { |l| l.strip }.select do |line|
|
|
154
|
+
line =~ /^-(.+)#(.+)/
|
|
155
|
+
end.inject({}) do |hash, line|
|
|
156
|
+
description = line.split("#", 2).last.strip
|
|
157
|
+
long = line.match(/--([A-Za-z_\- ]+)/)[1].strip
|
|
158
|
+
short = line.match(/-([A-Za-z ])/)[1].strip
|
|
159
|
+
hash.update(long.split(" ").first => { :desc => description, :short => short, :long => long })
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
def extract_option(name, default=true)
|
|
164
|
+
key = name.gsub("--", "").to_sym
|
|
165
|
+
return unless options[key]
|
|
166
|
+
value = options[key] || default
|
|
167
|
+
block_given? ? yield(value) : value
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
end # class base
|
|
172
|
+
|
|
173
|
+
end # Module AstroboaCLI::Command
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
require "astroboa-cli/command/base"
|
|
4
|
+
|
|
5
|
+
# display available commands and help
|
|
6
|
+
#
|
|
7
|
+
class AstroboaCLI::Command::Help < AstroboaCLI::Command::Base
|
|
8
|
+
|
|
9
|
+
# help [COMMAND]
|
|
10
|
+
#
|
|
11
|
+
# list available commands or display help for a specific command
|
|
12
|
+
#
|
|
13
|
+
def default
|
|
14
|
+
if command = args.shift
|
|
15
|
+
help_for_command(command)
|
|
16
|
+
else
|
|
17
|
+
help_for_root
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
private
|
|
22
|
+
|
|
23
|
+
def subcommands_in_namespace(name)
|
|
24
|
+
AstroboaCLI::Command.commands.values.select do |command|
|
|
25
|
+
command[:namespace] == name && command[:command] != name
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def help_for_root
|
|
30
|
+
puts "Usage: astroboa-cli COMMAND [command-specific-options]"
|
|
31
|
+
puts
|
|
32
|
+
puts "To get help about a top command, type \"astroboa-cli help command\""
|
|
33
|
+
puts "Available top commands:"
|
|
34
|
+
summary_for_namespaces
|
|
35
|
+
puts
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def summary_for_namespaces
|
|
39
|
+
size = longest(AstroboaCLI::Command.namespaces.values.map { |namespace| namespace[:name] })
|
|
40
|
+
AstroboaCLI::Command.namespaces.values.sort_by {|namespace| namespace[:name]}.each do |namespace|
|
|
41
|
+
name = namespace[:name]
|
|
42
|
+
puts " %-#{size}s # %s" % [ name, namespace[:description] ]
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def help_for_subcommands_in_namespace(namespace)
|
|
47
|
+
subcommands = subcommands_in_namespace(namespace)
|
|
48
|
+
|
|
49
|
+
unless subcommands.empty?
|
|
50
|
+
size = longest(subcommands.map { |c| c[:banner] })
|
|
51
|
+
subcommands.sort_by { |c| c[:banner].to_s }.each do |command|
|
|
52
|
+
next if command[:help] =~ /DEPRECATED/
|
|
53
|
+
puts " %-#{size}s # %s" % [ command[:banner], command[:summary] ]
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def help_for_command(name)
|
|
59
|
+
puts AstroboaCLI::Command.namespaces[name][:long_description] if AstroboaCLI::Command.namespaces[name]
|
|
60
|
+
puts
|
|
61
|
+
command = AstroboaCLI::Command.commands[name]
|
|
62
|
+
|
|
63
|
+
if command
|
|
64
|
+
puts "Usage: astroboa-cli #{command[:banner]}"
|
|
65
|
+
|
|
66
|
+
if command[:help].strip.length > 0
|
|
67
|
+
command[:help].split("\n")[1..-1].each do |line|
|
|
68
|
+
if line =~ /#/
|
|
69
|
+
option_parts = line.split('#')
|
|
70
|
+
puts "#{option_parts[0]}"
|
|
71
|
+
option_parts[1..-1].each do |sentence|
|
|
72
|
+
puts "\t #{sentence}"
|
|
73
|
+
end
|
|
74
|
+
puts
|
|
75
|
+
elsif
|
|
76
|
+
puts line
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
puts
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# if there are sub commands inform the user
|
|
85
|
+
if subcommands_in_namespace(name).size > 0
|
|
86
|
+
puts "This top command supports the following sub-commands, type \"astroboa-cli help SUB-COMMAND\" to get help:"
|
|
87
|
+
puts
|
|
88
|
+
help_for_subcommands_in_namespace(name)
|
|
89
|
+
puts
|
|
90
|
+
elsif command.nil? # if there are not subcommands and the top command itself does not exist display an error
|
|
91
|
+
error "#{name} is not an astroboa command. See 'astroboa-cli help'."
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
end
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
# encoding: UTF-8
|
|
2
|
+
|
|
3
|
+
require 'nokogiri'
|
|
4
|
+
require 'fileutils'
|
|
5
|
+
|
|
6
|
+
# Manage your domain models
|
|
7
|
+
#
|
|
8
|
+
# Astroboa facilitates a DOMAIN DRIVEN design of applications.
|
|
9
|
+
# The core of your application(s) is the DOMAIN MODEL, a graph of ENTITIES that describe
|
|
10
|
+
# the type of information your application(s) will create, consume and search.
|
|
11
|
+
#
|
|
12
|
+
# In order to store your application(s) data you follow three simple steps:
|
|
13
|
+
# 1) you create an astroboa repository (astroboa-cli repository:create)
|
|
14
|
+
# 2) you create your domain model by:
|
|
15
|
+
# - using the Astroboa Entity Definition DSL which is very close to ActiveRecord::Schema definitions of ruby on rails
|
|
16
|
+
# - directy writing an XML Schema for each entity (or a single schema to include all entity definitions)
|
|
17
|
+
# 3) you "associate" your domain model with the repository you just created (astroboa-cli model:associate)
|
|
18
|
+
#
|
|
19
|
+
# One of the best features of astroboa is its programming-language agnostic and dynamic domain model that can be shared between applications.
|
|
20
|
+
# You do not need to create model classes for your applications. Astroboa uses the domain model that you define once and
|
|
21
|
+
# dynamically creates the appropriate objects for your app.
|
|
22
|
+
# Additionally you can "model-as-you-go", that is you may define new entities
|
|
23
|
+
# or update existing ones at any time during development or production.
|
|
24
|
+
# Astroboa will automatically update the APIs and the generated object instances to the updated domain model.
|
|
25
|
+
#
|
|
26
|
+
class AstroboaCLI::Command::Model < AstroboaCLI::Command::Base
|
|
27
|
+
|
|
28
|
+
# model:associate REPOSITORY MODEL_DIR
|
|
29
|
+
#
|
|
30
|
+
# This command allows you to associate a repository with a domain model.
|
|
31
|
+
# After the association is done your repository can store entities that follow the domain model.
|
|
32
|
+
#
|
|
33
|
+
# It is recommended to use this command only on new repositories because it does not cope with model updates
|
|
34
|
+
# (it will cause instant performace decrease because it resets the whole repository schema and most important
|
|
35
|
+
# it may render your data inaccessible if the updated model contain changes to property names or property value cardinality)
|
|
36
|
+
# If you change a domain model that has been already associated with a repository use 'astroboa-cli model:propagate_updates'
|
|
37
|
+
#
|
|
38
|
+
# If you specify the 'MODEL_DIR' (i.e. where your models are stored) then your DSL model definition is expected to be
|
|
39
|
+
# in 'MODEL_DIR/dsl' and your XML Schemas to be in 'MODEL_DIR/xsd'
|
|
40
|
+
# If you do not specify the 'MODEL_DIR' then domain model is expected to be found inside current directory in 'model/dsl' and 'model/xsd'
|
|
41
|
+
#
|
|
42
|
+
def associate
|
|
43
|
+
|
|
44
|
+
if repository = args.shift
|
|
45
|
+
repository = repository.strip
|
|
46
|
+
else
|
|
47
|
+
error "Please specify the repository name. Usage: model:associate REPOSITORY MODEL_DIR"
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
server_configuration = get_server_configuration
|
|
51
|
+
|
|
52
|
+
error "Repository '#{repository}' does not exist or it is not properly configured (use astroboa-cli repository:list to see available repositories)" unless repository?(server_configuration, repository)
|
|
53
|
+
|
|
54
|
+
if model_dir = args.shift
|
|
55
|
+
model_dir = model_dir.strip
|
|
56
|
+
else
|
|
57
|
+
model_dir = File.join(Dir.getwd, 'model')
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
error <<-MSG unless Dir.exists? model_dir
|
|
61
|
+
Directory #{model_dir} does not exist.
|
|
62
|
+
If you specify the 'MODEL_DIR' then your DSL model definition is expected to be
|
|
63
|
+
in 'MODEL_DIR/dsl' and your XML Schemas to be in 'MODEL_DIR/xsd'
|
|
64
|
+
If you do not specify the 'MODEL_DIR' then domain model is expected to be found inside current directory in 'model/dsl' and 'model/xsd'
|
|
65
|
+
MSG
|
|
66
|
+
|
|
67
|
+
astroboa_dir = server_configuration['install_dir']
|
|
68
|
+
|
|
69
|
+
display "Looking for XML Schemas..."
|
|
70
|
+
xsd_dir = File.join model_dir, 'xsd'
|
|
71
|
+
model_contains_xsd = Dir.exists?(xsd_dir) && Dir.entries(xsd_dir) != [".", ".."]
|
|
72
|
+
|
|
73
|
+
if model_contains_xsd
|
|
74
|
+
display "Found XML Schemas in '#{xsd_dir}'"
|
|
75
|
+
display "Validating XML Schemas..."
|
|
76
|
+
|
|
77
|
+
tmp_dir = File.join(astroboa_dir, 'tmp')
|
|
78
|
+
|
|
79
|
+
FileUtils.rm_r tmp_dir if Dir.exists? tmp_dir
|
|
80
|
+
|
|
81
|
+
FileUtils.mkdir_p tmp_dir
|
|
82
|
+
FileUtils.cp_r File.join(astroboa_dir, 'schemas'), tmp_dir
|
|
83
|
+
|
|
84
|
+
tmp_schema_dir = File.join(tmp_dir, 'schemas')
|
|
85
|
+
FileUtils.cp_r Dir.glob(File.join(xsd_dir, '*.xsd')), tmp_schema_dir
|
|
86
|
+
|
|
87
|
+
# Validate schemas in domain model
|
|
88
|
+
Dir[File.join(xsd_dir, '*.xsd')].each do |schema_path|
|
|
89
|
+
schema_file = schema_path.split('/').last
|
|
90
|
+
|
|
91
|
+
display
|
|
92
|
+
display '-------------------------------------------------'
|
|
93
|
+
display "Validating XML Schema: #{schema_file}"
|
|
94
|
+
error "Please correct the schema file '#{schema_file}' and run the command again" unless domain_model_valid? schema_file, tmp_schema_dir
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# copy schemas to repository schemas directory
|
|
98
|
+
repository_schema_dir = File.join(server_configuration['repos_dir'], repository, 'astroboa_schemata')
|
|
99
|
+
FileUtils.cp_r Dir.glob(File.join(xsd_dir, '*.xsd')), repository_schema_dir
|
|
100
|
+
|
|
101
|
+
display
|
|
102
|
+
display '-------------------------------------------------'
|
|
103
|
+
display '-------------------------------------------------'
|
|
104
|
+
display "Repository '#{repository}' associated to XML Schemas in '#{xsd_dir}': OK"
|
|
105
|
+
else
|
|
106
|
+
display "No XML Schemas Found"
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
# model:graph DOMAIN_MODEL
|
|
113
|
+
#
|
|
114
|
+
# Draws a graphic representation of the domain model
|
|
115
|
+
def graph
|
|
116
|
+
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
# model:view PATH
|
|
120
|
+
#
|
|
121
|
+
# Displays the model of an entity or entity property
|
|
122
|
+
def view
|
|
123
|
+
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
# model:list DOMAIN_MODEL
|
|
127
|
+
#
|
|
128
|
+
# Displays information about the domain models and their entities
|
|
129
|
+
def list
|
|
130
|
+
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
private
|
|
134
|
+
|
|
135
|
+
def domain_model_valid? domain_model_file, schemas_dir
|
|
136
|
+
Dir.chdir(schemas_dir) do
|
|
137
|
+
|
|
138
|
+
# first make sure that Domain model is a well formed XML Doc and if not show errors
|
|
139
|
+
domain_model_doc = Nokogiri::XML(File.read(domain_model_file))
|
|
140
|
+
unless domain_model_doc.errors.empty?
|
|
141
|
+
puts "#{domain_model_file} is not a well formed XML Document"
|
|
142
|
+
puts domain_model_doc.errors
|
|
143
|
+
return false
|
|
144
|
+
else
|
|
145
|
+
puts "Check if domain model is a well formed XML Document: OK"
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
# Then check if domain model is a valid XML Schema, i.e. validate it against the XML Schema schema
|
|
149
|
+
xml_schema_grammar = File.read('XMLSchema.xsd')
|
|
150
|
+
xml_schema_validator = Nokogiri::XML::Schema(xml_schema_grammar)
|
|
151
|
+
|
|
152
|
+
errors = xml_schema_validator.validate(domain_model_doc)
|
|
153
|
+
|
|
154
|
+
unless errors.empty?
|
|
155
|
+
puts "Check if domain model is a valid XML Schema: Not valid XML Schema"
|
|
156
|
+
errors.each do |error|
|
|
157
|
+
puts error.message
|
|
158
|
+
end
|
|
159
|
+
return false
|
|
160
|
+
else
|
|
161
|
+
puts "Check if domain model is a valid XML Schema: OK"
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
# Finally check if domain model is valid against its dependencies to astroboa schemas and external user-provided schemas,
|
|
165
|
+
# i.e. it properly loads and uses all its external schema dependencies
|
|
166
|
+
begin
|
|
167
|
+
external_schemas_validator = Nokogiri::XML::Schema(File.read(domain_model_file))
|
|
168
|
+
puts 'Check if domain model properly loads and uses external schemas (i.e. astroboa model schemas + user defined schemas): OK'
|
|
169
|
+
true
|
|
170
|
+
rescue Exception => e
|
|
171
|
+
puts 'Check if domain model is properly loading and using external schemas (i.e. astroboa model schemas + user defined schemas): Errors found!'
|
|
172
|
+
puts external_schemas_validator.errors if external_schemas_validator
|
|
173
|
+
puts e.message
|
|
174
|
+
false
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
end
|