Class: Documinty::Store

Inherits:
Object
  • Object
show all
Defined in:
lib/documinty/store.rb

Constant Summary collapse

CONFIG_DIR =
'.documinty'.freeze
CONFIG_FILE =
'config.yml'.freeze
FEATURES_DIR =
'features'.freeze
FEATURE_EXT =
'.yml'.freeze

Instance Method Summary collapse

Constructor Details

#initialize(root = Dir.pwd) ⇒ Store

Returns a new instance of Store.



13
14
15
16
17
# File 'lib/documinty/store.rb', line 13

def initialize(root = Dir.pwd)
  @root          = root
  @base_path     = File.join(@root, CONFIG_DIR)
  @features_path = File.join(@base_path, FEATURES_DIR)
end

Instance Method Details

#add_entry(path:, node:, feature:, methods: [], timestamp:, description: '') ⇒ Object

─── Entries API ──────────────────────────────────────────────────────────Tag a file under a specific feature

Raises:



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/documinty/store.rb', line 46

def add_entry(path:, node:, feature:, methods: [], timestamp:, description: '')
  file = feature_file(feature)
  raise Error, "Feature '#{feature}' does not exist" unless File.exist?(file)

  data    = YAML.load_file(file) || {}
  entries = (data['entries'] ||= [])
  entry   = {
    'path'        => path,
    'node'        => node.to_s,
    'feature'     => feature,
    'methods'     => Array(methods).map(&:to_s),
    'description' => description.to_s.strip,
    'timestamp'   => timestamp
  }
  entries << entry
  File.write(file, data.to_yaml)
  entry
end

#add_feature(name) ⇒ Object

─── Features API ─────────────────────────────────────────────────────────Create a new feature file (errors if it already exists)

Raises:



30
31
32
33
34
35
36
# File 'lib/documinty/store.rb', line 30

def add_feature(name)
  path = feature_file(name)
  raise Error, "Feature '#{name}' already exists" if File.exist?(path)

  File.write(path, { 'entries' => [] }.to_yaml)
  name
end

#entries_for(path) ⇒ Object

Return all entries across all features for a given file path



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/documinty/store.rb', line 66

def entries_for(path)
  results = []
  features.each do |feature|
    file = feature_file(feature)
    next unless File.exist?(file)
    data = YAML.load_file(file) || {}
    (data['entries'] || []).each do |e|
      if e['path'] == path
        e['feature'] ||= feature
        results << e
      end
    end
  end
  results
end

#entries_for_feature(feature) ⇒ Object

Shows all the files listed under a feature

Raises:



98
99
100
101
102
103
104
# File 'lib/documinty/store.rb', line 98

def entries_for_feature(feature)
  file = feature_file(feature)
  raise Error, "Feature '#{feature}' does not exist" unless File.exist?(file)

  data = YAML.load_file(file) || {}
  data['entries'] || []
end

#featuresObject

List all defined feature names



39
40
41
42
# File 'lib/documinty/store.rb', line 39

def features
  Dir.glob(File.join(@features_path, "*#{FEATURE_EXT}"))
     .map { |f| File.basename(f, FEATURE_EXT) }
end

#init(codebase_name: nil) ⇒ Object

─── bootstrap ────────────────────────────────────────────────────────────Create .documinty/, write config.yml, and make the features/ dir



21
22
23
24
25
26
# File 'lib/documinty/store.rb', line 21

def init(codebase_name: nil)
  FileUtils.mkdir_p(@features_path)
  cfg = { 'codebase_name' => (codebase_name || default_codebase_name) }
  File.write(File.join(@base_path, CONFIG_FILE), cfg.to_yaml)
  puts "✅ Initialized documinty at #{File.join(@root, CONFIG_DIR)}"
end

#methods(path:, feature:, new_methods:, action:) ⇒ Hash

Add one or more methods to a documented file under a given feature

Parameters:

  • path (String)

    relative file path

  • feature (String)

    feature name (must already exist on that entry)

  • new_methods (Array<Symbol>)

    list of symbols to add

Returns:

  • (Hash)

    the updated entry

Raises:



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
# File 'lib/documinty/store.rb', line 111

def methods(path:, feature:, new_methods:, action:)
  file = feature_file(feature)
  raise Error, "Feature '#{feature}' does not exist" unless File.exist?(file)

  data = YAML.load_file(file) || {}
  entries = data['entries'] || []

  # Find the exact entry by path + feature
  entry = entries.find { |e| e['path'] == path && e['feature'] == feature }
  unless entry
    raise Error, "No documentation found for '#{path}' under feature '#{feature}'"
  end

  # Merge existing methods (strings) with new ones, avoid duplicates
  existing = Array(entry['methods']).map(&:to_s)
  if action == :add
    merged  = (existing + new_methods.map(&:to_s)).uniq
  else
    merged  = (existing - new_methods.map(&:to_s)).uniq
  end
  entry['methods'] = merged

  File.write(file, data.to_yaml)
  entry
end

#remove_entry(path:, feature:) ⇒ Object

Remove an entry for path under one feature

Raises:



83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/documinty/store.rb', line 83

def remove_entry(path:, feature:)
  file = feature_file(feature)
  raise Error, "Feature '#{feature}' does not exist" unless File.exist?(file)

  data    = YAML.load_file(file) || {}
  entries = data['entries'] || []
  removed = entries.select { |e| e['path'] == path }
  raise Error, "No entries for '#{path}' under feature '#{feature}'" if removed.empty?

  data['entries'] = entries.reject { |e| e['path'] == path }
  File.write(file, data.to_yaml)
  removed
end

#update_description(path:, feature:, new_description:) ⇒ Hash

Update the description for a documented file under a given feature

Parameters:

  • path (String)

    relative file path

  • feature (String)

    feature name

  • new_description (String)

Returns:

  • (Hash)

    the updated entry



142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# File 'lib/documinty/store.rb', line 142

def update_description(path:, feature:, new_description:)
  file = feature_file(feature)
  unless File.exist?(file)
    raise Error, "Feature '#{feature}' does not exist"
  end

  data     = YAML.load_file(file) || {}
  entries  = data['entries'] ||= []

  entry = entries.find { |e| e['path'] == path && e['feature'] == feature }
  unless entry
    raise Error, "No documentation found for '#{path}' under feature '#{feature}'"
  end

  entry['description'] = new_description.to_s.strip
  File.write(file, data.to_yaml)

  entry
end