Neurogami-rhesus 0.2.5 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README.md CHANGED
@@ -24,7 +24,6 @@ The results are copied out to some dir realtive to where you invoked the 'rhesus
24
24
  FEATURES/PROBLEMS
25
25
  -----------------
26
26
 
27
-
28
27
  Generates files for you to jump-start projects that have common code.
29
28
 
30
29
  Makes asorted assumptions and needs more testing with a variety of template sources
@@ -45,11 +44,12 @@ Run `rhesus list` to see the available templates
45
44
 
46
45
  $ rhesus list
47
46
 
47
+ NOTE: This behavior might vanish, since in actual use it is actually useless. See below.
48
+
48
49
 
49
50
  Run `rhesus gen` to generate code from a template. You may optionally pass the name
50
51
  of a template, but if you leave that out you'll get a list to pick from.
51
52
 
52
-
53
53
  $ rhesus gen
54
54
  1: jimpanzee.about
55
55
  2: jimpanzee.basic
@@ -57,6 +57,16 @@ of a template, but if you leave that out you'll get a list to pick from.
57
57
 
58
58
  Enter the number of the template to use:
59
59
 
60
+ If you pass a complete template name then that is automatically used:
61
+
62
+ $ rhesus gen jimpanzee.midi
63
+
64
+ Run `rhesus stuff` to have rhesus show a list of templates that match on `stuff`.
65
+
66
+ $ rhesus midi
67
+ 1: jimpanzee.midi
68
+
69
+ Enter the number of the template to use:
60
70
 
61
71
 
62
72
  The code assumes you have a directory `.rhesus` in your home directory (+~/.rhesus+)
@@ -194,6 +204,10 @@ A value of `FooBar`, for example, would create `src/foo_bar/foo_bar.rb`. But th
194
204
 
195
205
 
196
206
 
207
+ Note: Some of the code for auto-mangling file and path names is changing. Initially the code was specific to Ruby apps, but it's really very handy for all sorts of things, such as Haskell projects.
208
+
209
+ But these other things have different conventions; code to apply appropriate conventions is being added.
210
+
197
211
 
198
212
  REQUIREMENTS
199
213
  -------------
data/Rakefile CHANGED
@@ -26,7 +26,6 @@ PROJ.version = Neurogami::Rhesus::VERSION
26
26
  PROJ.readme_file = 'README.md'
27
27
  PROJ.summary = "Really simple, practical code generator."
28
28
 
29
- # PROJ.spec.opts << '--color'
30
29
 
31
30
  desc "Bacon specs"
32
31
  task 'test:bacon' do
@@ -36,4 +35,111 @@ end
36
35
 
37
36
  desc 'test'
38
37
  task :test => 'test:bacon'
38
+
39
+ namespace :issues do
40
+ desc 'Open issues'
41
+ task :open do
42
+ paged_issues ENV['GH_NO_CACHE']
43
+ end
44
+
45
+ desc 'Create a new issue'
46
+ task :create do
47
+ issue_details = ENV['DETAILS'].to_s.strip
48
+ if issue_details.empty?
49
+ warn "No issue details!"
50
+ else
51
+ title, body = issue_details.split(' -- ', 2)
52
+ create_issue title, body
53
+ end
54
+ end
55
+ end
56
+
57
+
58
+ def create_issue title, body
59
+ require 'net/http'
60
+ require 'uri'
61
+
62
+
63
+ token = ENV['GH_AUTH_TOKEN']
64
+ url = 'http://github.com/api/v2/yaml/issues/open/Neurogami/rhesus'
65
+ res = Net::HTTP.post_form(URI.parse(url),
66
+ {'title'=> title,
67
+ 'body' => body,
68
+ 'login' => 'Neurogami',
69
+ 'token'=> token }
70
+ )
71
+ warn res.body
72
+
73
+ end
74
+
75
+ def ___
76
+ warn "\n" + '_' * 30
77
+ end
78
+
79
+ def paged_issues no_cache = false
80
+ ARGV.clear
81
+ warn "Hit enter after each issue to see the next one"
82
+ issues(no_cache).each do |issue|
83
+ ___
84
+ warn "Title: #{issue['title']}"
85
+ warn "Details: \n#{issue['body']}"
86
+ ___
87
+ gets
88
+ end
89
+ warn "\nThat's it!"
90
+ end
91
+
92
+
93
+ def issues no_cache = false
94
+ issues_cache = 'issues.yaml'
95
+ if no_cache || !File.exist?(issues_cache)
96
+ warn "Reloading issues from GitHub ..."
97
+ File.open( issues_cache, 'w'){ |f| f.puts get_issues }
98
+ end
99
+ YAML.load(IO.read(issues_cache))['issues']
100
+ end
101
+
102
+ def get_issues
103
+ #require 'yaml'
104
+ # url = 'http://github.com/api/v2/yaml/issues/list/Neurogami/rhesus/open'
105
+ # open(url).read
106
+
107
+ %~---
108
+ issues:
109
+ - user: Neurogami
110
+ updated_at: 2009-08-25 11:15:11 -07:00
111
+ body: "The app started out to handle Ruby code, but is handy for almost anything (such as layout out a Haskel project). But not all languages use the same CamelCase and snake_case conventions. \r\n\
112
+ \r\n\
113
+ When the code is inventing file names it needs to follow appropriate language conventions. "
114
+ title: All variable-driven file names are snake_cased by default
115
+ number: 1
116
+ votes: 0
117
+ closed_at:
118
+ labels:
119
+ - configuration
120
+ created_at: 2009-08-25 10:09:44 -07:00
121
+ state: open
122
+ - user: Neurogami
123
+ updated_at: 2009-08-25 10:16:28 -07:00
124
+ body: |-
125
+ Running
126
+
127
+ rhesus list
128
+
129
+ or
130
+
131
+ rhesus gen
132
+
133
+ gives a full list of available templates, which can get too big to be useful.
134
+ title: CLI UI won't scale
135
+ number: 2
136
+ votes: 0
137
+ closed_at:
138
+ labels:
139
+ - UI
140
+ created_at: 2009-08-25 10:13:53 -07:00
141
+ state: open
142
+ ~
143
+ end
144
+
39
145
  # EOF
data/bin/rhesus CHANGED
@@ -26,7 +26,7 @@ def help(message = nil)
26
26
  end
27
27
 
28
28
  def process_template template_name
29
- puts "Using template #{template_name}"
29
+ puts " - Using template #{template_name.inspect}"
30
30
 
31
31
  var_set = {}
32
32
 
@@ -92,20 +92,33 @@ def copy_over_default_templates
92
92
  FileUtils.cp_r File.dirname(__FILE__) + "/../default-templates/.", Neurogami::Rhesus::Core.user_template_directory
93
93
  end
94
94
 
95
- def generate_from_template
95
+ def generate_from_template filter = /.*/
96
+
97
+ filter = Regexp.new(filter) unless filter.is_a?(Regexp)
98
+
96
99
  if ARGV.first
97
- puts "Generate from #{ARGV.first} template"
100
+ ARGV.first.strip!
101
+ t = Neurogami::Rhesus::Core.templates.find{ |t| t == ARGV.first }
102
+ ARGV.clear
103
+ process_template t
98
104
  else
99
- Neurogami::Rhesus::Core.templates.each_with_index do |template, idx|
105
+ templates = {}
106
+ Neurogami::Rhesus::Core.templates.select{ |t| t =~ filter }.each_with_index do |template, idx|
107
+ templates[idx+1] = template
100
108
  puts "#{idx+1}: #{template}"
101
109
  end
102
- item = 0
103
- while item < 1 || item-1 > Neurogami::Rhesus::Core.templates.size
104
- print "Enter the number of the template to use: "
105
- item = gets.to_i
110
+ if templates.empty?
111
+ warn "No templates matched on #{filter.pretty_inspect.strip}."
112
+ else
113
+ item = 0
114
+ while item < 1 || item-1 > Neurogami::Rhesus::Core.templates.size
115
+ print "Enter the number of the template to use: "
116
+ item = gets.to_i
117
+ end
118
+
119
+ process_template templates[item] # Neurogami::Rhesus::Core.templates[item-1]
106
120
  end
107
121
 
108
- process_template Neurogami::Rhesus::Core.templates[item-1]
109
122
  end
110
123
  end
111
124
  #-------------------------------------------------
@@ -127,7 +140,9 @@ else
127
140
  when '--setup'
128
141
  setup
129
142
  else
130
- puts "Nothing known about #{ARGV[0]}"
143
+ #puts "Nothing known about #{ARGV[0]}"
144
+ # Treat the same as gen, but use the argument as a pattern filter to reduce the number of items show
145
+ generate_from_template option.strip
131
146
  end
132
147
  end
133
148
 
data/lib/rhesus/core.rb CHANGED
@@ -19,10 +19,6 @@ module Neurogami
19
19
  module Rhesus
20
20
 
21
21
  class Core
22
- # Hacky :( FIXME Add a better way to define what files get slurped for parsing
23
- haz_vars = %w{ rb txt rhtml ini yml yaml Rakefile rake gemspec feature}
24
- @@re = haz_vars.map { |x| x + '$' }.join( '|')
25
- @@re = Regexp.new "(#{@@re})$"
26
22
 
27
23
  # http://refactormycode.com/codes/281-given-a-hash-of-variables-render-an-erb-template
28
24
  @@m = Module.new do
@@ -45,40 +41,40 @@ module Neurogami
45
41
  end
46
42
  end
47
43
 
48
- def self.process_template f, variables_hash
44
+ def self.process_template template_text, variables_hash
49
45
  create_methods_from_hash variables_hash
50
- t = ERB.new(IO.read(f), 0, "%<>")
46
+ t = ERB.new(template_text, 0, "%<>")
51
47
  t.result @@m.binding
52
48
  end
53
49
 
54
50
  def self.projects
55
51
  get_projects_directories.map { |path|
56
52
  path.sub! user_template_directory + '/', ''
57
- #path.identifier_to_path!
58
53
  path
59
54
  }
60
55
  end
61
56
 
62
-
63
-
64
57
  def self.tuple_base_name_pair name
65
58
  [snake_case(name), camelize(name)]
66
59
  end
67
60
 
68
61
 
62
+ #
69
63
  def self.required_vars_for_template_set template_name
70
64
  #template_name.identifier_to_path!
71
- vars = {}
65
+ vars = []
72
66
 
73
67
  selected_template_files(template_name).map do |path|
74
68
  next unless File.file? path
75
69
  next unless path =~ @@re
76
-
77
- required_vars(path).each do |v|
78
- vars[v] = v
79
- end
70
+ file_lines = IO.readlines path
71
+ vars.concat(required_vars(file_lines))
72
+ #file_lines.each do |v|
73
+ # vars[v] = v
74
+ #end
80
75
  end
81
- vars.keys.sort
76
+ vars.uniq!
77
+ vars.sort
82
78
  end
83
79
 
84
80
  def self.templates
@@ -89,18 +85,15 @@ module Neurogami
89
85
  end
90
86
  end
91
87
 
92
- def self.required_vars f
93
- vars = {}
94
- IO.readlines(f).each do |l|
95
- l =~ /(<%=)\s*(\S+)\s*(%>)/
96
- if $&
97
- varname = $2
98
- varname.strip!
99
- varname = varname.split('.').first
100
- vars[varname] = varname
101
- end
88
+ def self.required_vars file_lines
89
+ vars = []
90
+ file_lines.each do |l|
91
+ vars.concat l.scan(/(<%=)\s*(\S+)\s*(%>)/).map{ |m| m[1].strip.split('.').first}
92
+ #variables.each do |v|
93
+ # vars[v] = v
94
+ #end
102
95
  end
103
- vars.keys
96
+ vars.uniq
104
97
  end
105
98
 
106
99
 
@@ -116,13 +109,12 @@ module Neurogami
116
109
  end
117
110
 
118
111
  def self.selected_template_files template_name
119
- # template_name.identifier_to_path!
120
- Dir.glob user_template_directory + '/' + template_name + '/**/*'
112
+ Dir.glob( user_template_directory + '/' + template_name + '/**/*', File::FNM_DOTMATCH).select { |f| f !~ /\.$/ }
121
113
  end
122
114
 
123
- def self.add_user_haz_vars
124
- if File.exist?(File.expand_path( '~/.rhesus/haz_vars.txt'))
125
- IO.readlines(File.expand_path( '~/.rhesus/haz_vars.txt')).each { |x| haz_vars << x.strip unless x.strip.empty? }
115
+ def self.add_user_haz_vars haz_vars
116
+ if File.exist?(File.expand_path( user_template_directory + '/haz_vars.txt'))
117
+ IO.readlines(File.expand_path( user_template_directory + '/haz_vars.txt')).each { |x| haz_vars << x.strip unless x.strip.empty? }
126
118
  end
127
119
  end
128
120
 
@@ -134,11 +126,36 @@ module Neurogami
134
126
  File.expand_path "~/.rhesus"
135
127
  end
136
128
 
129
+ def self.language_appropriate_renaming path, template_var, given_value
130
+ # Hack to see what might work:
131
+ renaming_map = {
132
+ /\.rb$/ => :to_snake_case
133
+ }
134
+ renaming_map.each do |file_pattern, renaming_method|
135
+ if path =~ file_pattern
136
+ return path.gsub( template_var, given_value.send(renaming_method) )
137
+ end
138
+ end
139
+ path.gsub( template_var, given_value )
140
+ end
141
+
142
+ # How can this be tested? This method is more or less the core of the
143
+ # tool (other key method: extracting the set of vars from the templates)
144
+ # The trouble is that the code works by creating a side effect; the return
145
+ # value is nothing.
146
+ #
147
+ # This method does multiple things: computes file paths;
148
+ # alters file path basedon variable values; calls
149
+ # out to read in file text, alter it with variable subsition, and
150
+ # write it out; do direct file copies.
151
+
137
152
  def self.process template_name, var_set, location, path
138
153
  relative_path = path.sub user_template_directory , ''
139
154
  short_path = path.sub user_template_directory, ''
140
155
  real_path = short_path.sub(template_name + '/', '')
141
- var_set.each { |k,v| real_path.gsub!( k, v.to_snake_case ) }
156
+
157
+ var_set.each { |key, value| real_path = language_appropriate_renaming( real_path, key, value ) }
158
+
142
159
  write_to = location + real_path
143
160
  destination_dir = File.expand_path(File.dirname(write_to))
144
161
  FileUtils.mkdir_p destination_dir
@@ -146,7 +163,8 @@ module Neurogami
146
163
  rename( file_to_write_to ) if File.exist? file_to_write_to
147
164
  # Do a straight file copy unless this file might be using Erb
148
165
  if path =~ @@re
149
- text = process_template path, var_set
166
+ source_text = IO.read path
167
+ text = process_template source_text, var_set
150
168
  File.open(file_to_write_to, "w"){|f| f.puts text }
151
169
  else
152
170
  FileUtils.cp path, file_to_write_to
@@ -159,6 +177,13 @@ module Neurogami
159
177
  FileUtils.mv full_file_path, full_file_path + '.' + ts
160
178
  end
161
179
 
180
+
181
+ # Hacky :( FIXME Add a better way to define what files get slurped for parsing
182
+ haz_vars = %w{ rb txt rhtml ini yml yaml Rakefile rake gemspec feature}
183
+ add_user_haz_vars haz_vars
184
+ @@re = haz_vars.map { |x| x + '$' }.join( '|')
185
+ @@re = Regexp.new "(#{@@re})$"
186
+
162
187
  end
163
188
  end
164
189
  end
data/lib/rhesus/utils.rb CHANGED
@@ -9,15 +9,15 @@ def template_base_dir
9
9
  File.expand_path( File.join( File.dirname(__FILE__), '..', 'templates' ) )
10
10
  end
11
11
 
12
- def copy_over_prebuilt_template base_path, name
13
- %w{model view controller ui}.each do |unit|
14
- FileUtils.mkdir_p File.join(base_path, name)
15
- from = File.join( template_base_dir, name , name + '_' + unit + '.rb')
16
- dest = File.join(base_path, name, name + '_' + unit + '.rb' )
17
- warn "cp '#{from}' to '#{dest}'"
18
- FileUtils.cp from, dest
19
- end
20
- end
12
+ #def copy_over_prebuilt_template base_path, name
13
+ # %w{model view controller ui}.each do |unit|
14
+ # FileUtils.mkdir_p File.join(base_path, name)
15
+ # from = File.join( template_base_dir, name , name + '_' + unit + '.rb')
16
+ # dest = File.join(base_path, name, name + '_' + unit + '.rb' )
17
+ # warn "cp '#{from}' to '#{dest}'"
18
+ # FileUtils.cp from, dest
19
+ # end
20
+ #end
21
21
 
22
22
  def setup_directory path
23
23
  FileUtils.mkdir_p path.gsub("\\", "/")
data/lib/version.rb CHANGED
@@ -1,11 +1,7 @@
1
1
  module Neurogami
2
2
  module Rhesus
3
3
  # :stopdoc:
4
- VERSION = '0.2.5'
5
- # :startdoc:
6
-
7
- # Returns the version string for the library.
8
- #
4
+ VERSION = '0.3.1'
9
5
 
10
6
  def self.version
11
7
  VERSION
data/test/test_rhesus.rb CHANGED
@@ -2,22 +2,24 @@ require 'rubygems'
2
2
  require 'bacon'
3
3
  require 'lib/rhesus/core'
4
4
 
5
+ $here = File.expand_path(File.dirname(__FILE__))
6
+
5
7
  describe 'A rhesus directory' do
6
8
 
7
9
  before do
10
+
8
11
  @nrc = Neurogami::Rhesus::Core
9
12
  class Neurogami::Rhesus::Core
10
- #def self.user_template_directory
11
- # "~/.rhesus"
12
- #end
13
-
13
+ def self.user_template_directory
14
+ "#{$here}/.rhesus"
15
+ end
14
16
  end
15
17
 
16
18
  end
17
19
 
18
-
20
+ # Not all that useful ....
19
21
  it 'should be in the home directory' do
20
- @nrc.user_template_directory.should.equal '/home/james/.rhesus'
22
+ @nrc.user_template_directory.should.equal $here + '/.rhesus'
21
23
  end
22
24
 
23
25
  it 'should exist' do
@@ -32,20 +34,25 @@ describe 'A rhesus directory' do
32
34
  @nrc.templates.size.should.equal 5
33
35
  end
34
36
 
37
+ end
38
+
39
+ describe 'The core Rhesus code' do
35
40
 
36
- #it 'should have 4 files in the monkeybars:about template set' do
37
- #end
41
+ it 'really needs to populate an Erb string with key/value pairs' do
42
+ template_text = "I've got <%= adj1 %>, \nand I'm <%= adj2 %> <%= adj3 %>"
43
+ variable_set = { :adj1 => 'soul' , :adj2 => 'super', :adj3 => 'bad' }
44
+ new_text = Neurogami::Rhesus::Core.process_template template_text, variable_set
45
+ new_text.should == "I've got soul, \nand I'm super bad"
46
+ end
38
47
 
39
- #it 'returns a project template reference given the qualified name "monkeybars:about"' do
40
- # pt = @nrc.get "monkeybars:about"
41
- # pt.class.should.equal Neurogami::Rhesus::TemplateSet
42
- #end
48
+ it 'dang well better extract variable names from Erb, bro' do
49
+ template_text = "I've got <%= adj1 %>, \nand I'm <%= adj2 %> <%= adj3 %>. And I mean <%= adj2 %> <%= adj3 %>"
43
50
 
44
- end
51
+ vars = Neurogami::Rhesus::Core.required_vars template_text.split( "\n")
52
+ vars.sort!
53
+ vars.should == ['adj1', 'adj2', 'adj3' ]
45
54
 
46
- __END__
55
+ end
47
56
 
48
- What are the key useful things we might want?
57
+ end
49
58
 
50
- * List available templates
51
- * Use one of those templates
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: Neurogami-rhesus
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.5
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - James Britt / Neurogami
@@ -56,7 +56,6 @@ files:
56
56
  - test/test_rhesus.rb
57
57
  has_rdoc: false
58
58
  homepage: http://www.neurogami.com/code
59
- licenses:
60
59
  post_install_message:
61
60
  rdoc_options:
62
61
  - --main
@@ -80,7 +79,7 @@ requirements: []
80
79
  rubyforge_project: !binary |
81
80
  AA==
82
81
 
83
- rubygems_version: 1.3.5
82
+ rubygems_version: 1.2.0
84
83
  signing_key:
85
84
  specification_version: 3
86
85
  summary: Really simple, practical code generator.