Class: Kube::Helm::CommandTree
- Inherits:
-
Object
- Object
- Kube::Helm::CommandTree
- Defined in:
- lib/kube/helm/command_tree.rb
Defined Under Namespace
Classes: Result
Instance Method Summary collapse
-
#evaluate(builder) ⇒ Object
Evaluate a StringBuilder buffer against the helm command tree.
-
#initialize(data) ⇒ CommandTree
constructor
Parses helm.yaml’s flat commands array.
Constructor Details
#initialize(data) ⇒ CommandTree
Parses helm.yaml’s flat commands array.
Each entry has a ‘name` like “helm”, “helm install”, “helm get values”. We split on spaces, skip the leading “helm” token, and insert into a tree rooted at a synthetic “helm” node.
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
# File 'lib/kube/helm/command_tree.rb', line 24 def initialize(data) @root = Kube::Ctl::CommandTree::Node.new(name: "helm") data.fetch("commands", []).each do |cmd| name = cmd["name"] next unless name parts = name.split # Skip the root "helm" entry itself (no subcommand path) next if parts.size <= 1 # Walk/create intermediate nodes, attach leaf with full metadata node = @root parts[1..].each_with_index do |part, idx| existing = node.find_subcommand(part) if idx == parts.size - 2 # Leaf node — build with full options/inherited_options/usage if existing # Node was pre-created as an intermediate; we can't easily # replace it, but the intermediate was created bare. In # practice the YAML lists parent commands before children, # so the parent entry is processed first and the intermediate # won't exist yet when we hit the leaf. But just in case, # use the existing node. node = existing else leaf = Kube::Ctl::CommandTree::Node.new( name: part, options: cmd["options"] || [], inherited_options: cmd["inherited_options"] || [], usage: cmd["usage"] ) node.add_subcommand(leaf) node = leaf end else if existing node = existing else # Create a bare intermediate node intermediate = Kube::Ctl::CommandTree::Node.new(name: part) node.add_subcommand(intermediate) node = intermediate end end end end end |
Instance Method Details
#evaluate(builder) ⇒ Object
Evaluate a StringBuilder buffer against the helm command tree.
Classifies tokens as:
- commands: matched subcommand path (e.g. ["repo", "add"])
- positional: bare tokens after commands (release names, chart refs, URLs)
- flags: tokens with arguments (--namespace default, --set foo=bar)
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 |
# File 'lib/kube/helm/command_tree.rb', line 79 def evaluate(builder) buffer = builder.to_a commands = [] positional = [] flags = [] errors = [] node = @root i = 0 # 1. Walk commands/subcommands while i < buffer.length entry = buffer[i] break unless entry.is_a?(Array) name, args = entry break unless args.empty? child = node.find_subcommand(name) break unless child commands << name node = child i += 1 # Consume :dash separated subcommand parts (e.g. insecure-skip-tls-verify) while i < buffer.length && buffer[i] == :dash next_i = i + 1 break unless next_i < buffer.length && buffer[next_i].is_a?(Array) next_name, next_args = buffer[next_i] break unless next_args.empty? hyphenated = "#{commands.last}-#{next_name}" child = node.find_subcommand(hyphenated) if child commands[-1] = hyphenated node = child i = next_i + 1 else break end end end if commands.empty? && buffer.any? first = buffer[0].is_a?(Array) ? buffer[0][0] : buffer[0].to_s errors << "invalid command start: `#{first}`" end # 2. Walk remaining buffer: classify as positional args or flags current_positional = nil while i < buffer.length entry = buffer[i] case entry when :dash current_positional = "#{current_positional}-" if current_positional i += 1 when :slash current_positional = "#{current_positional}/" if current_positional i += 1 when Array name, args = entry if args.nil? || args.empty? # Bare token — positional segment if current_positional && !current_positional.end_with?("-") && !current_positional.end_with?("/") # Flush previous positional and start a new one flush_positional(positional, current_positional) current_positional = name elsif current_positional # Continue building hyphenated/slashed positional current_positional = "#{current_positional}#{name}" else current_positional = name end i += 1 else # Has args — it's a flag flush_positional(positional, current_positional) current_positional = nil flag_name = name.tr("_", "-") prefix = name.length == 1 ? "-" : "--" if args == [true] flags << "#{prefix}#{flag_name}" else value = args.map(&:to_s).join(",") flags << "#{prefix}#{flag_name} #{value}" end i += 1 end else i += 1 end end flush_positional(positional, current_positional) Result.new(commands, positional, flags, errors, errors.empty?) end |