Class: RubyLlmAgents::RestructureGenerator

Inherits:
Rails::Generators::Base
  • Object
show all
Defined in:
lib/generators/ruby_llm_agents/restructure_generator.rb

Overview

Restructure generator for migrating existing apps to new directory structure

Migrates ruby_llm-agents directories from the flat structure:

app/agents/, app/speakers/, app/embedders/, etc.

To the new grouped structure under app/llm/:

app/llm/agents/, app/llm/audio/speakers/, app/llm/image/generators/, etc.

Usage:

rails generate ruby_llm_agents:restructure
rails generate ruby_llm_agents:restructure --root=ai

Constant Summary collapse

DIRECTORY_MAPPING =

Maps old directory -> { category:, type: }

{
  # Top-level under llm/
  "agents" => {category: nil, type: "agents"},
  "tools" => {category: nil, type: "tools"},

  # Audio group
  "speakers" => {category: :audio, type: "speakers"},
  "transcribers" => {category: :audio, type: "transcribers"},

  # Image group
  "image_generators" => {category: :image, type: "generators"},
  "image_editors" => {category: :image, type: "editors"},
  "image_analyzers" => {category: :image, type: "analyzers"},
  "image_transformers" => {category: :image, type: "transformers"},
  "image_upscalers" => {category: :image, type: "upscalers"},
  "image_variators" => {category: :image, type: "variators"},
  "background_removers" => {category: :image, type: "background_removers"},

  # Text group
  "embedders" => {category: :text, type: "embedders"},
  "moderators" => {category: :text, type: "moderators"}
}.freeze

Instance Method Summary collapse

Instance Method Details

#cleanup_empty_directoriesObject



128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'lib/generators/ruby_llm_agents/restructure_generator.rb', line 128

def cleanup_empty_directories
  say ""
  say_status :cleanup, "Removing empty old directories", :green

  DIRECTORY_MAPPING.keys.each do |old_dir|
    path = Rails.root.join("app", old_dir)
    next unless File.directory?(path)

    if Dir.empty?(path)
      if options[:dry_run]
        say_status :dry_run, "Would remove empty directory app/#{old_dir}", :yellow
      else
        FileUtils.rmdir(path)
        say_status :removed, "app/#{old_dir}", :red
      end
    else
      say_status :warning, "app/#{old_dir} is not empty, skipping removal", :yellow
    end
  end
end

#create_directory_structureObject



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/generators/ruby_llm_agents/restructure_generator.rb', line 68

def create_directory_structure
  say_status :create, "#{root_directory}/ directory structure", :green

  if options[:dry_run]
    say_status :dry_run, "Would create directory structure under app/#{root_directory}/", :yellow
    return
  end

  # Create root directory
  empty_directory "app/#{root_directory}"

  # Create all subdirectories
  config.all_autoload_paths.each do |path|
    empty_directory path
  end
end

#move_directoriesObject



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
# File 'lib/generators/ruby_llm_agents/restructure_generator.rb', line 85

def move_directories
  say ""
  say_status :migrate, "Moving directories to new structure", :green

  directories_moved = 0

  DIRECTORY_MAPPING.each do |old_dir, mapping|
    source = Rails.root.join("app", old_dir)
    next unless File.directory?(source)

    destination = Rails.root.join(config.path_for(mapping[:category], mapping[:type]))

    if options[:dry_run]
      say_status :dry_run, "Would move app/#{old_dir}/* -> #{destination}", :yellow
      directories_moved += 1
      next
    end

    move_directory_contents(source, destination, old_dir)
    directories_moved += 1
  end

  if directories_moved == 0
    say_status :skip, "No directories found to migrate", :yellow
  end
end

#show_completion_messageObject



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
179
180
181
182
183
184
185
186
# File 'lib/generators/ruby_llm_agents/restructure_generator.rb', line 149

def show_completion_message
  say ""
  say "=" * 60
  say ""
  if options[:dry_run]
    say "Dry run complete! No changes were made.", :yellow
    say ""
    say "To perform the actual migration, run:"
    say "  rails generate ruby_llm_agents:restructure"
  else
    say "Migration complete!", :green
    say ""
    say "Your app now uses the new directory structure:"
    say ""
    say "  app/#{root_directory}/"
    say "  ├── agents/"
    say "  ├── audio/"
    say "  │   ├── speakers/"
    say "  │   └── transcribers/"
    say "  ├── image/"
    say "  │   ├── analyzers/"
    say "  │   ├── generators/"
    say "  │   └── ..."
    say "  ├── text/"
    say "  │   ├── embedders/"
    say "  │   └── moderators/"
    say "  └── tools/"
    say ""
    say "Namespaces have been updated to use #{root_namespace}::"
    say ""
    say "Next steps:"
    say "  1. Update any explicit class references in your code"
    say "  2. Run your test suite to verify everything works"
    say "  3. Commit the changes"
  end
  say ""
  say "=" * 60
end

#update_namespacesObject



112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/generators/ruby_llm_agents/restructure_generator.rb', line 112

def update_namespaces
  say ""
  say_status :update, "Adding namespaces to Ruby files", :green

  DIRECTORY_MAPPING.each do |_old_dir, mapping|
    directory_path = Rails.root.join(config.path_for(mapping[:category], mapping[:type]))
    next unless File.directory?(directory_path)

    namespace = config.namespace_for(mapping[:category])

    Dir.glob("#{directory_path}/**/*.rb").each do |file|
      update_file_namespace(file, namespace) if namespace
    end
  end
end

#validate_root_directoryObject



61
62
63
64
65
66
# File 'lib/generators/ruby_llm_agents/restructure_generator.rb', line 61

def validate_root_directory
  unless root_directory.match?(/\A[a-z][a-z0-9_-]*\z/i)
    raise ArgumentError, "Invalid root directory name: #{root_directory}. " \
                         "Must start with a letter and contain only letters, numbers, underscores, or hyphens."
  end
end