Created
August 1, 2011 13:42
-
-
Save jorrizza/1118135 to your computer and use it in GitHub Desktop.
ActiveRecord Shell
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
ActiveRecord SHell (or ARSH for short). | |
Here's the code that actually works. I have been working on a | |
half-baked pager for the shell, but the code's so ugly I'm not willing | |
to share it. At least this allows someone to continue the "project". | |
The original idea was this: | |
- ls should list available ActiveRecord classes and modules containing | |
ActiveRecord classes. | |
- cd should enter an ActiveRecord class or module. If it's a module, ls | |
will display the classes and/or modules in that. If it's a class, ls | |
will display the available objects as numbered files (with a pager). | |
- cat should display the object's content in YAML format. | |
- ed should start a person's $EDITOR and let him edit that object's YAML. | |
- find should search in objects. Like find -field string ClassName. | |
- Support class paths by adding forward slashes, like ClassName/4315 | |
- Fully support tab completion where possible. | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
# The magic | |
require File.join(File.dirname(__FILE__), '..', 'lib', 'arsh') | |
# Rails boot | |
begin | |
puts "Loading Rails..." | |
require File.join('.', 'config', 'application') | |
require File.join('.', 'config', 'boot') | |
Rails.application.require_environment! | |
rescue | |
$stderr.puts "Please run #{$0} in your Rails root." | |
exit 1 | |
end | |
ARSH::Shell.new self.class |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'readline' | |
# ARSH - the ActiveRecord SHell. | |
module ARSH | |
# The commands used in ARSH. | |
class Commands | |
# Standard output of the command. | |
attr_reader :out | |
# Parses the command in line and starts the right function. | |
def initialize(line, shell) | |
@params = line.split.reverse | |
command = @params.pop | |
@params.reverse! | |
@shell = shell | |
@out = "" | |
# Rails has some awesome deprecation warnings we don't like. | |
# So temporarily send those to /dev/null. | |
#old_stderr = $stderr | |
#$stderr = File.open('/dev/null', 'a+') | |
case command | |
when 'exit' | |
@shell.bye | |
when 'pwd' | |
@out = @shell.pwd.to_s | |
when 'ls' | |
ls | |
when 'cd' | |
cd | |
else | |
@out = "No such command: #{command}" | |
end | |
#$stderr = old_stderr | |
end | |
# Directory listing. | |
def ls | |
ar_classes = @shell.pwd.constants.map do |c| | |
klass = @shell.pwd.const_get c | |
if klass.is_a?(Class) && klass.ancestors.include?(ActiveRecord::Base) | |
klass.to_s | |
end | |
end.compact | |
if @shell.pwd == Object && @params.first | |
if ar_classes.include? @params.first | |
klass = @shell.pwd.const_get @params.first.to_sym | |
ls_files klass | |
else | |
@out = "No such directory: #{@params.first}" | |
end | |
elsif @shell.pwd == Object | |
@out = ar_classes.join ' ' | |
else | |
ls_files @shell.pwd | |
end | |
end | |
# Lists files in a directory. | |
def ls_files(klass) | |
files = klass.limit(50).map do |obj| | |
klass.name.downcase + '_' + obj.id.to_s | |
end | |
@out = "" | |
if files.length == 50 | |
@out = files.join(' ') + "\nThere's a lot of files to list. Maybe you'd like to use find instead\?" | |
else | |
@out = files.join ' ' | |
end | |
end | |
# Change directory. | |
def cd | |
if [email protected] || @params.first == '..' | |
@shell.pwd = Object | |
else | |
klass = @shell.pwd.const_get @params.first.to_sym | |
if !klass || !klass.ancestors.include?(ActiveRecord::Base) | |
@out = "No such directory: #{@params.first}" | |
else | |
@shell.pwd = klass | |
end | |
end | |
end | |
end | |
# Shell wrapper for ARSH. | |
class Shell | |
PROMPT = "#{self.name} %s$ " | |
# The parent directory, e.g. the parent class. | |
attr_accessor :pwd | |
# Start the shell with 'pwd' as starter class. | |
def initialize(pwd) | |
@pwd = pwd | |
# Make sure our shell stays clean after an exit. | |
@stty_save = `stty -g`.chomp | |
trap('INT') { bye } | |
runner | |
end | |
# Quit. | |
def bye | |
puts "Bye!" | |
system('stty', @stty_save) | |
exit | |
end | |
# The shell itself. | |
def runner | |
loop do | |
prompt = PROMPT % @pwd.name | |
line = Readline.readline(prompt, true) | |
bye unless line | |
out = Commands.new(line, self).out | |
puts out unless out.empty? | |
end | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment