context_spook 0.5.0 → 0.6.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bf46500652e697db299ccdfe21d5dd4c02953b699ca528b21810f87348eddceb
4
- data.tar.gz: ad41e6c9f6141ba5303c845aaf26c2d141125201d82575834a62efc05c2ae7b8
3
+ metadata.gz: e70334ee77b21283268eaabfc74ea73593a375119003d74be68442188f4dbf5b
4
+ data.tar.gz: cc7ca13e3a403a97f16c897a797d0b2a4a92bba1b8e3da99adb199f807169b1c
5
5
  SHA512:
6
- metadata.gz: edab814b82519dc36f9bb01c4e59dfb372aad6c2e1fa0d8ef7f487a288281ad6bf9bf1474d09a7ff7b818c1a6140ef08c0ba464b986e9bf56a34bd2720f9e778
7
- data.tar.gz: 052e05ca7fc2825a75b43e1b9a8585344f9d4e8a6a805e3a5d826680d81bfed723d4359db7083d6451ce4afa6e35e82688a979dae0fcd0dcde401784d373b2de
6
+ metadata.gz: db73acce9ba9aa696619be04671adde77a115d63b2e2c48d559848cc3d02c608579982a29da2bba7bd70bda7a5fae5654828c6ad1f763e2b04094e47820c98e0
7
+ data.tar.gz: f95575da363d9c70d5f9303ce66bc13d8c2bb2e4c70c7c6074fe3c61f1bf35554dbfc68f286bf2eac2d4080fe39291ad4b1f2ce9ca0910560e2a4b86f5eb6154
data/.contexts/project.rb CHANGED
@@ -45,5 +45,9 @@ context do
45
45
 
46
46
  meta nixda_json: json('nixda_json.json')
47
47
 
48
+ meta hey_world: yaml('hey_world.yaml')
49
+
50
+ meta nixda_yaml: yaml('nixda_yaml.yaml')
51
+
48
52
  meta code_coverage: json('coverage/coverage_context.json')
49
53
  end
data/Rakefile CHANGED
@@ -36,6 +36,7 @@ GemHadar do
36
36
  dependency 'term-ansicolor', '~> 1.11'
37
37
  dependency 'mize', '~> 0.6'
38
38
  dependency 'mime-types', '~> 3.0'
39
+ dependency 'yaml', '~> 0.4'
39
40
  development_dependency 'all_images', '~> 0.6'
40
41
  development_dependency 'rspec', '~> 3.2'
41
42
  development_dependency 'debug'
@@ -1,9 +1,9 @@
1
1
  # -*- encoding: utf-8 -*-
2
- # stub: context_spook 0.5.0 ruby lib
2
+ # stub: context_spook 0.6.0 ruby lib
3
3
 
4
4
  Gem::Specification.new do |s|
5
5
  s.name = "context_spook".freeze
6
- s.version = "0.5.0".freeze
6
+ s.version = "0.6.0".freeze
7
7
 
8
8
  s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
9
9
  s.require_paths = ["lib".freeze]
@@ -13,7 +13,7 @@ Gem::Specification.new do |s|
13
13
  s.email = "flori@ping.de".freeze
14
14
  s.executables = ["context_spook".freeze]
15
15
  s.extra_rdoc_files = ["README.md".freeze, "lib/context_spook.rb".freeze, "lib/context_spook/generator.rb".freeze, "lib/context_spook/version.rb".freeze]
16
- s.files = [".contexts/project.rb".freeze, "Gemfile".freeze, "LICENSE".freeze, "README.md".freeze, "Rakefile".freeze, "bin/context_spook".freeze, "context_spook.gemspec".freeze, "hello_world.json".freeze, "lib/context_spook.rb".freeze, "lib/context_spook/generator.rb".freeze, "lib/context_spook/version.rb".freeze, "spec/context_spook/generator_spec.rb".freeze, "spec/spec_helper.rb".freeze]
16
+ s.files = [".contexts/project.rb".freeze, "Gemfile".freeze, "LICENSE".freeze, "README.md".freeze, "Rakefile".freeze, "bin/context_spook".freeze, "context_spook.gemspec".freeze, "hello_world.json".freeze, "hey_world.yaml".freeze, "lib/context_spook.rb".freeze, "lib/context_spook/generator.rb".freeze, "lib/context_spook/version.rb".freeze, "spec/context_spook/generator_spec.rb".freeze, "spec/spec_helper.rb".freeze]
17
17
  s.homepage = "https://github.com/flori/context_spook".freeze
18
18
  s.licenses = ["MIT".freeze]
19
19
  s.rdoc_options = ["--title".freeze, "ContextSpook - context_spook collects project context for AI".freeze, "--main".freeze, "README.md".freeze]
@@ -34,4 +34,5 @@ Gem::Specification.new do |s|
34
34
  s.add_runtime_dependency(%q<term-ansicolor>.freeze, ["~> 1.11".freeze])
35
35
  s.add_runtime_dependency(%q<mize>.freeze, ["~> 0.6".freeze])
36
36
  s.add_runtime_dependency(%q<mime-types>.freeze, ["~> 3.0".freeze])
37
+ s.add_runtime_dependency(%q<yaml>.freeze, ["~> 0.4".freeze])
37
38
  end
data/hey_world.yaml ADDED
@@ -0,0 +1,2 @@
1
+ ---
2
+ hey: world
@@ -3,12 +3,37 @@ require 'term/ansicolor'
3
3
  require 'json'
4
4
  require 'mize'
5
5
  require 'mime-types'
6
+ require 'yaml'
6
7
 
7
8
  # The ContextSpook module serves as a namespace container for collecting and
8
9
  # organizing project information for AI assistance.
9
10
  module ContextSpook
10
11
  include DSLKit::Interpreter
11
12
 
13
+ # The VerbosePuts module provides a conditional output mechanism for
14
+ # displaying status or debug messages.
15
+ #
16
+ # This module includes a method that outputs messages to standard error only
17
+ # when a verbose flag is enabled. It is designed to be included in classes
18
+ # that need to conditionally emit verbose logging information during
19
+ # processing.
20
+ module VerbosePuts
21
+ # The verbose_puts method outputs the given arguments to standard error
22
+ # only if verbose mode is enabled.
23
+ #
24
+ # This method serves as a conditional output mechanism, allowing debug or
25
+ # status messages to be displayed based on the verbosity setting of the
26
+ # object.
27
+ #
28
+ # @param a [ Array ] the arguments to be printed to standard error
29
+ #
30
+ # @return [ nil ] always returns nil after attempting to output
31
+ def verbose_puts(*a)
32
+ @verbose and return
33
+ STDERR.puts(a)
34
+ end
35
+ end
36
+
12
37
  # The generate_context method processes a context definition file or block
13
38
  # and returns the resulting context object.
14
39
  #
@@ -48,6 +73,8 @@ module ContextSpook
48
73
  # project metadata, file contents, command outputs, and variables for AI
49
74
  # assistance.
50
75
  class Generator
76
+ include VerbosePuts
77
+
51
78
  private_class_method :new
52
79
 
53
80
  # The initialize method sets up the object by evaluating the provided block
@@ -58,7 +85,7 @@ module ContextSpook
58
85
  # @param block [ Proc ] a block of code to be evaluated within the object's context
59
86
  # If no block is given, the method does nothing.
60
87
  def initialize(verbose: false, &block)
61
- @verbose = verbose
88
+ @verbose = !!verbose
62
89
  block and instance_eval(&block)
63
90
  end
64
91
 
@@ -70,7 +97,7 @@ module ContextSpook
70
97
  def context(&block)
71
98
  if block
72
99
  @context and raise ArgumentError, "only one context allowed"
73
- @context = Context.new(&block)
100
+ @context = Context.new(verbose: @verbose, &block)
74
101
  else
75
102
  @context
76
103
  end
@@ -87,24 +114,27 @@ module ContextSpook
87
114
  json_content_size = Tins::Unit.format(
88
115
  context_size, format: '%.2f %U', unit: ?b, prefix: 1024
89
116
  )
90
- if @verbose
91
- STDERR.puts "Built #{json_content_size} of JSON context in total."
92
- end
117
+ verbose_puts "Built #{json_content_size} of JSON context in total."
93
118
  end
94
119
 
95
120
  # The Context class represents and manages project context data, providing
96
121
  # structured storage for file contents, command outputs, variables, and
97
122
  # metadata that can be serialized to JSON for AI assistance.
98
123
  class Context
124
+ include VerbosePuts
99
125
  include Tins::Scope
100
126
  include Tins::DSLAccessor
101
127
  include Term::ANSIColor
102
128
 
103
- # The initialize method sets up the object by evaluating a block in the
104
- # object's context.
129
+ # The initialize method sets up the object by evaluating the provided block
130
+ # in the object's context.
105
131
  #
106
- # @param block [ Proc ] A block to be evaluated within the object's context.
107
- def initialize(&block)
132
+ # @param verbose [ TrueClass, FalseClass ] flag to enable verbose output
133
+ # during processing, defaults to false.
134
+ # @param block [ Proc ] a block of code to be evaluated within the object's context
135
+ # If no block is given, the method does nothing.
136
+ def initialize(verbose: false, &block)
137
+ @verbose = !!verbose
108
138
  block and instance_eval(&block)
109
139
  end
110
140
 
@@ -173,14 +203,34 @@ module ContextSpook
173
203
  file_size = Tins::Unit.format(
174
204
  File.size(filename), format: '%.2f %U', unit: ?b, prefix: 1024
175
205
  )
176
- if @verbose
177
- STDERR.puts "Read #{filename.inspect} as JSON (%s) for context." % file_size
178
- end
206
+ verbose_puts "Read #{filename.inspect} as JSON (%s) for context." % file_size
179
207
  JSON.load_file(filename)
180
- rescue Errno::ENOENT => e
181
- if @verbose
182
- STDERR.puts color(208) { "Reading #{filename.inspect} as JSON caused #{e.class}: #{e}" }
183
- end
208
+ rescue Errno::ENOENT, JSON::ParserError => e
209
+ verbose_puts color(208) { "Reading #{filename.inspect} as JSON caused #{e.class}: #{e}" }
210
+ nil
211
+ end
212
+
213
+ # The yaml method reads and parses a YAML file, returning the resulting
214
+ # data structure.
215
+ #
216
+ # This method attempts to load a YAML file from the specified path and
217
+ # returns the resulting Ruby data structure. It provides verbose output
218
+ # about the file size when successfully reading the file. In case of file
219
+ # not found errors or YAML syntax errors, it outputs a colored warning
220
+ # message to standard error and returns nil.
221
+ #
222
+ # @param filename [ String ] the path to the YAML file to be read and parsed
223
+ #
224
+ # @return [ Object, nil ] the parsed YAML data structure or nil if the
225
+ # file cannot be read
226
+ def yaml(filename)
227
+ file_size = Tins::Unit.format(
228
+ File.size(filename), format: '%.2f %U', unit: ?b, prefix: 1024
229
+ )
230
+ verbose_puts "Read #{filename.inspect} as YAML (%s) for context." % file_size
231
+ YAML.load_file(filename)
232
+ rescue Errno::ENOENT, Psych::SyntaxError => e
233
+ verbose_puts color(208) { "Reading #{filename.inspect} as YAML caused #{e.class}: #{e}" }
184
234
  nil
185
235
  end
186
236
 
@@ -214,14 +264,10 @@ module ContextSpook
214
264
  file_size = Tins::Unit.format(
215
265
  content.size, format: '%.2f %U', unit: ?b, prefix: 1024
216
266
  )
217
- if @verbose
218
- STDERR.puts "Read #{filename.inspect} (%s) for context." % file_size
219
- end
267
+ verbose_puts "Read #{filename.inspect} (%s) for context." % file_size
220
268
  nil
221
269
  rescue Errno::ENOENT => e
222
- if @verbose
223
- STDERR.puts color(208) { "Reading #{filename.inspect} caused #{e.class}: #{e}" }
224
- end
270
+ verbose_puts color(208) { "Reading #{filename.inspect} caused #{e.class}: #{e}" }
225
271
  end
226
272
 
227
273
  # The commands method sets up a DSL accessor for provided command outputs.
@@ -244,11 +290,9 @@ module ContextSpook
244
290
  output = `#{shell_command}`
245
291
  exit_code = $?&.exitstatus.to_i
246
292
  if exit_code != 0
247
- if @verbose
248
- STDERR.puts color(208) {
249
- "Executing #{shell_command.inspect} resulted in exit code #{exit_code}."
250
- }
251
- end
293
+ verbose_puts color(208) {
294
+ "Executing #{shell_command.inspect} resulted in exit code #{exit_code}."
295
+ }
252
296
  end
253
297
  commands[shell_command] = {
254
298
  namespace: scope_top,
@@ -260,9 +304,7 @@ module ContextSpook
260
304
  output_size = Tins::Unit.format(
261
305
  output.size, format: '%.2f %U', unit: ?b, prefix: 1024
262
306
  )
263
- if @verbose
264
- STDERR.puts "Executed #{shell_command.inspect} with output (%s) for context." % output_size
265
- end
307
+ verbose_puts "Executed #{shell_command.inspect} with output (%s) for context." % output_size
266
308
  nil
267
309
  end
268
310
 
@@ -1,6 +1,6 @@
1
1
  module ContextSpook
2
2
  # ContextSpook version
3
- VERSION = '0.5.0'
3
+ VERSION = '0.6.0'
4
4
  VERSION_ARRAY = VERSION.split('.').map(&:to_i) # :nodoc:
5
5
  VERSION_MAJOR = VERSION_ARRAY[0] # :nodoc:
6
6
  VERSION_MINOR = VERSION_ARRAY[1] # :nodoc:
@@ -2,7 +2,7 @@ require 'spec_helper'
2
2
 
3
3
  describe ContextSpook::Generator do
4
4
  let :context do
5
- ContextSpook.generate_context('.contexts/project.rb')
5
+ ContextSpook.generate_context('.contexts/project.rb', verbose: true)
6
6
  end
7
7
 
8
8
  it 'context can be generated from block' do
@@ -76,5 +76,37 @@ describe ContextSpook::Generator do
76
76
  it 'can have metada' do
77
77
  expect(context.metadata[:ruby]).to eq RUBY_DESCRIPTION
78
78
  end
79
+
80
+ it 'can have json metadata' do
81
+ expect(context.metadata[:hello_world]).to eq("hello" => "world")
82
+ end
83
+
84
+ it 'can have yaml metadata' do
85
+ expect(context.metadata[:hey_world]).to eq("hey" => "world")
86
+ end
87
+
88
+ it 'handles missing json files gracefully' do
89
+ expect(context.json('nixda.json')).to be_nil
90
+ end
91
+
92
+ it 'handles invalid json content gracefully' do
93
+ Tempfile.create('invalid.json') do |f|
94
+ f.write('{ invalid json }')
95
+ f.close
96
+ expect(context.json(f.path)).to be_nil
97
+ end
98
+ end
99
+
100
+ it 'handles missing yaml files gracefully' do
101
+ expect(context.yaml('nixda.yaml')).to be_nil
102
+ end
103
+
104
+ it 'handles invalid yaml content gracefully' do
105
+ Tempfile.create('invalid.yaml') do |f|
106
+ f.write('invalid: [yaml')
107
+ f.close
108
+ expect(context.yaml(f.path)).to be_nil
109
+ end
110
+ end
79
111
  end
80
112
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: context_spook
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Florian Frank
@@ -149,6 +149,20 @@ dependencies:
149
149
  - - "~>"
150
150
  - !ruby/object:Gem::Version
151
151
  version: '3.0'
152
+ - !ruby/object:Gem::Dependency
153
+ name: yaml
154
+ requirement: !ruby/object:Gem::Requirement
155
+ requirements:
156
+ - - "~>"
157
+ - !ruby/object:Gem::Version
158
+ version: '0.4'
159
+ type: :runtime
160
+ prerelease: false
161
+ version_requirements: !ruby/object:Gem::Requirement
162
+ requirements:
163
+ - - "~>"
164
+ - !ruby/object:Gem::Version
165
+ version: '0.4'
152
166
  description: |
153
167
  context_spook is a library that collects and organizes project
154
168
  information to help AI assistants understand codebases better.
@@ -170,6 +184,7 @@ files:
170
184
  - bin/context_spook
171
185
  - context_spook.gemspec
172
186
  - hello_world.json
187
+ - hey_world.yaml
173
188
  - lib/context_spook.rb
174
189
  - lib/context_spook/generator.rb
175
190
  - lib/context_spook/version.rb