Module: MFE

Defined in:
lib/mfe.rb

Overview

This module houses the main logic for MFE.

Constant Summary collapse

MLook =

Method lookup table for commands

{
	'add' => :add_cmd,
	'edit' => :edit_json,
	'show' => :show_cmd,
	'to-shell' => :cmd_to_shell,
	'rm' => :rm_cmd,
	'remove' => :rm_cmd,
}
CommandSig =

This is the character (or string) that indicates that we will be running an MFE command rather than loading and executing a user-defined command.

ENV['MFE_COMMAND_SIG'] || '-'

Instance Method Summary collapse

Instance Method Details

#add_cmd(name, *cmd) ⇒ Object

Adds a new command.



113
114
115
116
117
118
119
120
121
# File 'lib/mfe.rb', line 113

def add_cmd(name, *cmd)
	if cmd.empty?
		cmd = edit_json(name)
		return false if cmd.to_s.empty?
	else
		cmd = Cmd.new(name, cmd)
	end
	cmd.save(dirname!)
end

#cmd_to_shell(name, *argv) ⇒ Object

Given a name and a list of args, this method prints a shell script that would have the effect of running the command.



92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/mfe.rb', line 92

def cmd_to_shell(name, *argv)
	cmd = load_cmd(name)
	shell = [
		`which ENV['SHELL'] 2>/dev/null`,
		Etc.getpwuid(Process.uid).shell,
		'/bin/sh',
	].find { |shell| !shell.chomp.empty? }

	puts("#!#{shell}", 
		cmd.expand(argv))
	true
end

#dirnameObject

Returns the first viable directory for the MFE directory. If none is found, returns nil. Otherwise, it’s guaranteed to always return the same value.



132
133
134
135
136
137
138
139
140
# File 'lib/mfe.rb', line 132

def dirname
	dir = dirnames.find { |d| File.directory?(d) }
	if dir
		# It's important for this to be consistent (and faster anyway).
		meta_def(:dirname) { dir }
		return dir
	end
	nil
end

#dirname!Object

Returns the dirname, but if it’s nil, makes the directory with permissions 0700.



144
145
146
147
148
# File 'lib/mfe.rb', line 144

def dirname!
	return dirname if dirname
	Dir.mkdir(dirnames.first, 0700)
	dirname
end

#dirnamesObject



40
41
42
43
44
45
46
# File 'lib/mfe.rb', line 40

def dirnames
	# Possible directories for housing mfe commands.
	@dirnames ||= [ENV['MFE_HOME'],
		(File.join(ENV['HOME'], '/.mfe') rescue nil),
		File.join(Etc.getpwuid(Process.euid).dir, '/.mfe'),
	].compact
end

#edit_json(name, *argv) ⇒ Object

Allows the user to directly edit the JSON representation of a command.



124
125
126
127
# File 'lib/mfe.rb', line 124

def edit_json(name, *argv)
	system editor, full_path!(name)
	$?.exited?
end

#editorObject

Returns the user’s (suspected) preferred editor.



151
152
153
154
155
# File 'lib/mfe.rb', line 151

def editor
	ENV['VISUAL'] || 
	ENV['EDITOR'] || 
	'vi'  # Reasonable default.
end

#exec_cmd(name, *argv) ⇒ Object

Loads and executes a command named by name with args argv.



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/mfe.rb', line 54

def exec_cmd(name, *argv)
	begin
		exec load_cmd(name).expand(argv)
	rescue Errno::E2BIG
		fp = full_path name
		$stderr.puts "Couldn't execute #{name}!", "Argument list too long."
	rescue Exception => e
		fp = full_path name
		$stderr.puts "Couldn't execute #{name}! (#{e.message})"

		if !File.exist? fp
			$stderr.puts 'File does not exist.'
		elsif !File.readable? fp
			$stderr.puts 'File is not readable.'
		elsif File.directory? fp
			$stderr.puts 'It\'s a directory.'
		else
			$stderr.puts e.inspect
		end
	end
end

#full_path(name) ⇒ Object

Returns the full path for a given command with name name.



158
159
160
# File 'lib/mfe.rb', line 158

def full_path(name)
	File.join(dirname, name)
end

#full_path!(name) ⇒ Object

Returns the full path for a given command with name name, and creates the path if it does not exist.



164
165
166
167
168
# File 'lib/mfe.rb', line 164

def full_path!(name)
	fn = File.join(dirname!, name)
	File.open(fn, 'a').close
	fn
end

#load_cmd(name) ⇒ Object

Loads a command with the given name



49
50
51
# File 'lib/mfe.rb', line 49

def load_cmd(name)
	Cmd.load full_path(name)
end

#rm_cmd(names) ⇒ Object

Removes commands! :O



106
107
108
109
110
# File 'lib/mfe.rb', line 106

def rm_cmd(names)
	names.each { |name|
		File.unlink full_path(name)
	}
end

#show_cmd(*names) ⇒ Object

Given a list of command names, show_cmd will print what each one does. In the absense of a list of names, it will print all commands in the .mfe directory.



79
80
81
82
83
84
85
86
87
88
# File 'lib/mfe.rb', line 79

def show_cmd(*names)
	if names.empty?
		names = Dir["#{dirname}/*"] - %w(. ..)
		names.map! &File.method(:basename)
	end

	names.sort.each { |name|
		puts "#{name}:  #{load_cmd(name).to_s}"
	}
end

#usage(out = $stderr) ⇒ Object



170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
# File 'lib/mfe.rb', line 170

def usage(out = $stderr)
	out.puts [ "",
		"MFE, the meta front-end (#{MFEConfig::URL})",
		"Usage:",
		"#{$0} #{CommandSig} command [args ...]",
		"    Where command is one of",
		"        add name script [args ...]:",
		"            Adds a command named 'name' that executes " +
			"'script [args ...]'.",
		"        show [name(s)]", 
		"            Shows the command(s) named, or all commands if none " +
			"are named.",
		"        edit name",
		"            Runs your favorite editor on the named command.",
		"        to-shell name [args ...]",
		"            Turns the user-defined command into a shell script.",
		"#{$0} your_command [args ...]",
		"    Runs the user-defined command named 'your_command' with the " +
			"specified\n    arguments.",
		"#{$0} ['-h'|'-help'|'--help']",
		"    This help screen.",
		"See the README for more info about usage and influential " +
			"environment\nvariables.",
	]
end

#version_stringObject



196
197
198
# File 'lib/mfe.rb', line 196

def version_string
	"MFE, version #{MFEConfig::Version}."
end