-
Notifications
You must be signed in to change notification settings - Fork 0
/
grrr_meta.rb
214 lines (185 loc) · 6.76 KB
/
grrr_meta.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
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
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
136
137
138
139
140
141
142
143
144
145
146
147
148
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
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
require 'rsclass'
require 'tmpdir'
module GrrrMeta
class <<self
def execute(operation, defname)
ensure_editor_environment_variable_is_set
repo_entry = parse_def_arg(defname)
rest_of_repo = []
case operation
when "generate"
generate(repo_entry, rest_of_repo, [:rb_stub, :sc_stub])
when "generate-rb"
generate(repo_entry, rest_of_repo, [:rb_stub])
when "generate-sc"
generate(repo_entry, rest_of_repo, [:sc_stub])
when "workcopyedit-rb"
workcopyedit_one(repo_entry, rest_of_repo, :rb_stub)
when "workcopyedit-sc"
workcopyedit_one(repo_entry, rest_of_repo, :sc_stub)
when "workcopyedit-both"
workcopyedit_both(repo_entry, rest_of_repo)
when "workcopyedit-sidebyside"
workcopyedit_sidebyside(repo_entry, rest_of_repo)
when "defedit"
defedit(repo_entry)
else
raise "unknown operation #{operation}"
end
end
def print_usage
operations = [
"generate",
"generate-rb",
"generate-sc",
"workcopyedit-rb",
"workcopyedit-sc",
"workcopyedit-both",
"workcopyedit-sidebyside",
"defedit"
]
puts "usage: ruby #{__FILE__} operation [defname]"
puts " operation:"
puts operations.map { |operation| "\t\t#{operation}" }.join("\n")
end
def ensure_editor_environment_variable_is_set
raise "EDITOR environment variable is not set" unless ENV["EDITOR"]
end
def ensure_destination_folders_exist
raise "GRRR_META_RB_DESTINATION_FOLDER environment variable is not set" unless ENV["GRRR_META_RB_DESTINATION_FOLDER"]
raise "GRRR_META_SC_DESTINATION_FOLDER environment variable is not set" unless ENV["GRRR_META_SC_DESTINATION_FOLDER"]
raise "GRRR_META_RB_DESTINATION_FOLDER environment variable does not refer to a folder" unless File.directory?(ENV["GRRR_META_RB_DESTINATION_FOLDER"])
raise "GRRR_META_SC_DESTINATION_FOLDER environment variable does not refer to a folder" unless File.directory?(ENV["GRRR_META_SC_DESTINATION_FOLDER"])
end
def generate(repo_entry, rest_of_repo, dest_types)
ensure_destination_folders_exist
dest_types.each do |dest_type|
stub = RSClass.generate(repo_entry, rest_of_repo, dest_type)
write_n_diff(stub)
end
end
def workcopyedit_one(repo_entry, rest_of_repo, dest_type)
path = get_workcopy_file_path_from_repo(repo_entry, rest_of_repo, dest_type)
print "\"#{ENV["EDITOR"]} #{File.basename(path)}\"? [Yn] "
system("#{ENV["EDITOR"]} \"#{path}\"") if user_say_yes?
end
def workcopyedit_both(repo_entry, rest_of_repo)
rb_path, sc_path = get_rb_and_sc_workcopy_file_paths_from_repo(repo_entry, rest_of_repo)
print "\"#{ENV["EDITOR"]} #{[rb_path, sc_path].map {|p|File.basename(p)}.join(" ")}\"? [Yn] "
system("#{ENV["EDITOR"]} #{[rb_path, sc_path].map{|path| "\"#{path}\""}.join(" ")}") if user_say_yes?
end
def workcopyedit_sidebyside(repo_entry, rest_of_repo)
rb_path, sc_path = get_rb_and_sc_workcopy_file_paths_from_repo(repo_entry, rest_of_repo)
print "\"#{ENV["EDITOR"]} -O2 #{[rb_path, sc_path].map {|p|File.basename(p)}.join(" ")}\"? [Yn] "
system("#{ENV["EDITOR"]} -O2 #{[rb_path, sc_path].map{|path| "\"#{path}\""}.join(" ")}") if user_say_yes?
end
def defedit(repo_entry)
defpath = get_defpath(repo_entry["source"]["name"])
print "\"#{ENV["EDITOR"]} #{File.basename(defpath)}\"? [Yn] "
system("#{ENV["EDITOR"]} \"#{defpath}\"") if user_say_yes?
end
def get_rootdir
File.expand_path(File.dirname(__FILE__))
end
def get_repodir
File.join(get_rootdir, "def")
end
def get_defpath(defname)
File.join(get_repodir, "#{defname}.rsclass.rb")
end
def parse_def(filename)
name, type, format = File.basename(filename).split "."
file = {
:source => {
:name => name,
:type => type,
:format => format
},
:content => File.read(filename)
}
RSClass.parse_file(file)
end
def parse_def_arg(defname)
filename = get_defpath(defname)
if not File.exists?(filename)
entries = Dir.entries(get_repodir).
reject{|p|%w{. ..}.include?(p)}.
map {|p|p.split(".")[0]}.
select{|p|/#{defname}/ =~ p}
if entries.size == 0
puts "Argument matched no definition in repository."
exit
else
if entries.size == 1
single_match = entries.first
print "You meant \"#{single_match}\", right? [Yn] "
exit unless user_say_yes?
filename = get_defpath(single_match)
else
puts "Several matches in repository. Choose:"
entries.each_with_index { |item, i| puts "#{i+1}. #{item}" }
filename = get_defpath(
entries[get_user_number_in_range((1..entries.size))-1]
)
end
end
end
parse_def(filename)
end
def write_n_diff(stub)
dest = stub[:destination]
generated_file_path = get_generated_file_path(dest[:filetype], dest[:filename])
workcopy_file_path = get_workcopy_file_path(dest[:filetype], dest[:filename])
File.open("#{generated_file_path}", 'w') {|f| f.write(stub[:content])}
print "stub #{get_destination_language_from_filetype(dest[:filetype])}/#{File.basename(generated_file_path)} generated. diff with workcopy? [Yn] "
system("#{ENV["EDITOR"]} -d \"#{generated_file_path}\" \"#{workcopy_file_path}\"") if user_say_yes?
end
def get_destination_language_from_filetype(destination_filetype)
case destination_filetype
when "rb" then "Ruby"
when "sc" then "SuperCollider"
else
raise "unsupported file type"
end
end
def get_generated_file_path(destination_filetype, destination_filename)
dir = File.join(Dir.tmpdir, destination_filetype)
Dir.mkdir(dir) unless File.directory? dir
File.join(dir, destination_filename)
end
def get_workcopy_file_path(destination_filetype, destination_filename)
File.join(get_workcopy_folder_path(destination_filetype), destination_filename)
end
def get_workcopy_folder_path(destination_filetype)
ENV["GRRR_META_#{destination_filetype.upcase}_DESTINATION_FOLDER"]
end
def get_rb_and_sc_workcopy_file_paths_from_repo(repo_entry, rest_of_repo)
rb_path = get_workcopy_file_path_from_repo(repo_entry, rest_of_repo, :rb_stub)
sc_path = get_workcopy_file_path_from_repo(repo_entry, rest_of_repo, :sc_stub)
[rb_path, sc_path]
end
def get_workcopy_file_path_from_repo(repo_entry, rest_of_repo, dest_type)
stub = RSClass.generate(repo_entry, rest_of_repo, dest_type)
dest = stub[:destination]
get_workcopy_file_path(dest[:filetype], dest[:filename])
end
def user_say_yes?
["y", ""].include?(STDIN.gets.chomp.downcase)
end
def get_user_number_in_range(range)
print "[#{range.min}-#{range.max}] "
number = STDIN.gets.chomp.to_i
exit unless range.include? number
number
end
end
end
if $0 == __FILE__
if ARGV.size == 0
GrrrMeta.print_usage
else
operation = ARGV[0]
defname = ARGV[1]
GrrrMeta.execute(operation, defname)
end
end