Class: Aidp::Setup::Devcontainer::Parser
- Inherits:
-
Object
- Object
- Aidp::Setup::Devcontainer::Parser
- Defined in:
- lib/aidp/setup/devcontainer/parser.rb
Overview
Parses existing devcontainer.json files and extracts configuration for pre-filling wizard defaults.
Defined Under Namespace
Classes: DevcontainerNotFoundError, InvalidDevcontainerError
Constant Summary collapse
- STANDARD_LOCATIONS =
[ ".devcontainer/devcontainer.json", ".devcontainer.json", "devcontainer.json" ].freeze
Instance Attribute Summary collapse
-
#comments ⇒ Object
readonly
Returns the value of attribute comments.
-
#config ⇒ Object
readonly
Returns the value of attribute config.
-
#devcontainer_path ⇒ Object
readonly
Returns the value of attribute devcontainer_path.
-
#project_dir ⇒ Object
readonly
Returns the value of attribute project_dir.
Instance Method Summary collapse
-
#detect ⇒ String?
Detect devcontainer.json in standard locations.
-
#devcontainer_exists? ⇒ Boolean
Check if devcontainer exists.
-
#extract_customizations ⇒ Hash
Extract VS Code customizations.
-
#extract_env ⇒ Hash
Extract container environment variables.
-
#extract_features ⇒ Array<String>
Extract devcontainer features.
-
#extract_image_config ⇒ Hash
Extract the base image or dockerfile reference.
-
#extract_ports ⇒ Array<Hash>
Extract port forwarding configuration.
-
#extract_post_commands ⇒ Hash
Extract post-create and post-start commands.
-
#extract_remote_user ⇒ String?
Extract remote user setting.
-
#extract_workspace_folder ⇒ String?
Extract working directory.
-
#initialize(project_dir = Dir.pwd) ⇒ Parser
constructor
A new instance of Parser.
-
#parse ⇒ Hash
Parse devcontainer.json and extract configuration.
-
#to_h ⇒ Hash
Get complete parsed configuration as hash.
Constructor Details
#initialize(project_dir = Dir.pwd) ⇒ Parser
Returns a new instance of Parser.
24 25 26 27 28 |
# File 'lib/aidp/setup/devcontainer/parser.rb', line 24 def initialize(project_dir = Dir.pwd) @project_dir = project_dir @devcontainer_path = nil @config = nil end |
Instance Attribute Details
#comments ⇒ Object (readonly)
Returns the value of attribute comments.
22 23 24 |
# File 'lib/aidp/setup/devcontainer/parser.rb', line 22 def comments @comments end |
#config ⇒ Object (readonly)
Returns the value of attribute config.
22 23 24 |
# File 'lib/aidp/setup/devcontainer/parser.rb', line 22 def config @config end |
#devcontainer_path ⇒ Object (readonly)
Returns the value of attribute devcontainer_path.
22 23 24 |
# File 'lib/aidp/setup/devcontainer/parser.rb', line 22 def devcontainer_path @devcontainer_path end |
#project_dir ⇒ Object (readonly)
Returns the value of attribute project_dir.
22 23 24 |
# File 'lib/aidp/setup/devcontainer/parser.rb', line 22 def project_dir @project_dir end |
Instance Method Details
#detect ⇒ String?
Detect devcontainer.json in standard locations
32 33 34 35 36 37 38 39 40 41 42 43 44 |
# File 'lib/aidp/setup/devcontainer/parser.rb', line 32 def detect STANDARD_LOCATIONS.each do |location| path = File.join(project_dir, location) if File.exist?(path) @devcontainer_path = path Aidp.log_debug("devcontainer_parser", "detected devcontainer", path: path) return path end end Aidp.log_debug("devcontainer_parser", "no devcontainer found") nil end |
#devcontainer_exists? ⇒ Boolean
Check if devcontainer exists
48 49 50 |
# File 'lib/aidp/setup/devcontainer/parser.rb', line 48 def devcontainer_exists? !detect.nil? end |
#extract_customizations ⇒ Hash
Extract VS Code customizations
167 168 169 170 171 172 173 174 175 176 177 |
# File 'lib/aidp/setup/devcontainer/parser.rb', line 167 def extract_customizations ensure_parsed customizations = @config["customizations"] || {} vscode = customizations["vscode"] || {} { extensions: Array(vscode["extensions"]), settings: vscode["settings"] || {} } end |
#extract_env ⇒ Hash
Extract container environment variables
136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 |
# File 'lib/aidp/setup/devcontainer/parser.rb', line 136 def extract_env ensure_parsed env = @config["containerEnv"] || @config["remoteEnv"] || {} env = {} unless env.is_a?(Hash) # Filter out sensitive values filtered_env = env.reject { |key, value| sensitive_key?(key) || sensitive_value?(value) } Aidp.log_debug("devcontainer_parser", "extracted env vars", total: env.size, filtered: filtered_env.size) filtered_env end |
#extract_features ⇒ Array<String>
Extract devcontainer features
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
# File 'lib/aidp/setup/devcontainer/parser.rb', line 115 def extract_features ensure_parsed features = @config["features"] || {} # Handle both object and array format feature_list = case features when Hash features.keys when Array features else [] end Aidp.log_debug("devcontainer_parser", "extracted features", count: feature_list.size) feature_list end |
#extract_image_config ⇒ Hash
Extract the base image or dockerfile reference
195 196 197 198 199 200 201 202 203 204 |
# File 'lib/aidp/setup/devcontainer/parser.rb', line 195 def extract_image_config ensure_parsed { image: @config["image"], dockerfile: @config["dockerFile"] || @config["dockerfile"], context: @config["context"], build: @config["build"] }.compact end |
#extract_ports ⇒ Array<Hash>
Extract port forwarding configuration
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 |
# File 'lib/aidp/setup/devcontainer/parser.rb', line 83 def extract_ports ensure_parsed ports = [] # Extract from forwardPorts array forward_ports = @config["forwardPorts"] || [] forward_ports = [forward_ports] unless forward_ports.is_a?(Array) # Get port attributes for labels port_attrs = @config["portsAttributes"] || {} forward_ports.each do |port| port_num = port.to_i next if port_num <= 0 attrs = port_attrs[port.to_s] || port_attrs[port_num.to_s] || {} ports << { number: port_num, label: attrs["label"], protocol: attrs["protocol"] || "http", on_auto_forward: attrs["onAutoForward"] || "notify" } end Aidp.log_debug("devcontainer_parser", "extracted ports", count: ports.size) ports end |
#extract_post_commands ⇒ Hash
Extract post-create and post-start commands
155 156 157 158 159 160 161 162 163 |
# File 'lib/aidp/setup/devcontainer/parser.rb', line 155 def extract_post_commands ensure_parsed { post_create: @config["postCreateCommand"], post_start: @config["postStartCommand"], post_attach: @config["postAttachCommand"] }.compact end |
#extract_remote_user ⇒ String?
Extract remote user setting
181 182 183 184 |
# File 'lib/aidp/setup/devcontainer/parser.rb', line 181 def extract_remote_user ensure_parsed @config["remoteUser"] end |
#extract_workspace_folder ⇒ String?
Extract working directory
188 189 190 191 |
# File 'lib/aidp/setup/devcontainer/parser.rb', line 188 def extract_workspace_folder ensure_parsed @config["workspaceFolder"] end |
#parse ⇒ Hash
Parse devcontainer.json and extract configuration
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
# File 'lib/aidp/setup/devcontainer/parser.rb', line 56 def parse detect unless @devcontainer_path unless @devcontainer_path raise DevcontainerNotFoundError, "No devcontainer.json found in #{project_dir}" end begin content = File.read(@devcontainer_path) document = JsoncDocument.parse(content) @config = document.data @comments = document.comments Aidp.log_debug("devcontainer_parser", "parsed devcontainer", features_count: extract_features.size, ports_count: extract_ports.size) @config rescue JsoncDocument::ParseError, JSON::ParserError => e Aidp.log_error("devcontainer_parser", "invalid JSON", error: e., path: @devcontainer_path) raise InvalidDevcontainerError, "Invalid JSON in #{@devcontainer_path}: #{e.}" rescue => e Aidp.log_error("devcontainer_parser", "failed to read devcontainer", error: e.) raise InvalidDevcontainerError, "Failed to read #{@devcontainer_path}: #{e.}" end end |
#to_h ⇒ Hash
Get complete parsed configuration as hash
208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 |
# File 'lib/aidp/setup/devcontainer/parser.rb', line 208 def to_h ensure_parsed { path: @devcontainer_path, ports: extract_ports, features: extract_features, env: extract_env, post_commands: extract_post_commands, customizations: extract_customizations, remote_user: extract_remote_user, workspace_folder: extract_workspace_folder, image_config: extract_image_config, raw: @config } end |