|
6 | 6 | require "ruby/gdb" |
7 | 7 | require "fileutils" |
8 | 8 |
|
9 | | -# Install GDB Python extensions to XDG data directory or custom prefix |
10 | | -# @parameter prefix [String] Optional installation prefix (defaults to XDG_DATA_HOME) |
11 | | -def install(prefix: nil) |
12 | | - install_path = Ruby::GDB.install_path(prefix: prefix) |
13 | | - |
14 | | - puts "Installing Ruby GDB extensions to: #{install_path}" |
15 | | - |
16 | | - # Create installation directory |
17 | | - FileUtils.mkdir_p(install_path) |
18 | | - |
19 | | - # Copy Python scripts |
20 | | - scripts = [ |
21 | | - Ruby::GDB.object_script_path, |
22 | | - Ruby::GDB.fiber_script_path |
23 | | - ] |
24 | | - |
25 | | - scripts.each do |script| |
26 | | - if File.exist?(script) |
27 | | - dest = File.join(install_path, File.basename(script)) |
28 | | - puts " Installing #{File.basename(script)}..." |
29 | | - FileUtils.cp(script, dest) |
30 | | - else |
31 | | - warn " Warning: #{script} not found" |
| 9 | +# Install GDB extensions by adding source line to ~/.gdbinit |
| 10 | +# @parameter gdbinit [String] Optional path to .gdbinit (defaults to ~/.gdbinit) |
| 11 | +def install(gdbinit: nil) |
| 12 | + gdbinit_path = gdbinit || File.join(Dir.home, ".gdbinit") |
| 13 | + init_py_path = Ruby::GDB.init_script_path |
| 14 | + source_line = "source #{init_py_path}" |
| 15 | + marker_comment = "# Ruby GDB Extensions (ruby-gdb gem)" |
| 16 | + |
| 17 | + puts "Installing Ruby GDB extensions..." |
| 18 | + puts " Extensions: #{File.dirname(init_py_path)}" |
| 19 | + puts " Config: #{gdbinit_path}" |
| 20 | + |
| 21 | + # Read existing .gdbinit or create empty array |
| 22 | + lines = File.exist?(gdbinit_path) ? File.readlines(gdbinit_path) : [] |
| 23 | + |
| 24 | + # Check if already installed (look for marker comment) |
| 25 | + marker_index = lines.index{|line| line.strip == marker_comment} |
| 26 | + |
| 27 | + if marker_index |
| 28 | + # Already installed - update the source line in case path changed |
| 29 | + source_index = marker_index + 1 |
| 30 | + if source_index < lines.size && lines[source_index].strip.start_with?("source") |
| 31 | + old_source = lines[source_index].strip |
| 32 | + if old_source == source_line |
| 33 | + puts "\n✓ Already installed in #{gdbinit_path}" |
| 34 | + puts " #{source_line}" |
| 35 | + return |
| 36 | + else |
| 37 | + # Path changed - update it |
| 38 | + lines[source_index] = "#{source_line}\n" |
| 39 | + File.write(gdbinit_path, lines.join) |
| 40 | + puts "\n✓ Updated installation in #{gdbinit_path}" |
| 41 | + puts " Old: #{old_source}" |
| 42 | + puts " New: #{source_line}" |
| 43 | + return |
| 44 | + end |
32 | 45 | end |
33 | 46 | end |
34 | 47 |
|
35 | | - # Create a loader script that sources both extensions |
36 | | - loader_path = File.join(install_path, "init.gdb") |
37 | | - puts " Creating loader script: #{File.basename(loader_path)}" |
38 | | - |
39 | | - File.write(loader_path, <<~GDB) |
40 | | - # Ruby GDB Extensions Loader |
41 | | - # This file loads Ruby debugging extensions for GDB |
42 | | - |
43 | | - python |
44 | | - import sys |
45 | | - import os |
46 | | - |
47 | | - # Add the Ruby GDB extensions directory to Python path |
48 | | - ruby_gdb_dir = os.path.dirname(__file__) |
49 | | - if ruby_gdb_dir not in sys.path: |
50 | | - sys.path.insert(0, ruby_gdb_dir) |
51 | | - |
52 | | - # Load Ruby object printing extensions |
53 | | - exec(open(os.path.join(ruby_gdb_dir, 'object.py')).read()) |
54 | | - |
55 | | - # Load Ruby fiber debugging extensions |
56 | | - exec(open(os.path.join(ruby_gdb_dir, 'fiber.py')).read()) |
57 | | - |
58 | | - print("Ruby GDB extensions loaded successfully!") |
59 | | - print("Use 'help rb-' to see available commands.") |
60 | | - end |
61 | | - GDB |
| 48 | + # Not installed - add it |
| 49 | + File.open(gdbinit_path, "a") do |f| |
| 50 | + f.puts unless lines.last&.strip&.empty? |
| 51 | + f.puts marker_comment |
| 52 | + f.puts source_line |
| 53 | + end |
62 | 54 |
|
63 | | - puts "\nInstallation complete!" |
64 | | - puts "\nTo use these extensions, add the following to your ~/.gdbinit:" |
65 | | - puts " source #{loader_path}" |
66 | | - puts "\nOr load them manually in GDB with:" |
67 | | - puts " (gdb) source #{loader_path}" |
| 55 | + puts "\n✓ Installation complete!" |
| 56 | + puts "\nAdded to #{gdbinit_path}:" |
| 57 | + puts " #{source_line}" |
| 58 | + puts "\nExtensions will load automatically when you start GDB." |
68 | 59 | end |
69 | 60 |
|
70 | | -# Uninstall GDB Python extensions |
71 | | -# @parameter prefix [String] Optional installation prefix (defaults to XDG_DATA_HOME) |
72 | | -def uninstall(prefix: nil) |
73 | | - install_path = Ruby::GDB.install_path(prefix: prefix) |
74 | | - |
75 | | - if Dir.exist?(install_path) |
76 | | - puts "Removing Ruby GDB extensions from: #{install_path}" |
77 | | - FileUtils.rm_rf(install_path) |
78 | | - puts "Uninstallation complete!" |
79 | | - else |
80 | | - puts "No installation found at: #{install_path}" |
| 61 | +# Uninstall GDB extensions by removing source line from ~/.gdbinit |
| 62 | +# @parameter gdbinit [String] Optional path to .gdbinit (defaults to ~/.gdbinit) |
| 63 | +def uninstall(gdbinit: nil) |
| 64 | + gdbinit_path = gdbinit || File.join(Dir.home, ".gdbinit") |
| 65 | + marker_comment = "# Ruby GDB Extensions (ruby-gdb gem)" |
| 66 | + |
| 67 | + puts "Uninstalling Ruby GDB extensions..." |
| 68 | + |
| 69 | + unless File.exist?(gdbinit_path) |
| 70 | + puts "No ~/.gdbinit file found - nothing to uninstall." |
| 71 | + return |
| 72 | + end |
| 73 | + |
| 74 | + lines = File.readlines(gdbinit_path) |
| 75 | + marker_index = lines.index{|line| line.strip == marker_comment} |
| 76 | + |
| 77 | + unless marker_index |
| 78 | + puts "Extensions were not found in #{gdbinit_path}" |
| 79 | + return |
| 80 | + end |
| 81 | + |
| 82 | + # Remove the marker comment and the source line after it |
| 83 | + lines.delete_at(marker_index) # Remove comment |
| 84 | + if marker_index < lines.size && lines[marker_index].strip.start_with?("source") |
| 85 | + removed_line = lines.delete_at(marker_index).strip # Remove source line |
| 86 | + puts " Removed: #{removed_line}" |
81 | 87 | end |
| 88 | + |
| 89 | + # Clean up empty line before marker if it exists |
| 90 | + if marker_index > 0 && lines[marker_index - 1].strip.empty? |
| 91 | + lines.delete_at(marker_index - 1) |
| 92 | + end |
| 93 | + |
| 94 | + File.write(gdbinit_path, lines.join) |
| 95 | + puts "✓ Removed Ruby GDB extensions from #{gdbinit_path}" |
82 | 96 | end |
83 | 97 |
|
84 | 98 | # Show installation information |
85 | | -def info |
| 99 | +# @parameter gdbinit [String] Optional path to .gdbinit (defaults to ~/.gdbinit) |
| 100 | +def info(gdbinit: nil) |
| 101 | + gdbinit_path = gdbinit || File.join(Dir.home, ".gdbinit") |
| 102 | + init_py_path = Ruby::GDB.init_script_path |
| 103 | + marker_comment = "# Ruby GDB Extensions (ruby-gdb gem)" |
| 104 | + |
86 | 105 | puts "Ruby GDB Extensions v#{Ruby::GDB::VERSION}" |
87 | | - puts "\nData directory: #{Ruby::GDB.data_path}" |
88 | | - puts "Default install path: #{Ruby::GDB.install_path}" |
89 | | - puts "\nAvailable scripts:" |
90 | | - puts " - object.py (rb-object-print command)" |
91 | | - puts " - fiber.py (rb-scan-fibers, rb-fiber-bt, and more)" |
| 106 | + puts "\nGem data directory: #{Ruby::GDB.data_path}" |
| 107 | + puts "Init script: #{init_py_path}" |
| 108 | + |
| 109 | + # Check installation status by looking for marker comment |
| 110 | + installed = false |
| 111 | + current_source = nil |
| 112 | + |
| 113 | + if File.exist?(gdbinit_path) |
| 114 | + lines = File.readlines(gdbinit_path) |
| 115 | + marker_index = lines.index{|line| line.strip == marker_comment} |
| 116 | + if marker_index |
| 117 | + installed = true |
| 118 | + source_index = marker_index + 1 |
| 119 | + if source_index < lines.size |
| 120 | + current_source = lines[source_index].strip |
| 121 | + end |
| 122 | + end |
| 123 | + end |
| 124 | + |
| 125 | + puts "\nGDB config: #{gdbinit_path}" |
| 126 | + if installed |
| 127 | + puts "Status: ✓ Installed" |
| 128 | + if current_source |
| 129 | + puts " #{current_source}" |
| 130 | + end |
| 131 | + else |
| 132 | + puts "Status: ✗ Not installed" |
| 133 | + puts "\nRun: bake ruby:gdb:install" |
| 134 | + end |
92 | 135 | end |
93 | | - |
|
0 commit comments