magister_cli 1.0.0 → 1.1.1
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/lib/magister_cli/ext/string.rb +9 -0
- data/lib/magister_cli/parser.rb +119 -0
- data/lib/magister_cli/runtime.rb +73 -0
- data/lib/magister_cli/tokenizer.rb +86 -0
- data/lib/magister_cli.rb +59 -4
- metadata +23 -5
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 6e19320505e5f88d8b0e19157fff2e8be5e6c01b24cb1402c4f3cea6bb18e373
         | 
| 4 | 
            +
              data.tar.gz: a49f14db0b9e983e93faab5f0c3b348556537b22072d19f5b4cd82763af4ecf4
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 111c260237f9554a165433d577164749170f2bcac3149cd3f298d604fb6c0b68b78a2d80b2047da79ae9615dcbc4a65f3b141c04062c88c466b9bbef3acd6f18
         | 
| 7 | 
            +
              data.tar.gz: ce3b825f0507a925e13854f39201562466eb27246e09a1a2fc700db454bec58bf7f9981547ee01091101dbd4e409ff1e6302f1227d60b9755080736505c50c3c
         | 
| @@ -0,0 +1,9 @@ | |
| 1 | 
            +
            # This Source Code Form is subject to the terms of the Mozilla Public
         | 
| 2 | 
            +
            # License, v. 2.0. If a copy of the MPL was not distributed with this
         | 
| 3 | 
            +
            # file, You can obtain one at https://mozilla.org/MPL/2.0/.
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            class String
         | 
| 6 | 
            +
                def is_integer?
         | 
| 7 | 
            +
                    self.to_i.to_s == self
         | 
| 8 | 
            +
                end
         | 
| 9 | 
            +
            end
         | 
| @@ -0,0 +1,119 @@ | |
| 1 | 
            +
            # This Source Code Form is subject to the terms of the Mozilla Public
         | 
| 2 | 
            +
            # License, v. 2.0. If a copy of the MPL was not distributed with this
         | 
| 3 | 
            +
            # file, You can obtain one at https://mozilla.org/MPL/2.0/.
         | 
| 4 | 
            +
            require 'magister_cli/tokenizer'
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            class Parser
         | 
| 7 | 
            +
                @@actions = [
         | 
| 8 | 
            +
                    ['login', ['username', 'password', 'school']],
         | 
| 9 | 
            +
                    ['auth', ['token', 'school']],
         | 
| 10 | 
            +
                    ['quit', []],
         | 
| 11 | 
            +
                    ['exit', []],
         | 
| 12 | 
            +
                    ['get_classes', ['date_from', 'date_to']]
         | 
| 13 | 
            +
                ]
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                def initialize(string)
         | 
| 16 | 
            +
                    @tokenizer = Tokenizer.new(string)
         | 
| 17 | 
            +
                    @string = string
         | 
| 18 | 
            +
                end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                def is_action?(actionName)
         | 
| 21 | 
            +
                    @@actions.each do |action|
         | 
| 22 | 
            +
                        if action[0] == actionName
         | 
| 23 | 
            +
                            return true
         | 
| 24 | 
            +
                        end
         | 
| 25 | 
            +
                    end
         | 
| 26 | 
            +
                    return false
         | 
| 27 | 
            +
                end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                def string=(string)
         | 
| 30 | 
            +
                    @string = string
         | 
| 31 | 
            +
                    @tokenizer = Tokenizer.new(string)
         | 
| 32 | 
            +
                end
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                def get_args(actionName)
         | 
| 35 | 
            +
                    @@actions.each do |action|
         | 
| 36 | 
            +
                        if action[0] == actionName
         | 
| 37 | 
            +
                            return action[1].dup
         | 
| 38 | 
            +
                        end
         | 
| 39 | 
            +
                    end
         | 
| 40 | 
            +
                end
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                def parse()
         | 
| 43 | 
            +
                    tokens = @tokenizer.tokenize
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                    i = 0
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                    ast = Array.new
         | 
| 48 | 
            +
                    while i < tokens.length
         | 
| 49 | 
            +
                        tmp = 0
         | 
| 50 | 
            +
                        props = false
         | 
| 51 | 
            +
                        opts = false
         | 
| 52 | 
            +
                        altOpts = false # true if opts are in the place props would be
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                        if tokens[0 + i]["type"] != "KEYWORD"
         | 
| 55 | 
            +
                            puts "Current index: #{i.to_s}"
         | 
| 56 | 
            +
                            raise SyntaxError.new "Expected #{tokens[0 + i]["value"]} to be a KEYWORD, is a #{tokens[0 + i]["type"]}"
         | 
| 57 | 
            +
                        end
         | 
| 58 | 
            +
             | 
| 59 | 
            +
                        if tokens[1 + i] != nil && tokens[1 + i]["type"] == "PARAMS"
         | 
| 60 | 
            +
                            tmp += 1
         | 
| 61 | 
            +
                            props = true
         | 
| 62 | 
            +
                        end
         | 
| 63 | 
            +
             | 
| 64 | 
            +
                        if tokens[2 + i] != nil && tokens[2 + i]["type"] == "OPTIONS"
         | 
| 65 | 
            +
                            tmp += 1
         | 
| 66 | 
            +
                            opts = true
         | 
| 67 | 
            +
                        end
         | 
| 68 | 
            +
             | 
| 69 | 
            +
                        if tokens[1 + i] != nil && tokens[1 + i]["type"] == "OPTIONS"
         | 
| 70 | 
            +
                            if opts || props
         | 
| 71 | 
            +
                                raise SyntaxError.new "Cant have type OPTIONS here, must be PARAMS"
         | 
| 72 | 
            +
                            end
         | 
| 73 | 
            +
                            opts = true
         | 
| 74 | 
            +
                            altOpts = true
         | 
| 75 | 
            +
                            tmp += 1
         | 
| 76 | 
            +
                        end
         | 
| 77 | 
            +
             | 
| 78 | 
            +
                        ast_node = {"action" => tokens[0 + i]["value"]}
         | 
| 79 | 
            +
             | 
| 80 | 
            +
                        if props
         | 
| 81 | 
            +
                            ast_node["parameters"] = tokens[1 + i]["value"]
         | 
| 82 | 
            +
                        end
         | 
| 83 | 
            +
             | 
| 84 | 
            +
                        if opts
         | 
| 85 | 
            +
                            if altOpts
         | 
| 86 | 
            +
                                ast_node["options"] = tokens[1 + i]["value"]
         | 
| 87 | 
            +
                            else
         | 
| 88 | 
            +
                                ast_node["options"] = tokens[2 + i]["value"]
         | 
| 89 | 
            +
                            end
         | 
| 90 | 
            +
                        end
         | 
| 91 | 
            +
             | 
| 92 | 
            +
                        if !is_action? ast_node["action"]
         | 
| 93 | 
            +
                            throw SyntaxError.new "#{ast_node["action"]} is not a valid action!"
         | 
| 94 | 
            +
                        end
         | 
| 95 | 
            +
             | 
| 96 | 
            +
                        lacking = Array.new
         | 
| 97 | 
            +
                        lacking = get_args(ast_node["action"])
         | 
| 98 | 
            +
             | 
| 99 | 
            +
                        if props
         | 
| 100 | 
            +
                            ast_node["parameters"].each do |prop|
         | 
| 101 | 
            +
                                if !lacking.include? prop["key"]
         | 
| 102 | 
            +
                                    raise SyntaxError.new "#{prop["key"]} is is already defined or is not a valid parameter for #{ast_node["action"]}!"
         | 
| 103 | 
            +
                                end
         | 
| 104 | 
            +
                                lacking.delete prop["key"]
         | 
| 105 | 
            +
                            end
         | 
| 106 | 
            +
                        else
         | 
| 107 | 
            +
                            ast_node["parameters"] = Array.new
         | 
| 108 | 
            +
                        end
         | 
| 109 | 
            +
             | 
| 110 | 
            +
                        ast_node["lacking_params"] = lacking
         | 
| 111 | 
            +
             | 
| 112 | 
            +
                        ast.append(ast_node)
         | 
| 113 | 
            +
             | 
| 114 | 
            +
                        i += tmp + 1 # + 1 for the keyword itself
         | 
| 115 | 
            +
                    end
         | 
| 116 | 
            +
             | 
| 117 | 
            +
                    ast
         | 
| 118 | 
            +
                end
         | 
| 119 | 
            +
            end
         | 
| @@ -0,0 +1,73 @@ | |
| 1 | 
            +
            # This Source Code Form is subject to the terms of the Mozilla Public
         | 
| 2 | 
            +
            # License, v. 2.0. If a copy of the MPL was not distributed with this
         | 
| 3 | 
            +
            # file, You can obtain one at https://mozilla.org/MPL/2.0/.
         | 
| 4 | 
            +
            require 'magister'
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            def zulu_to_ams(string)
         | 
| 7 | 
            +
                ("%02d" % (string[0..1].to_i + 1)).to_s + string[2..-1]
         | 
| 8 | 
            +
            end
         | 
| 9 | 
            +
             | 
| 10 | 
            +
            module Runners
         | 
| 11 | 
            +
                def login(username, password, school)
         | 
| 12 | 
            +
                    $magcli_runtime_variables["magister"].login(school, username, password)
         | 
| 13 | 
            +
                end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                def auth(token, school)
         | 
| 16 | 
            +
                    $magcli_runtime_variables["magister"].authenticate(school, token)
         | 
| 17 | 
            +
                end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                def get_classes(date_from, date_to)
         | 
| 20 | 
            +
                    classes = $magcli_runtime_variables["magister"].get_classes(date_from, date_to)
         | 
| 21 | 
            +
                    if classes == nil
         | 
| 22 | 
            +
                        raise "Couldn't fetch classes!"
         | 
| 23 | 
            +
                    end
         | 
| 24 | 
            +
                    if @opts["outputMode"]
         | 
| 25 | 
            +
                        classes.each do |c|
         | 
| 26 | 
            +
                            puts "|#{zulu_to_ams c.classStart.to_s[11..-13]} - #{zulu_to_ams c.classEndInclusive.to_s[11..-13]}| #{c.description} [#{c.location}]"
         | 
| 27 | 
            +
                        end
         | 
| 28 | 
            +
                    else
         | 
| 29 | 
            +
                        puts classes.to_json
         | 
| 30 | 
            +
                    end
         | 
| 31 | 
            +
                end
         | 
| 32 | 
            +
            end
         | 
| 33 | 
            +
             | 
| 34 | 
            +
            class Runtime
         | 
| 35 | 
            +
                include Runners
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                @@spec = {
         | 
| 38 | 
            +
                    "login" => :login,
         | 
| 39 | 
            +
                    "auth" => :auth,
         | 
| 40 | 
            +
                    "quit" => :exit,
         | 
| 41 | 
            +
                    "exit" => :exit,
         | 
| 42 | 
            +
                    "get_classes" => :get_classes
         | 
| 43 | 
            +
                }
         | 
| 44 | 
            +
                def initialize(action)
         | 
| 45 | 
            +
                    if action["options"] != nil
         | 
| 46 | 
            +
                        @opts = action["options"]
         | 
| 47 | 
            +
                    else
         | 
| 48 | 
            +
                        @opts = {"outputMode" => "formatted"}
         | 
| 49 | 
            +
                    end
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                    if @opts["noCache"] != nil && @opts["noCache"] == "true"
         | 
| 52 | 
            +
                        $magister_useCache = false
         | 
| 53 | 
            +
                    else
         | 
| 54 | 
            +
                        $magister_useCache = true
         | 
| 55 | 
            +
                    end
         | 
| 56 | 
            +
             | 
| 57 | 
            +
                    requiredArgs = Parser.new("").get_args(action["action"])
         | 
| 58 | 
            +
                    args = Array.new
         | 
| 59 | 
            +
             | 
| 60 | 
            +
                    if action["parameters"] == nil
         | 
| 61 | 
            +
                        raise "Not a single parameter defined!! not even an empty array!"
         | 
| 62 | 
            +
                    end
         | 
| 63 | 
            +
             | 
| 64 | 
            +
                    requiredArgs.each do |arg|
         | 
| 65 | 
            +
                        action["parameters"].each do |param|
         | 
| 66 | 
            +
                            if arg == param["key"]
         | 
| 67 | 
            +
                                args.append(param["value"])
         | 
| 68 | 
            +
                            end
         | 
| 69 | 
            +
                        end
         | 
| 70 | 
            +
                    end
         | 
| 71 | 
            +
                    send(@@spec[action["action"]], *args)
         | 
| 72 | 
            +
                end
         | 
| 73 | 
            +
            end
         | 
| @@ -0,0 +1,86 @@ | |
| 1 | 
            +
            # This Source Code Form is subject to the terms of the Mozilla Public
         | 
| 2 | 
            +
            # License, v. 2.0. If a copy of the MPL was not distributed with this
         | 
| 3 | 
            +
            # file, You can obtain one at https://mozilla.org/MPL/2.0/.
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            class Tokenizer
         | 
| 6 | 
            +
                @@spec = [
         | 
| 7 | 
            +
                    [/(\w+)/, "KEYWORD"],
         | 
| 8 | 
            +
                    [/(?:\w+\s?){(.*)}/, "PARAMS"],
         | 
| 9 | 
            +
                    [/(?:\w+\s?(?:{.*}\s?)?)\[(.*)\]/, "OPTIONS"],
         | 
| 10 | 
            +
                    [/(\s+)/, "EMPTY"]
         | 
| 11 | 
            +
                ]
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                def initialize(string)
         | 
| 14 | 
            +
                    @string = string
         | 
| 15 | 
            +
                end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                def parse_options(optionsString)
         | 
| 18 | 
            +
                    cursor = 0
         | 
| 19 | 
            +
                    found = Array.new
         | 
| 20 | 
            +
                    while cursor < optionsString.length
         | 
| 21 | 
            +
                        scope = optionsString[cursor..-1]
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                        if scope[0] == "{" || scope[0] == "}" || scope[0] == "[" || scope[0] == "]"
         | 
| 24 | 
            +
                            cursor += 1
         | 
| 25 | 
            +
                            next
         | 
| 26 | 
            +
                        end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                        whiteSpaceMatch = scope.match /^\s+/
         | 
| 29 | 
            +
                        if whiteSpaceMatch != nil
         | 
| 30 | 
            +
                            cursor += whiteSpaceMatch[0].length
         | 
| 31 | 
            +
                            next
         | 
| 32 | 
            +
                        end
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                        keywordMatch = scope.match /^\w+\s?:/
         | 
| 35 | 
            +
                        if keywordMatch != nil
         | 
| 36 | 
            +
                            cursor += keywordMatch[0].length
         | 
| 37 | 
            +
                            found.append({"type" => "KEYWORD", "value" => keywordMatch[0][0..-2]})
         | 
| 38 | 
            +
                            next
         | 
| 39 | 
            +
                        end
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                        explicitString = scope.match /^'([^']*)',*/
         | 
| 42 | 
            +
                        if explicitString != nil
         | 
| 43 | 
            +
                            cursor += explicitString[0].length
         | 
| 44 | 
            +
                            found.append({"type" => "STRING", "value" => explicitString.captures[0]})
         | 
| 45 | 
            +
                            next
         | 
| 46 | 
            +
                        end
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                        impliedString = scope.match /^(.*?),*/
         | 
| 49 | 
            +
                        if impliedString != nil
         | 
| 50 | 
            +
                            cursor += impliedString[0].length
         | 
| 51 | 
            +
                            found.append({"type" => "STRING", "value" => impliedString.captures[0]})
         | 
| 52 | 
            +
                            next
         | 
| 53 | 
            +
                        end
         | 
| 54 | 
            +
                    end
         | 
| 55 | 
            +
                    parsed = Array.new
         | 
| 56 | 
            +
                    i = 0
         | 
| 57 | 
            +
                    while i < found.length
         | 
| 58 | 
            +
                        if found[i]["type"] != "KEYWORD" || found[i + 1]["type"] != "STRING"
         | 
| 59 | 
            +
                            raise TypeError.new "Expected #{found[i]["value"]} to be a KEYWORD and #{found[i + 1]["value"]} to be a STRING"
         | 
| 60 | 
            +
                        end
         | 
| 61 | 
            +
             | 
| 62 | 
            +
                        parsed.append({"type" => "PROPERTY", "key" => found[i]["value"], "value" => found[i + 1]["value"]})
         | 
| 63 | 
            +
             | 
| 64 | 
            +
                        i += 2
         | 
| 65 | 
            +
                    end
         | 
| 66 | 
            +
                    parsed
         | 
| 67 | 
            +
                end
         | 
| 68 | 
            +
             | 
| 69 | 
            +
                def tokenize
         | 
| 70 | 
            +
                    @tokens = Array.new
         | 
| 71 | 
            +
                    @@spec.each do |item|
         | 
| 72 | 
            +
                        matched = @string.match item[0]
         | 
| 73 | 
            +
                        if matched != nil
         | 
| 74 | 
            +
                            matched.captures.each do |match|
         | 
| 75 | 
            +
                                if item[1] == "PARAMS" || item[1] == "OPTIONS"
         | 
| 76 | 
            +
                                    @tokens.append({"type" => item[1], "value" => parse_options(match)})
         | 
| 77 | 
            +
                                elsif item[1] == "EMPTY"
         | 
| 78 | 
            +
                                else
         | 
| 79 | 
            +
                                    @tokens.append({"type" => item[1], "value" => match})
         | 
| 80 | 
            +
                                end
         | 
| 81 | 
            +
                            end
         | 
| 82 | 
            +
                        end
         | 
| 83 | 
            +
                    end
         | 
| 84 | 
            +
                    @tokens
         | 
| 85 | 
            +
                end
         | 
| 86 | 
            +
            end
         | 
    
        data/lib/magister_cli.rb
    CHANGED
    
    | @@ -2,13 +2,24 @@ | |
| 2 2 | 
             
            # License, v. 2.0. If a copy of the MPL was not distributed with this
         | 
| 3 3 | 
             
            # file, You can obtain one at https://mozilla.org/MPL/2.0/.
         | 
| 4 4 | 
             
            require 'magister'
         | 
| 5 | 
            +
            require 'magister_cli/ext/string'
         | 
| 6 | 
            +
            require 'magister_cli/parser'
         | 
| 7 | 
            +
            require 'magister_cli/tokenizer'
         | 
| 8 | 
            +
            require 'magister_cli/runtime'
         | 
| 9 | 
            +
            require 'io/console'
         | 
| 10 | 
            +
             | 
| 11 | 
            +
            $magister_cachingDirectory = Dir.home + "/.cache/magister"
         | 
| 5 12 |  | 
| 6 13 | 
             
            $magcli_runmode = "normal"
         | 
| 14 | 
            +
            $magcli_runtime_variables = {}
         | 
| 7 15 |  | 
| 8 16 | 
             
            module MagisterCLI
         | 
| 9 17 | 
             
                extend self
         | 
| 10 18 |  | 
| 11 19 | 
             
                def main
         | 
| 20 | 
            +
                  $magcli_runtime_variables["magister"] = Magister.new
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                  begin
         | 
| 12 23 | 
             
                    if ARGV.include?("-r") || ARGV.include?("--run")
         | 
| 13 24 | 
             
                        $magcli_runmode = "inline"
         | 
| 14 25 | 
             
                        args = ARGV
         | 
| @@ -27,9 +38,53 @@ module MagisterCLI | |
| 27 38 | 
             
                        return
         | 
| 28 39 | 
             
                    end
         | 
| 29 40 |  | 
| 30 | 
            -
                     | 
| 31 | 
            -
                     | 
| 32 | 
            -
             | 
| 33 | 
            -
             | 
| 41 | 
            +
                    parser = Parser.new("")
         | 
| 42 | 
            +
                    while true
         | 
| 43 | 
            +
                      print "> "
         | 
| 44 | 
            +
                      input = gets.chomp
         | 
| 45 | 
            +
                      parser.string = input
         | 
| 46 | 
            +
                      output = parser.parse
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                      # loop over each action that was outputted
         | 
| 49 | 
            +
                      output.each do |action|
         | 
| 50 | 
            +
                        props = action["parameters"]
         | 
| 51 | 
            +
                        doneParams = Array.new
         | 
| 52 | 
            +
                        # get any parametres that werent set and ask then set them
         | 
| 53 | 
            +
                        action["lacking_params"].each do |param|
         | 
| 54 | 
            +
                          print "#{param}: "
         | 
| 55 | 
            +
                          if param == "password"
         | 
| 56 | 
            +
                            ans = STDIN.noecho(&:gets).chomp
         | 
| 57 | 
            +
                            print "\n"
         | 
| 58 | 
            +
                          else
         | 
| 59 | 
            +
                            ans = gets.chomp
         | 
| 60 | 
            +
                          end
         | 
| 61 | 
            +
                          props.append({"type" => "PROPERTY", "key" => param, "value" => ans})
         | 
| 62 | 
            +
                          doneParams.append param
         | 
| 63 | 
            +
                        end
         | 
| 64 | 
            +
             | 
| 65 | 
            +
                        # update lacking_params value, done here as to not mess with the order while looping over them
         | 
| 66 | 
            +
                        doneParams.each do |p|
         | 
| 67 | 
            +
                          action["lacking_params"].delete(p)
         | 
| 68 | 
            +
                        end
         | 
| 69 | 
            +
                        action["parameters"] = props
         | 
| 70 | 
            +
                        props = Array.new
         | 
| 71 | 
            +
             | 
| 72 | 
            +
                        runtime = Runtime.new(action)
         | 
| 73 | 
            +
                      end
         | 
| 74 | 
            +
                    end
         | 
| 75 | 
            +
                  rescue SignalException
         | 
| 76 | 
            +
                    $magcli_runtime_variables = Array.new
         | 
| 77 | 
            +
                    puts "[CTRL + C]\nExiting..."
         | 
| 78 | 
            +
                    exit
         | 
| 79 | 
            +
                  rescue UncaughtThrowError => e
         | 
| 80 | 
            +
                    if e.message.include? "#<SyntaxError: "
         | 
| 81 | 
            +
                      message = e.message.split("#<SyntaxError: ").last[0..-2]
         | 
| 82 | 
            +
                      puts "Invalid syntax: #{message}"
         | 
| 83 | 
            +
                    else
         | 
| 84 | 
            +
                      puts "Something went wrong: #{e.message}"
         | 
| 85 | 
            +
                    end
         | 
| 86 | 
            +
                  rescue => e
         | 
| 87 | 
            +
                    puts "Something went wrong: #{e.message}"
         | 
| 88 | 
            +
                  end
         | 
| 34 89 | 
             
                end
         | 
| 35 90 | 
             
            end
         | 
    
        metadata
    CHANGED
    
    | @@ -1,15 +1,29 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: magister_cli
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 1. | 
| 4 | 
            +
              version: 1.1.1
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Riley0122
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2024- | 
| 12 | 
            -
            dependencies: | 
| 11 | 
            +
            date: 2024-12-18 00:00:00.000000000 Z
         | 
| 12 | 
            +
            dependencies:
         | 
| 13 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 14 | 
            +
              name: json
         | 
| 15 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 16 | 
            +
                requirements:
         | 
| 17 | 
            +
                - - ">="
         | 
| 18 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 19 | 
            +
                    version: '0'
         | 
| 20 | 
            +
              type: :runtime
         | 
| 21 | 
            +
              prerelease: false
         | 
| 22 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 23 | 
            +
                requirements:
         | 
| 24 | 
            +
                - - ">="
         | 
| 25 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 26 | 
            +
                    version: '0'
         | 
| 13 27 | 
             
            description: The CLI for the 'magister' gem
         | 
| 14 28 | 
             
            email: contact@riley0122.dev
         | 
| 15 29 | 
             
            executables:
         | 
| @@ -19,11 +33,15 @@ extra_rdoc_files: [] | |
| 19 33 | 
             
            files:
         | 
| 20 34 | 
             
            - bin/magister
         | 
| 21 35 | 
             
            - lib/magister_cli.rb
         | 
| 22 | 
            -
             | 
| 36 | 
            +
            - lib/magister_cli/ext/string.rb
         | 
| 37 | 
            +
            - lib/magister_cli/parser.rb
         | 
| 38 | 
            +
            - lib/magister_cli/runtime.rb
         | 
| 39 | 
            +
            - lib/magister_cli/tokenizer.rb
         | 
| 40 | 
            +
            homepage: https://github.com/riley0122/rubymag/tree/main/cli#readme
         | 
| 23 41 | 
             
            licenses:
         | 
| 24 42 | 
             
            - MPL-2.0
         | 
| 25 43 | 
             
            metadata:
         | 
| 26 | 
            -
              source_code_uri: https://github.com/riley0122/rubymag/cli
         | 
| 44 | 
            +
              source_code_uri: https://github.com/riley0122/rubymag/tree/main/cli
         | 
| 27 45 | 
             
            post_install_message: 
         | 
| 28 46 | 
             
            rdoc_options: []
         | 
| 29 47 | 
             
            require_paths:
         |