kxi 1.0.1 → 1.0.2

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.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/lib/kxi.rb +44 -39
  3. data/lib/kxi/application/config.rb +177 -177
  4. data/lib/kxi/application/config_reader.rb +16 -16
  5. data/lib/kxi/application/event.rb +35 -35
  6. data/lib/kxi/application/logger.rb +155 -155
  7. data/lib/kxi/application/version.rb +106 -74
  8. data/lib/kxi/application/version_expression.rb +94 -69
  9. data/lib/kxi/application/workspace.rb +105 -0
  10. data/lib/kxi/cli/anonymous_argument.rb +50 -50
  11. data/lib/kxi/cli/argument.rb +56 -56
  12. data/lib/kxi/cli/argument_values.rb +83 -83
  13. data/lib/kxi/cli/explicit_argument.rb +38 -38
  14. data/lib/kxi/cli/flag_argument.rb +15 -15
  15. data/lib/kxi/cli/named_argument.rb +59 -59
  16. data/lib/kxi/cli/property_list.rb +57 -48
  17. data/lib/kxi/cli/table.rb +82 -62
  18. data/lib/kxi/cli/verb.rb +282 -280
  19. data/lib/kxi/collections/array_collection.rb +106 -106
  20. data/lib/kxi/collections/enumerable.rb +527 -527
  21. data/lib/kxi/collections/enumerator.rb +31 -31
  22. data/lib/kxi/collections/hash_collection.rb +100 -100
  23. data/lib/kxi/collections/protected_collection.rb +20 -19
  24. data/lib/kxi/exceptions/abstract_exception.rb +34 -34
  25. data/lib/kxi/exceptions/argument_exception.rb +21 -21
  26. data/lib/kxi/exceptions/collection_exception.rb +13 -13
  27. data/lib/kxi/exceptions/configuration_exception.rb +36 -25
  28. data/lib/kxi/exceptions/dimension_mismatch_exception.rb +29 -0
  29. data/lib/kxi/exceptions/invalid_type_exception.rb +32 -32
  30. data/lib/kxi/exceptions/no_argument_exception.rb +20 -20
  31. data/lib/kxi/exceptions/not_implemented_exception.rb +12 -12
  32. data/lib/kxi/exceptions/out_of_range_exception.rb +43 -43
  33. data/lib/kxi/exceptions/parse_exception.rb +28 -20
  34. data/lib/kxi/exceptions/verb_expected_exception.rb +20 -20
  35. data/lib/kxi/exceptions/workspace_collision_exception.rb +21 -0
  36. data/lib/kxi/math/math.rb +45 -0
  37. data/lib/kxi/math/matrix.rb +303 -0
  38. data/lib/kxi/math/polynomial.rb +141 -101
  39. data/lib/kxi/math/vector.rb +181 -0
  40. data/lib/kxi/platform.rb +103 -57
  41. data/lib/kxi/reflection/stack_frame.rb +80 -80
  42. data/lib/kxi/version.rb +4 -4
  43. metadata +8 -3
  44. data/lib/kxi/exceptions/invalid_operation_exception.rb +0 -11
@@ -1,70 +1,95 @@
1
- # Created by Matyáš Pokorný on 2018-01-27.
2
-
3
- module KXI
4
- module Application
5
- class VersionExpression
6
- COMP_EQ = '='
7
- COMP_LEQ = '<='
8
- COMP_LT = '<'
9
- COMP_GEQ = '>='
10
- COMP_GT = '>'
11
- COMP_AT = '~>'
12
-
13
- def comparison
14
- @comp
15
- end
16
-
17
- def major
18
- @major
19
- end
20
-
21
- def minor
22
- @minor
23
- end
24
-
25
- def patch
26
- @patch
27
- end
28
-
29
- def initialize(comp, major, minor = nil, patch = nil)
30
- @comp = comp
31
- @major = major
32
- @minor = minor
33
- @patch = patch
34
- @target = KXI::Application::Version.new(major, minor == nil ? 0 : minor, patch == nil ? 0 : patch)
35
- end
36
-
37
- # @param ver [KXI::Application::Version]
38
- def matches?(ver)
39
- case @comp
40
- when COMP_EQ
41
- return (
42
- ver.major == @major and
43
- ver.minor == (@minor == nil ? 0 : @minor) and
44
- ver.patch == (@patch == nil ? 0 : @patch)
45
- )
46
- when COMP_AT
47
- return (
48
- ver.major == @major and
49
- (@minor == nil or ver.minor == @minor) and
50
- (@patch == nil or ver.patch == @patch)
51
- )
52
- when COMP_GEQ
53
- return ver >= @target
54
- when COMP_LEQ
55
- return ver <= @target
56
- when COMP_GT
57
- return ver > @target
58
- when COMP_LT
59
- return ver < @target
60
- end
61
- end
62
-
63
- def self.parse(str)
64
- m = /^\s*(?'cm'>|<|>=|<=|=|~>)\s*(?'mj'\d+)\s*(\.\s*(?'mi'\d+))?\s*(\.\s*(?'pt'\d+))?\s*?$/m.match(str)
65
- raise(KXI::Exceptions::ParseException.new('version expression', str)) if m == nil
66
- return VersionExpression.new(m['cm'], m['mj'].to_i, m['mi']&.to_i, m['pt']&.to_i)
67
- end
68
- end
69
- end
1
+ # Created by Matyáš Pokorný on 2018-01-27.
2
+
3
+ module KXI
4
+ module Application
5
+ # Represents a comparison of two semantic versions
6
+ class VersionExpression
7
+ # Equivalence comparison
8
+ COMP_EQ = '='
9
+ # Less than or equivalent to comparison
10
+ COMP_LEQ = '<='
11
+ # Less than comparison
12
+ COMP_LT = '<'
13
+ # Grater than or equivalent to comparison
14
+ COMP_GEQ = '>='
15
+ # Grater than comparison
16
+ COMP_GT = '>'
17
+ # Minimal requirement comparison
18
+ COMP_AT = '~>'
19
+
20
+ # Get the comparison of versions
21
+ # @return [string] Comparison of versions
22
+ def comparison
23
+ @comp
24
+ end
25
+
26
+ # Gets the major number of left-side version
27
+ # @return [int] Major number version
28
+ def major
29
+ @major
30
+ end
31
+
32
+ # Gets the minor number of left-side version
33
+ # @return [int,nil] Minor number version
34
+ def minor
35
+ @minor
36
+ end
37
+
38
+ # Gets the patch number of left-side version
39
+ # @return [int,nil] Patch number version
40
+ def patch
41
+ @patch
42
+ end
43
+
44
+ # Instantiates the {KXI::Application::VersionExpression} class
45
+ # @param [string] comp Comparison rule of expression
46
+ # @param [int] major Major number of left-side version
47
+ # @param [int,nil] minor Minor number of left-side version
48
+ # @param [int,nil] patch Patch number of left-side version
49
+ def initialize(comp, major, minor = nil, patch = nil)
50
+ @comp = comp
51
+ @major = major
52
+ @minor = minor
53
+ @patch = patch
54
+ @target = KXI::Application::Version.new(major, minor == nil ? 0 : minor, patch == nil ? 0 : patch)
55
+ end
56
+
57
+ # Checks whether expression is true for given version
58
+ # @param ver [KXI::Application::Version] Right-side version of expression
59
+ # @return [bool] True if expression is valid; otherwise false
60
+ def matches?(ver)
61
+ case @comp
62
+ when COMP_EQ
63
+ return (
64
+ ver.major == @major and
65
+ ver.minor == (@minor == nil ? 0 : @minor) and
66
+ ver.patch == (@patch == nil ? 0 : @patch)
67
+ )
68
+ when COMP_AT
69
+ return (
70
+ ver.major == @major and
71
+ (@minor == nil or ver.minor == @minor) and
72
+ (@patch == nil or ver.patch == @patch)
73
+ )
74
+ when COMP_GEQ
75
+ return ver >= @target
76
+ when COMP_LEQ
77
+ return ver <= @target
78
+ when COMP_GT
79
+ return ver > @target
80
+ when COMP_LT
81
+ return ver < @target
82
+ end
83
+ end
84
+
85
+ # Parses a version expression from its string form
86
+ # @param [string] str String representation of version expression
87
+ # @return [KXI::Application::VersionExpression] Version expression equivalent to given string
88
+ def self.parse(str)
89
+ m = /^\s*(?'cm'>|<|>=|<=|=|~>)\s*(?'mj'\d+)\s*(\.\s*(?'mi'\d+))?\s*(\.\s*(?'pt'\d+))?\s*?$/m.match(str)
90
+ raise(KXI::Exceptions::ParseException.new('version expression', str)) if m == nil
91
+ return VersionExpression.new(m['cm'], m['mj'].to_i, m['mi']&.to_i, m['pt']&.to_i)
92
+ end
93
+ end
94
+ end
70
95
  end
@@ -0,0 +1,105 @@
1
+ # Created by Matyáš Pokorný on 2018-03-23.
2
+
3
+ module KXI
4
+ module Application
5
+ # Represents a workspace (directory)
6
+ class Workspace
7
+ # Instantiates the {KXI::Application::Workspace} class
8
+ # @param path [String] Path to workspace
9
+ # @param mk [Bool] True if workspace should be created; otherwise false
10
+ def initialize(path, mk = false)
11
+ @path = File.expand_path(path)
12
+ validate
13
+ make if mk
14
+ end
15
+
16
+ # Gets path relative to this workspace
17
+ # @param path [String] Parts of path
18
+ # @return [String] The combined path
19
+ def path(*path)
20
+ return @path if path.length == 0
21
+ return File.expand_path(File.join(@path, *path))
22
+ end
23
+
24
+ # Obtains the parent of this workspace, if it exists
25
+ # @return [KXI::Application::Workspace, nil] Parent workspace if any; nil otherwise
26
+ def parent
27
+ dir = File.dirname(@path)
28
+ return nil if KXI::Platform.this.path_case_sensitive? ? dir == @path : dir.downcase == @path.downcase
29
+ return KXI::Application::Workspace.new(dir)
30
+ end
31
+
32
+ # Checks if workspace physically exists in the file system
33
+ # @return [Bool] True if workspace exists; false otherwise
34
+ def made?
35
+ validate
36
+ return Dir.exists?(@path)
37
+ end
38
+
39
+ # Creates the workspace, if it doesn't exist
40
+ def make
41
+ validate
42
+ return if made?
43
+ p = parent
44
+ p.make unless parent == nil
45
+ Dir.mkdir(@path)
46
+ end
47
+
48
+ # Gets a child workspace
49
+ # @param [String] path Path to child workspace
50
+ # @return [KXI::Application::Workspace] Child workspace
51
+ def inner(*path)
52
+ return KXI::Application::Workspace.new(path(*path))
53
+ end
54
+
55
+ # Opens a file withing the workspace
56
+ # @overload open(mode, *path)
57
+ # @param mode [String] IO mode to open the file with
58
+ # @param path [String] Path to desired file
59
+ # @return [IO] File handle
60
+ # @overload open(mode, *path)
61
+ # @param mode [String] IO mode to open the file with
62
+ # @param path [String] Path to desired file
63
+ # @yield [handle] Block where file is used
64
+ # @yieldparam handle [IO] Handle of block
65
+ def open(mode, *path)
66
+ h = File.open(path(*path), mode)
67
+ return h unless block_given?
68
+ begin
69
+ yield(h)
70
+ ensure
71
+ h.flush
72
+ h.close
73
+ end
74
+ end
75
+
76
+ # Preforms lookup of files (glob)
77
+ # @param ptt [String, nil] Pattern for searching, returns all files if nil
78
+ # @param rec [Bool] Determines weather search is recursive
79
+ # @return [Array<String>] Found files
80
+ def files(ptt = nil, rec = true)
81
+ ptt = '*' if ptt == nil
82
+ ptt = File.join('**', ptt) if rec
83
+ return Dir.glob(path(ptt), File::FNM_DOTMATCH).select { |i| File.exists?(i) and not File.directory?(i) }.collect { |i| File.expand_path(i) }
84
+ end
85
+
86
+ # Preforms lookup of directories (glob)
87
+ # @param ptt [String, nil] Pattern for searching, returns all directories if nil
88
+ # @param rec [Bool] Determines weather search is recursive
89
+ # @return [Array<String>] Found directories
90
+ def dirs(ptt = nil, rec = true)
91
+ ptt = '*' if ptt == nil
92
+ ptt = File.join('**', ptt) if rec
93
+ return Dir.glob(path(ptt), File::FNM_DOTMATCH).select { |i| File.exists?(i) and File.directory?(i) }.collect { |i| File.expand_path(i) }
94
+ end
95
+
96
+ # Validates path of workspace
97
+ # @raise [KXI::Exceptions::WorkspaceCollisionException] If workspace path is used by file
98
+ def validate
99
+ raise(KXI::Exceptions::WorkspaceCollisionException.new(@path)) if File.exists?(@path) and not File.directory?(@path)
100
+ end
101
+
102
+ private :validate
103
+ end
104
+ end
105
+ end
@@ -1,51 +1,51 @@
1
- # Created by Matyáš Pokorný on 2018-01-20.
2
-
3
- module KXI
4
- module CLI
5
- # Represents anonymous argument (eg.: verb VALUE)
6
- class AnonymousArgument < KXI::CLI::Argument
7
- # Gets default value of argument
8
- # @return [Object] Default value of argument
9
- def default
10
- @def
11
- end
12
-
13
- # Gets whether argument is variadic
14
- # @return [Bool] True if argument is variadic; false otherwise
15
- def variadic?
16
- @var
17
- end
18
-
19
- # Gets syntax of argument
20
- # @return [String] Syntax of argument
21
- def syntax
22
- "#{required? ? '<' : '['}#{name}#{required? ? '>' : ']'}"
23
- end
24
-
25
- # Gets full descriptive name of argument
26
- # @return [String] Full name of argument
27
- def headline
28
- super.upcase
29
- end
30
-
31
- # Instantiates the {KXI::CLI::AnonymousArgument} class
32
- # @param nm [String] Name of argument
33
- # @param desc [String] Description of argument
34
- # @param rq [Bool] Indicates whether argument is required
35
- # @param df Default value of argument
36
- # @param var [Bool] Indicates whether argument is variadic
37
- def initialize(nm, desc, rq = true, df = nil, var = false, &validator)
38
- super(nm, desc, rq, 5 - (var ? 1 : 0) - (rq ? 0 : 1))
39
- @def = df
40
- @var = var
41
- @val = validator
42
- end
43
-
44
- # Validates value of argument
45
- # @param val [String, Array<String>] Value of argument
46
- def validate(val)
47
- @val.call(val) if @val != nil
48
- end
49
- end
50
- end
1
+ # Created by Matyáš Pokorný on 2018-01-20.
2
+
3
+ module KXI
4
+ module CLI
5
+ # Represents anonymous argument (eg.: verb VALUE)
6
+ class AnonymousArgument < KXI::CLI::Argument
7
+ # Gets default value of argument
8
+ # @return [Object] Default value of argument
9
+ def default
10
+ @def
11
+ end
12
+
13
+ # Gets whether argument is variadic
14
+ # @return [Bool] True if argument is variadic; false otherwise
15
+ def variadic?
16
+ @var
17
+ end
18
+
19
+ # Gets syntax of argument
20
+ # @return [String] Syntax of argument
21
+ def syntax
22
+ "#{required? ? '<' : '['}#{name}#{required? ? '>' : ']'}"
23
+ end
24
+
25
+ # Gets full descriptive name of argument
26
+ # @return [String] Full name of argument
27
+ def headline
28
+ super.upcase
29
+ end
30
+
31
+ # Instantiates the {KXI::CLI::AnonymousArgument} class
32
+ # @param nm [String] Name of argument
33
+ # @param desc [String] Description of argument
34
+ # @param rq [Bool] Indicates whether argument is required
35
+ # @param df Default value of argument
36
+ # @param var [Bool] Indicates whether argument is variadic
37
+ def initialize(nm, desc, rq = true, df = nil, var = false, &validator)
38
+ super(nm, desc, rq, 5 - (var ? 1 : 0) - (rq ? 0 : 1))
39
+ @def = df
40
+ @var = var
41
+ @val = validator
42
+ end
43
+
44
+ # Validates value of argument
45
+ # @param val [String, Array<String>] Value of argument
46
+ def validate(val)
47
+ @val.call(val) if @val != nil
48
+ end
49
+ end
50
+ end
51
51
  end
@@ -1,57 +1,57 @@
1
- # Created by Matyáš Pokorný on 2018-01-20.
2
-
3
- module KXI
4
- module CLI
5
- # Represents argument of command-line interface
6
- class Argument
7
- # Gets the name of argument
8
- # @return [String] Name of argument
9
- def name
10
- @name
11
- end
12
-
13
- # Gets syntax of argument
14
- # @return [String] Syntax of argument
15
- def syntax
16
- name
17
- end
18
-
19
- # Gets full descriptive name of argument
20
- # @return [String] Full name of argument
21
- def headline
22
- name
23
- end
24
-
25
- # Gets the description of argument
26
- # @return [String] Description of argument
27
- def description
28
- @desc
29
- end
30
-
31
- # Indicates whether argument is mandatory
32
- # @return [Bool] True if argument is mandatory; otherwise false
33
- def required?
34
- @req
35
- end
36
-
37
- # Gets the order of argument (in descending order)
38
- # @return [Number] Order of argument
39
- def order
40
- @order
41
- end
42
-
43
- # Instantiates the {KXI::CLI::Argument} class
44
- # @param nm [String] Name of argument
45
- # @param desc [String] Description of argument
46
- # @param req [Bool] Determines whether argument is mandatory
47
- # @param order [Number] Order of argument
48
- def initialize(nm, desc, req, order)
49
- raise(Exception.new('Invalid argument name!')) unless /^[A-Za-z0-9\-]+$/m =~ nm
50
- @name = nm.downcase
51
- @desc = desc
52
- @req = req
53
- @order = order
54
- end
55
- end
56
- end
1
+ # Created by Matyáš Pokorný on 2018-01-20.
2
+
3
+ module KXI
4
+ module CLI
5
+ # Represents argument of command-line interface
6
+ class Argument
7
+ # Gets the name of argument
8
+ # @return [String] Name of argument
9
+ def name
10
+ @name
11
+ end
12
+
13
+ # Gets syntax of argument
14
+ # @return [String] Syntax of argument
15
+ def syntax
16
+ name
17
+ end
18
+
19
+ # Gets full descriptive name of argument
20
+ # @return [String] Full name of argument
21
+ def headline
22
+ name
23
+ end
24
+
25
+ # Gets the description of argument
26
+ # @return [String] Description of argument
27
+ def description
28
+ @desc
29
+ end
30
+
31
+ # Indicates whether argument is mandatory
32
+ # @return [Bool] True if argument is mandatory; otherwise false
33
+ def required?
34
+ @req
35
+ end
36
+
37
+ # Gets the order of argument (in descending order)
38
+ # @return [Number] Order of argument
39
+ def order
40
+ @order
41
+ end
42
+
43
+ # Instantiates the {KXI::CLI::Argument} class
44
+ # @param nm [String] Name of argument
45
+ # @param desc [String] Description of argument
46
+ # @param req [Bool] Determines whether argument is mandatory
47
+ # @param order [Number] Order of argument
48
+ def initialize(nm, desc, req, order)
49
+ raise(Exception.new('Invalid argument name!')) unless /^[A-Za-z0-9\-]+$/m =~ nm
50
+ @name = nm.downcase
51
+ @desc = desc
52
+ @req = req
53
+ @order = order
54
+ end
55
+ end
56
+ end
57
57
  end