deathsyn-seedling 0.0.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/AUTHORS +3 -0
- data/CHANGELOG +72 -0
- data/MANIFEST +42 -0
- data/README +28 -0
- data/Rakefile +68 -0
- data/bin/seedling +15 -0
- data/lib/seedling.rb +5 -0
- data/lib/seedling/bin.rb +196 -0
- data/lib/seedling/extensions/inflector.rb +283 -0
- data/lib/seedling/project_creator.rb +147 -0
- data/lib/seedling/version.rb +3 -0
- data/lib/templates/core/Rakefile.seed +68 -0
- data/lib/templates/core/lib/library.rb.seed +5 -0
- data/lib/templates/core/lib/library/version.rb.seed +3 -0
- data/lib/templates/core/spec/helper.rb.seed +28 -0
- data/lib/templates/core/tasks/authors.rake +30 -0
- data/lib/templates/core/tasks/bacon.rake +70 -0
- data/lib/templates/core/tasks/changelog.rake +18 -0
- data/lib/templates/core/tasks/copyright.rake +21 -0
- data/lib/templates/core/tasks/gem.rake +23 -0
- data/lib/templates/core/tasks/gem_installer.rake +76 -0
- data/lib/templates/core/tasks/install_dependencies.rake +6 -0
- data/lib/templates/core/tasks/manifest.rake +4 -0
- data/lib/templates/core/tasks/rcov.rake +23 -0
- data/lib/templates/core/tasks/release.rake +52 -0
- data/lib/templates/core/tasks/reversion.rake +8 -0
- data/lib/templates/core/tasks/setup.rake.seed +15 -0
- data/seedling.gemspec +38 -0
- data/spec/helper.rb +28 -0
- data/tasks/authors.rake +30 -0
- data/tasks/bacon.rake +70 -0
- data/tasks/changelog.rake +18 -0
- data/tasks/copyright.rake +21 -0
- data/tasks/gem.rake +23 -0
- data/tasks/gem_installer.rake +76 -0
- data/tasks/install_dependencies.rake +6 -0
- data/tasks/manifest.rake +4 -0
- data/tasks/rcov.rake +23 -0
- data/tasks/release.rake +52 -0
- data/tasks/reversion.rake +8 -0
- data/tasks/setup.rake +15 -0
- data/tasks/yard.rake +4 -0
- metadata +101 -0
data/AUTHORS
ADDED
data/CHANGELOG
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
[27deb65 | Thu May 14 15:30:14 UTC 2009] Kevin Berry <kevin@opensourcealchemist.com>
|
2
|
+
|
3
|
+
* Version 0.0.1
|
4
|
+
|
5
|
+
[4017044 | Thu May 14 14:50:26 UTC 2009] Kevin Berry <kevinberry@nrs.us>
|
6
|
+
|
7
|
+
* Remove old library dir, and correct erb output for library.rb.seed
|
8
|
+
|
9
|
+
[04d16e0 | Thu May 14 14:45:02 UTC 2009] Kevin Berry <kevinberry@nrs.us>
|
10
|
+
|
11
|
+
* Get the library module and children in the right place. TODO: Remove library directory from plant.
|
12
|
+
|
13
|
+
[25e0453 | Thu May 14 14:09:29 UTC 2009] Kevin Berry <kevinberry@nrs.us>
|
14
|
+
|
15
|
+
* Fix erb calls (Railsism doesn't work!)
|
16
|
+
|
17
|
+
[f8eeba5 | Wed May 13 18:55:39 UTC 2009] Kevin Berry <kevinberry@nrs.us>
|
18
|
+
|
19
|
+
* Add params for doc_generator, test_suite, correct email parameter.
|
20
|
+
|
21
|
+
[ead7fbf | Wed May 13 18:22:26 UTC 2009] Kevin Berry <kevinberry@nrs.us>
|
22
|
+
|
23
|
+
* Add rubyforge_project commandline option.
|
24
|
+
|
25
|
+
[fb7663b | Wed May 13 17:34:18 UTC 2009] Kevin Berry <kevinberry@nrs.us>
|
26
|
+
|
27
|
+
* Fix a couple of templates, and add more planting options.
|
28
|
+
|
29
|
+
[eb1d0d0 | Wed May 13 15:40:01 UTC 2009] Kevin Berry <kevinberry@nrs.us>
|
30
|
+
|
31
|
+
* Convert setup into a seed (erb) so that bacon/rspec and rdoc/yard choices can be made.
|
32
|
+
|
33
|
+
[771f9d3 | Tue May 12 23:12:42 UTC 2009] Kevin Berry <KevinBerry@nrs.us>
|
34
|
+
|
35
|
+
* rest of erb to seed conversion.
|
36
|
+
|
37
|
+
[72aa1b4 | Tue May 12 23:06:40 UTC 2009] Kevin Berry <KevinBerry@nrs.us>
|
38
|
+
|
39
|
+
* Adjust library.rb.erb to library.rb.seed, and adjust template data to match new standards.
|
40
|
+
|
41
|
+
[2f71f19 | Tue May 12 22:50:37 UTC 2009] TJ Vanderpoel <bougy.man@gmail.com>
|
42
|
+
|
43
|
+
* changed extension for templates to be parsed with erb to .seed to remove conflicts with actual .erb files. added most options to Rakefile.seed. TODO: finish out Rakefile.seed and move on to more .seed files where dynamic values are needed
|
44
|
+
|
45
|
+
[aff3223 | Mon May 11 19:41:52 UTC 2009] TJ Vanderpoel <bougyman@zero.(none)>
|
46
|
+
|
47
|
+
* added bin/seedling and began forming bin.rb to seedling usage
|
48
|
+
|
49
|
+
[6765184 | Sun May 10 22:32:16 UTC 2009] Kevin Berry <Kevin Berry>
|
50
|
+
|
51
|
+
* Modify Rakefile.erb to get some project info, need to get ProjectCreator to feed the right info.
|
52
|
+
|
53
|
+
[5917d53 | Sun May 10 03:42:26 UTC 2009] Kevin Berry <Kevin Berry>
|
54
|
+
|
55
|
+
* Make plant work.
|
56
|
+
|
57
|
+
[f02eaf1 | Sun May 10 03:06:22 UTC 2009] Kevin Berry <Kevin Berry>
|
58
|
+
|
59
|
+
* Bring in initial generator and ProjectCreator kit (stripped down bougyman's autumn library.)
|
60
|
+
|
61
|
+
[22fb2a5 | Fri May 08 03:19:21 UTC 2009] TJ Vanderpoel <bougy.man@gmail.com>
|
62
|
+
|
63
|
+
* changed env variable for versioning to VERSION
|
64
|
+
|
65
|
+
[6329710 | Fri May 08 03:07:50 UTC 2009] TJ Vanderpoel <bougy.man@gmail.com>
|
66
|
+
|
67
|
+
* added yard task and a README, plus a .gitignore
|
68
|
+
|
69
|
+
[41fd3c5 | Thu May 07 19:21:22 UTC 2009] TJ Vanderpoel <bougy.man@gmail.com>
|
70
|
+
|
71
|
+
* new tree to begin seedling work
|
72
|
+
|
data/MANIFEST
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
AUTHORS
|
2
|
+
CHANGELOG
|
3
|
+
MANIFEST
|
4
|
+
README
|
5
|
+
Rakefile
|
6
|
+
bin/seedling
|
7
|
+
lib/seedling.rb
|
8
|
+
lib/seedling/bin.rb
|
9
|
+
lib/seedling/extensions/inflector.rb
|
10
|
+
lib/seedling/project_creator.rb
|
11
|
+
lib/seedling/version.rb
|
12
|
+
lib/templates/core/Rakefile.seed
|
13
|
+
lib/templates/core/lib/library.rb.seed
|
14
|
+
lib/templates/core/lib/library/version.rb.seed
|
15
|
+
lib/templates/core/spec/helper.rb.seed
|
16
|
+
lib/templates/core/tasks/authors.rake
|
17
|
+
lib/templates/core/tasks/bacon.rake
|
18
|
+
lib/templates/core/tasks/changelog.rake
|
19
|
+
lib/templates/core/tasks/copyright.rake
|
20
|
+
lib/templates/core/tasks/gem.rake
|
21
|
+
lib/templates/core/tasks/gem_installer.rake
|
22
|
+
lib/templates/core/tasks/install_dependencies.rake
|
23
|
+
lib/templates/core/tasks/manifest.rake
|
24
|
+
lib/templates/core/tasks/rcov.rake
|
25
|
+
lib/templates/core/tasks/release.rake
|
26
|
+
lib/templates/core/tasks/reversion.rake
|
27
|
+
lib/templates/core/tasks/setup.rake.seed
|
28
|
+
seedling.gemspec
|
29
|
+
spec/helper.rb
|
30
|
+
tasks/authors.rake
|
31
|
+
tasks/bacon.rake
|
32
|
+
tasks/changelog.rake
|
33
|
+
tasks/copyright.rake
|
34
|
+
tasks/gem.rake
|
35
|
+
tasks/gem_installer.rake
|
36
|
+
tasks/install_dependencies.rake
|
37
|
+
tasks/manifest.rake
|
38
|
+
tasks/rcov.rake
|
39
|
+
tasks/release.rake
|
40
|
+
tasks/reversion.rake
|
41
|
+
tasks/setup.rake
|
42
|
+
tasks/yard.rake
|
data/README
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
==Seedling
|
2
|
+
----------
|
3
|
+
|
4
|
+
Seedling is a tool for creating ruby projects. It aims to add
|
5
|
+
tasks (via a Rakefile and some tasks/*.rake) which allow for quick
|
6
|
+
and easy publishing of your new ruby library, via github and or rubyforge.
|
7
|
+
It automates some of the monotony such as
|
8
|
+
|
9
|
+
* Re-Versioning
|
10
|
+
* AUTHORS updating
|
11
|
+
* .gemspec updates
|
12
|
+
* building a gem, tarball, zip, source export tree
|
13
|
+
* Test (spec) running, via a bacon task and bacon spec helper (we love bacon)
|
14
|
+
* Documentation via yard
|
15
|
+
* CHANGELOG updating
|
16
|
+
|
17
|
+
== Download
|
18
|
+
|
19
|
+
using git
|
20
|
+
git clone git://rubyists.com/gits/seedling
|
21
|
+
|
22
|
+
==Usage
|
23
|
+
-------
|
24
|
+
|
25
|
+
We're getting there. Will be
|
26
|
+
seedling plant /path/to/tree
|
27
|
+
|
28
|
+
Copyright(c) 2009 The Rubyists
|
data/Rakefile
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
begin; require 'rubygems'; rescue LoadError; end
|
2
|
+
|
3
|
+
require 'rake'
|
4
|
+
require 'rake/clean'
|
5
|
+
require 'rake/gempackagetask'
|
6
|
+
require 'time'
|
7
|
+
require 'date'
|
8
|
+
require "lib/seedling"
|
9
|
+
|
10
|
+
PROJECT_SPECS = FileList[
|
11
|
+
'spec/**/*.rb'
|
12
|
+
]
|
13
|
+
|
14
|
+
PROJECT_MODULE = 'Seedling'
|
15
|
+
PROJECT_README = 'README'
|
16
|
+
#PROJECT_RUBYFORGE_GROUP_ID = 3034
|
17
|
+
PROJECT_COPYRIGHT = [
|
18
|
+
"# Copyright (c) #{Time.now.year} The Rubyists rubyists@rubyists.com",
|
19
|
+
"# Distributed under the terms of the MIT license."
|
20
|
+
]
|
21
|
+
|
22
|
+
# To release the monthly version do:
|
23
|
+
# $ PROJECT_VERSION=2009.03 rake release
|
24
|
+
IGNORE_FILES = [/\.gitignore/]
|
25
|
+
|
26
|
+
GEMSPEC = Gem::Specification.new{|s|
|
27
|
+
s.name = 'seedling'
|
28
|
+
s.author = "Kevin Berry"
|
29
|
+
s.summary = "A lightweight tool to create new ruby library trees, with helpers to make gemming and maintaining a breeze."
|
30
|
+
s.description = s.summary
|
31
|
+
s.email = 'deathsyn@gmail.com'
|
32
|
+
s.homepage = 'http://github.com/deathsyn/seedling'
|
33
|
+
s.platform = Gem::Platform::RUBY
|
34
|
+
s.version = (ENV['VERSION'] || (begin;Object.const_get(PROJECT_MODULE)::VERSION;rescue;Date.today.strftime("%Y.%m.%d");end))
|
35
|
+
s.files = `git ls-files`.split("\n").sort.reject { |f| IGNORE_FILES.detect { |exp| f.match(exp) } }
|
36
|
+
s.has_rdoc = true
|
37
|
+
s.require_path = 'lib'
|
38
|
+
s.bindir = "bin"
|
39
|
+
s.executables = ["seedling"]
|
40
|
+
s.rubyforge_project = "seedling"
|
41
|
+
|
42
|
+
s.post_install_message = <<MESSAGE.strip
|
43
|
+
============================================================
|
44
|
+
|
45
|
+
Thank you for installing Seedling!
|
46
|
+
Begin by planting your ruby project with
|
47
|
+
# seedling plant /path/to/new/project
|
48
|
+
|
49
|
+
============================================================
|
50
|
+
MESSAGE
|
51
|
+
}
|
52
|
+
|
53
|
+
Dir['tasks/*.rake'].each{|f| import(f) }
|
54
|
+
|
55
|
+
task :default => [:bacon]
|
56
|
+
|
57
|
+
CLEAN.include %w[
|
58
|
+
**/.*.sw?
|
59
|
+
*.gem
|
60
|
+
.config
|
61
|
+
**/*~
|
62
|
+
**/{data.db,cache.yaml}
|
63
|
+
*.yaml
|
64
|
+
pkg
|
65
|
+
rdoc
|
66
|
+
ydoc
|
67
|
+
*coverage*
|
68
|
+
]
|
data/bin/seedling
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
begin
|
3
|
+
require "pathname"
|
4
|
+
local_seedling = Pathname.new(__FILE__).expand_path.dirname.join("..", "lib", "seedling.rb")
|
5
|
+
if local_seedling.file?
|
6
|
+
require local_seedling
|
7
|
+
else
|
8
|
+
require "seedling"
|
9
|
+
end
|
10
|
+
require "seedling/bin"
|
11
|
+
rescue LoadError
|
12
|
+
require "rubygems"
|
13
|
+
require "seedling/bin"
|
14
|
+
end
|
15
|
+
Seedling::Bin::Cmd.run(ARGV)
|
data/lib/seedling.rb
ADDED
data/lib/seedling/bin.rb
ADDED
@@ -0,0 +1,196 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'optparse'
|
3
|
+
require "seedling/extensions/inflector"
|
4
|
+
### This module offers the functionality to create.
|
5
|
+
module Seedling
|
6
|
+
module Bin
|
7
|
+
class Cmd # This class contains the command methods {{{
|
8
|
+
#include Helpers
|
9
|
+
attr_accessor :command
|
10
|
+
|
11
|
+
def initialize(args = nil)
|
12
|
+
args ||= ARGV
|
13
|
+
raise "arguments must be an array!" unless args.respond_to?(:detect)
|
14
|
+
@ourargs = args.dup
|
15
|
+
@command = args.detect { |arg| arg.match(/^(?:--?)?(?:plant|create|h(?:elp)?|v(?:ersion)?|console)/) }
|
16
|
+
if command.nil?
|
17
|
+
@command = ""
|
18
|
+
else
|
19
|
+
args.delete(@command)
|
20
|
+
end
|
21
|
+
ARGV.replace(args)
|
22
|
+
end
|
23
|
+
|
24
|
+
# {{{ #run is called when we're interactive ($0 == __FILE__)
|
25
|
+
def self.run(args = nil)
|
26
|
+
cmd = new(args)
|
27
|
+
case cmd.command
|
28
|
+
when /^(?:--?)?(?:plant|create)$/
|
29
|
+
require "seedling/project_creator"
|
30
|
+
cmd.plant(cmd.command)
|
31
|
+
when /^(?:--?)?console$/
|
32
|
+
require "irb"
|
33
|
+
require "irb/completion"
|
34
|
+
cmd.include_seedling
|
35
|
+
IRB.start
|
36
|
+
puts "Seedling session has ended."
|
37
|
+
when /^(?:--?)?h(elp)?$/
|
38
|
+
puts cmd.usage
|
39
|
+
when /^(?:--?)?v(ersion)?$/
|
40
|
+
cmd.include_seedling
|
41
|
+
puts Seedling::VERSION
|
42
|
+
exit
|
43
|
+
when /^$/
|
44
|
+
puts "Must supply a valid command"
|
45
|
+
puts cmd.usage
|
46
|
+
exit 1
|
47
|
+
else
|
48
|
+
puts "#{command} not implemented"
|
49
|
+
puts cmd.usage
|
50
|
+
exit 1
|
51
|
+
end
|
52
|
+
end # }}}
|
53
|
+
|
54
|
+
def include_seedling # {{{
|
55
|
+
begin
|
56
|
+
$LOAD_PATH.unshift File.join(File.dirname(__FILE__), '/../lib')
|
57
|
+
require 'seedling'
|
58
|
+
rescue LoadError
|
59
|
+
$LOAD_PATH.shift
|
60
|
+
|
61
|
+
begin
|
62
|
+
require 'rubygems'
|
63
|
+
rescue LoadError
|
64
|
+
end
|
65
|
+
require 'seedling'
|
66
|
+
end
|
67
|
+
end # }}}
|
68
|
+
|
69
|
+
def usage # {{{
|
70
|
+
txt = [
|
71
|
+
"\n Usage:",
|
72
|
+
"seedling <plant|create|console> PROJECT [options]\n",
|
73
|
+
"Commands:\n",
|
74
|
+
" plant - Creates a new prototype Seedling application in a directory named PROJECT in",
|
75
|
+
" the current directory. seedling create foo would make ./foo containing a",
|
76
|
+
" seedling prototype.\n",
|
77
|
+
" create - Synonymous with plant.\n",
|
78
|
+
" console - Starts an irb console with seedling (and irb completion) loaded.",
|
79
|
+
" ARGV is passed on to IRB.\n\n"
|
80
|
+
].join("\n\t")
|
81
|
+
|
82
|
+
txt << "* All commands take PROJECT as the directory the seedling lives in.\n\n"
|
83
|
+
txt << plant_options.to_s << "\n"
|
84
|
+
#if is_windows?
|
85
|
+
#txt << %x{ruby #{rackup_path} --help}.split("\n").reject { |line| line.match(/^Usage:/) }.join("\n\t")
|
86
|
+
#else
|
87
|
+
#txt << %x{#{rackup_path} --help}.split("\n").reject { |line| line.match(/^Usage:/) }.join("\n\t")
|
88
|
+
#end
|
89
|
+
end # }}}
|
90
|
+
|
91
|
+
def al_root
|
92
|
+
require "pathname"
|
93
|
+
dir = nil
|
94
|
+
if ARGV.size == 1
|
95
|
+
dir = Pathname.new(ARGV.shift)
|
96
|
+
elsif ARGV.size > 1
|
97
|
+
$stderr.puts "Unknown options given #{ARGV.join(" ")}"
|
98
|
+
puts usage
|
99
|
+
exit 1
|
100
|
+
end
|
101
|
+
if dir.nil? or not dir.directory?
|
102
|
+
dir = Pathname.new(ENV["PWD"]).expand_path
|
103
|
+
$stderr.puts "Path to seedling tree not given or invalid, using #{dir}"
|
104
|
+
end
|
105
|
+
Object.const_set("AL_ROOT", dir.expand_path.to_s)
|
106
|
+
Dir.chdir(AL_ROOT)
|
107
|
+
end
|
108
|
+
|
109
|
+
### Methods for commands {{{
|
110
|
+
def plant_options(opts = {})
|
111
|
+
@plant_opts ||= OptionParser.new do |o|
|
112
|
+
o.banner = "Planting Options"
|
113
|
+
o.on("-nSUMMARY", "--summary SUMMARY", "Short description of this project") { |yn| opts[:summary] = yn }
|
114
|
+
o.on("-dDESCRIPTION", "--description DESCRIPTION", "Longer description (Default: summary)") { |des| opts[:description] = des }
|
115
|
+
o.on("-lLIBNAME", "--libname LIBNAME", "Library name (Default: path specifcation)") { |libname| opts[:lib_name] = libname }
|
116
|
+
o.on("-gDOCGENERATOR", "--doc-generator DOCGENERATOR", "Preferred documentation generator (Default: yard)") { |docgenerator| opts[:doc_generator] = docgenerator }
|
117
|
+
o.on("-tTESTSUITE", "--test-suite TESTSUITE", "Preferred test suite (Default: bacon)") { |testsuite| opts[:test_suite] = testsuite }
|
118
|
+
o.on("-vVER", "--version VER", "Initial version number (Default: 0.0.1)") { |ver| opts[:version] = ver }
|
119
|
+
o.on("-rRUBYFORGE", "--rubyforge RUBYFORGE", "Rubyforge project name") { |rubyforge| opts[:rubyforge_project] = rubyforge }
|
120
|
+
|
121
|
+
o.separator ""
|
122
|
+
o.separator "Author Options"
|
123
|
+
o.on("-sAUTHOR", "--summary AUTHOR", "Author's Name") { |yn| opts[:author_name] = yn }
|
124
|
+
o.on("-eEMAIL", "--email EMAIL", "Author's Email") { |yn| opts[:author_email] = yn }
|
125
|
+
o.on("-uURL", "--url URL", "Project URL/homepage") { |url| opts[:project_url] = url }
|
126
|
+
|
127
|
+
o.separator ""
|
128
|
+
o.separator "Directory Creation Options"
|
129
|
+
o.on("-f", "--force", "Force creation if dir already exists") { |yn| opts[:force] = true }
|
130
|
+
o.on("-a", "--amend", "Update a tree") { |yn| opts[:amend] = true }
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
def plant(command) # {{{
|
135
|
+
plant_options(o = {}).parse!(ARGV)
|
136
|
+
unless ARGV.size == 1
|
137
|
+
$stderr.puts "Invalid options given: #{ARGV.join(" ")}"
|
138
|
+
exit 1
|
139
|
+
end
|
140
|
+
project_root = ARGV.shift
|
141
|
+
if project_root.nil?
|
142
|
+
$stderr.puts "Must supply a valid directory to install your project, you gave none."
|
143
|
+
puts usage
|
144
|
+
exit 1
|
145
|
+
end
|
146
|
+
o[:lib_name] ||= Pathname.new(project_root).basename.to_s.classify
|
147
|
+
o[:lib_name_u] ||= o[:lib_name].underscore
|
148
|
+
opts = plant_defaults(o)
|
149
|
+
# need to titleize this
|
150
|
+
include_seedling
|
151
|
+
Seedling::ProjectCreator.new(project_root, opts).create
|
152
|
+
end # }}}
|
153
|
+
|
154
|
+
private
|
155
|
+
|
156
|
+
# Sets all of our default settings to make a sane rakefile, pulling from everywhere that makes sense
|
157
|
+
def plant_defaults(o = {:lib_name => "Seedling"})
|
158
|
+
# this shouldn't happen, but if so let's be descriptive
|
159
|
+
raise "plant_defaults requires a :lib_name in the calling argument" unless o[:lib_name]
|
160
|
+
o[:lib_name_u] = o[:lib_name].underscore
|
161
|
+
[:author_name, :author_email].each do |opt|
|
162
|
+
o[opt] = self.send(opt)
|
163
|
+
end
|
164
|
+
o[:summary] ||= "The #{o[:lib_name].classify.titleize} library, by #{o[:author_name]}"
|
165
|
+
o[:description] ||= o[:summary]
|
166
|
+
o[:version] ||= "0.0.1"
|
167
|
+
o[:test_suite] ||= "bacon"
|
168
|
+
o[:doc_generator] ||= "yard"
|
169
|
+
o
|
170
|
+
end
|
171
|
+
|
172
|
+
def author_email
|
173
|
+
gitted = %x{git config --global --get user.email}
|
174
|
+
return gitted.to_s.strip if gitted.to_s.match(/\w/)
|
175
|
+
return ENV["EMAIL"] if ENV["EMAIL"]
|
176
|
+
return [ENV["LOGUSER"], ENV["HOSTNAME"]].join("@") if ENV["LOGUSER"] and ENV["HOSTNAME"]
|
177
|
+
raise "Cannot find author email, please use --email \"you@your.domain.com\" or set the EMAIL environment variable"
|
178
|
+
end
|
179
|
+
|
180
|
+
def author_name
|
181
|
+
gitted = %x{git config --global --get user.name}
|
182
|
+
return gitted.to_s.strip if gitted.to_s.match(/\w/)
|
183
|
+
return ENV["NAME"] if ENV["NAME"]
|
184
|
+
return ENV["LOGUSER"] if ENV["LOGUSER"]
|
185
|
+
return Pathname.new(ENV["HOME"]).expand_path.basename.to_s if ENV["HOME"]
|
186
|
+
raise "Cannot find author name, please use --author \"Your Name\" or set the NAME or LOGUSER environment variables"
|
187
|
+
end
|
188
|
+
|
189
|
+
### End of command methods }}}
|
190
|
+
end # }}}
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
if $0 == __FILE__
|
195
|
+
Seedling::Bin::Cmd.run(ARGV)
|
196
|
+
end
|
@@ -0,0 +1,283 @@
|
|
1
|
+
# Add inflection methods to String, which allows the easy transformation of
|
2
|
+
# words from singular to plural,class names to table names, modularized class
|
3
|
+
# names to ones without, and class names to foreign keys.
|
4
|
+
|
5
|
+
class String
|
6
|
+
# This module acts as a singleton returned/yielded by String.inflections,
|
7
|
+
# which is used to override or specify additional inflection rules. Examples:
|
8
|
+
#
|
9
|
+
# String.inflections do |inflect|
|
10
|
+
# inflect.plural /^(ox)$/i, '\1\2en'
|
11
|
+
# inflect.singular /^(ox)en/i, '\1'
|
12
|
+
#
|
13
|
+
# inflect.irregular 'octopus', 'octopi'
|
14
|
+
#
|
15
|
+
# inflect.uncountable "equipment"
|
16
|
+
# end
|
17
|
+
#
|
18
|
+
# New rules are added at the top. So in the example above, the irregular rule for octopus will now be the first of the
|
19
|
+
# pluralization and singularization rules that is runs. This guarantees that your rules run before any of the rules that may
|
20
|
+
# already have been loaded.
|
21
|
+
module Inflections
|
22
|
+
@plurals, @singulars, @uncountables = [], [], []
|
23
|
+
|
24
|
+
class << self
|
25
|
+
attr_reader :plurals, :singulars, :uncountables
|
26
|
+
end
|
27
|
+
|
28
|
+
# Clears the loaded inflections within a given scope (default is :all). Give the scope as a symbol of the inflection type,
|
29
|
+
# the options are: :plurals, :singulars, :uncountables
|
30
|
+
#
|
31
|
+
# Examples:
|
32
|
+
# clear :all
|
33
|
+
# clear :plurals
|
34
|
+
def self.clear(scope = :all)
|
35
|
+
case scope
|
36
|
+
when :all
|
37
|
+
@plurals, @singulars, @uncountables = [], [], []
|
38
|
+
else
|
39
|
+
instance_variable_set("@#{scope}", [])
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# Specifies a new irregular that applies to both pluralization and singularization at the same time. This can only be used
|
44
|
+
# for strings, not regular expressions. You simply pass the irregular in singular and plural form.
|
45
|
+
#
|
46
|
+
# Examples:
|
47
|
+
# irregular 'octopus', 'octopi'
|
48
|
+
# irregular 'person', 'people'
|
49
|
+
def self.irregular(singular, plural)
|
50
|
+
plural(Regexp.new("(#{singular[0,1]})#{singular[1..-1]}$", "i"), '\1' + plural[1..-1])
|
51
|
+
singular(Regexp.new("(#{plural[0,1]})#{plural[1..-1]}$", "i"), '\1' + singular[1..-1])
|
52
|
+
end
|
53
|
+
|
54
|
+
# Specifies a new pluralization rule and its replacement. The rule can either be a string or a regular expression.
|
55
|
+
# The replacement should always be a string that may include references to the matched data from the rule.
|
56
|
+
#
|
57
|
+
# Example:
|
58
|
+
# plural(/(x|ch|ss|sh)$/i, '\1es')
|
59
|
+
def self.plural(rule, replacement)
|
60
|
+
@plurals.insert(0, [rule, replacement])
|
61
|
+
end
|
62
|
+
|
63
|
+
# Specifies a new singularization rule and its replacement. The rule can either be a string or a regular expression.
|
64
|
+
# The replacement should always be a string that may include references to the matched data from the rule.
|
65
|
+
#
|
66
|
+
# Example:
|
67
|
+
# singular(/([^aeiouy]|qu)ies$/i, '\1y')
|
68
|
+
def self.singular(rule, replacement)
|
69
|
+
@singulars.insert(0, [rule, replacement])
|
70
|
+
end
|
71
|
+
|
72
|
+
# Add uncountable words that shouldn't be attempted inflected.
|
73
|
+
#
|
74
|
+
# Examples:
|
75
|
+
# uncountable "money"
|
76
|
+
# uncountable "money", "information"
|
77
|
+
# uncountable %w( money information rice )
|
78
|
+
def self.uncountable(*words)
|
79
|
+
(@uncountables << words).flatten!
|
80
|
+
end
|
81
|
+
|
82
|
+
# Setup the default inflections
|
83
|
+
plural(/$/, 's')
|
84
|
+
plural(/s$/i, 's')
|
85
|
+
plural(/(ax|test)is$/i, '\1es')
|
86
|
+
plural(/(octop|vir)us$/i, '\1i')
|
87
|
+
plural(/(alias|status)$/i, '\1es')
|
88
|
+
plural(/(bu)s$/i, '\1ses')
|
89
|
+
plural(/(buffal|tomat)o$/i, '\1oes')
|
90
|
+
plural(/([ti])um$/i, '\1a')
|
91
|
+
plural(/sis$/i, 'ses')
|
92
|
+
plural(/(?:([^f])fe|([lr])f)$/i, '\1\2ves')
|
93
|
+
plural(/(hive)$/i, '\1s')
|
94
|
+
plural(/([^aeiouy]|qu)y$/i, '\1ies')
|
95
|
+
plural(/(x|ch|ss|sh)$/i, '\1es')
|
96
|
+
plural(/(matr|vert|ind)ix|ex$/i, '\1ices')
|
97
|
+
plural(/([m|l])ouse$/i, '\1ice')
|
98
|
+
plural(/^(ox)$/i, '\1en')
|
99
|
+
plural(/(quiz)$/i, '\1zes')
|
100
|
+
|
101
|
+
singular(/s$/i, '')
|
102
|
+
singular(/(n)ews$/i, '\1ews')
|
103
|
+
singular(/([ti])a$/i, '\1um')
|
104
|
+
singular(/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i, '\1\2sis')
|
105
|
+
singular(/(^analy)ses$/i, '\1sis')
|
106
|
+
singular(/([^f])ves$/i, '\1fe')
|
107
|
+
singular(/(hive)s$/i, '\1')
|
108
|
+
singular(/(tive)s$/i, '\1')
|
109
|
+
singular(/([lr])ves$/i, '\1f')
|
110
|
+
singular(/([^aeiouy]|qu)ies$/i, '\1y')
|
111
|
+
singular(/(s)eries$/i, '\1eries')
|
112
|
+
singular(/(m)ovies$/i, '\1ovie')
|
113
|
+
singular(/(x|ch|ss|sh)es$/i, '\1')
|
114
|
+
singular(/([m|l])ice$/i, '\1ouse')
|
115
|
+
singular(/(bus)es$/i, '\1')
|
116
|
+
singular(/(o)es$/i, '\1')
|
117
|
+
singular(/(shoe)s$/i, '\1')
|
118
|
+
singular(/(cris|ax|test)es$/i, '\1is')
|
119
|
+
singular(/(octop|vir)i$/i, '\1us')
|
120
|
+
singular(/(alias|status)es$/i, '\1')
|
121
|
+
singular(/^(ox)en/i, '\1')
|
122
|
+
singular(/(vert|ind)ices$/i, '\1ex')
|
123
|
+
singular(/(matr)ices$/i, '\1ix')
|
124
|
+
singular(/(quiz)zes$/i, '\1')
|
125
|
+
|
126
|
+
irregular('person', 'people')
|
127
|
+
irregular('man', 'men')
|
128
|
+
irregular('child', 'children')
|
129
|
+
irregular('sex', 'sexes')
|
130
|
+
irregular('move', 'moves')
|
131
|
+
|
132
|
+
uncountable(%w(equipment information rice money species series fish sheep))
|
133
|
+
end
|
134
|
+
|
135
|
+
# Yield the Inflections module if a block is given, and return
|
136
|
+
# the Inflections module.
|
137
|
+
def self.inflections
|
138
|
+
yield Inflections if block_given?
|
139
|
+
Inflections
|
140
|
+
end
|
141
|
+
|
142
|
+
# By default, camelize converts the string to UpperCamelCase. If the argument to camelize
|
143
|
+
# is set to :lower then camelize produces lowerCamelCase.
|
144
|
+
#
|
145
|
+
# camelize will also convert '/' to '::' which is useful for converting paths to namespaces
|
146
|
+
#
|
147
|
+
# Examples
|
148
|
+
# "active_record".camelize #=> "ActiveRecord"
|
149
|
+
# "active_record".camelize(:lower) #=> "activeRecord"
|
150
|
+
# "active_record/errors".camelize #=> "ActiveRecord::Errors"
|
151
|
+
# "active_record/errors".camelize(:lower) #=> "activeRecord::Errors"
|
152
|
+
def camelize(first_letter_in_uppercase = :upper)
|
153
|
+
s = gsub(/\/(.?)/){|x| "::#{x[-1..-1].upcase unless x == '/'}"}.gsub(/(^|_)(.)/){|x| x[-1..-1].upcase}
|
154
|
+
s[0...1] = s[0...1].downcase unless first_letter_in_uppercase == :upper
|
155
|
+
s
|
156
|
+
end
|
157
|
+
alias_method :camelcase, :camelize
|
158
|
+
|
159
|
+
# Singularizes and camelizes the string. Also strips out all characters preceding
|
160
|
+
# and including a period (".").
|
161
|
+
#
|
162
|
+
# Examples
|
163
|
+
# "egg_and_hams".classify #=> "EggAndHam"
|
164
|
+
# "post".classify #=> "Post"
|
165
|
+
# "schema.post".classify #=> "Post"
|
166
|
+
def classify
|
167
|
+
sub(/.*\./, '').singularize.camelize
|
168
|
+
end
|
169
|
+
|
170
|
+
# Constantize tries to find a declared constant with the name specified
|
171
|
+
# in the string. It raises a NameError when the name is not in CamelCase
|
172
|
+
# or is not initialized.
|
173
|
+
#
|
174
|
+
# Examples
|
175
|
+
# "Module".constantize #=> Module
|
176
|
+
# "Class".constantize #=> Class
|
177
|
+
def constantize
|
178
|
+
raise(NameError, "#{inspect} is not a valid constant name!") unless m = /\A(?:::)?([A-Z]\w*(?:::[A-Z]\w*)*)\z/.match(self)
|
179
|
+
Object.module_eval("::#{m[1]}", __FILE__, __LINE__)
|
180
|
+
end
|
181
|
+
|
182
|
+
# Replaces underscores with dashes in the string.
|
183
|
+
#
|
184
|
+
# Example
|
185
|
+
# "puni_puni".dasherize #=> "puni-puni"
|
186
|
+
def dasherize
|
187
|
+
gsub(/_/, '-')
|
188
|
+
end
|
189
|
+
|
190
|
+
# Removes the module part from the expression in the string
|
191
|
+
#
|
192
|
+
# Examples
|
193
|
+
# "ActiveRecord::CoreExtensions::String::Inflections".demodulize #=> "Inflections"
|
194
|
+
# "Inflections".demodulize #=> "Inflections"
|
195
|
+
def demodulize
|
196
|
+
gsub(/^.*::/, '')
|
197
|
+
end
|
198
|
+
|
199
|
+
# Creates a foreign key name from a class name.
|
200
|
+
# +use_underscore+ sets whether the method should put '_' between the name and 'id'.
|
201
|
+
#
|
202
|
+
# Examples
|
203
|
+
# "Message".foreign_key #=> "message_id"
|
204
|
+
# "Message".foreign_key(false) #=> "messageid"
|
205
|
+
# "Admin::Post".foreign_key #=> "post_id"
|
206
|
+
def foreign_key(use_underscore = true)
|
207
|
+
"#{demodulize.underscore}#{'_' if use_underscore}id"
|
208
|
+
end
|
209
|
+
|
210
|
+
# Capitalizes the first word and turns underscores into spaces and strips _id.
|
211
|
+
# Like titleize, this is meant for creating pretty output.
|
212
|
+
#
|
213
|
+
# Examples
|
214
|
+
# "employee_salary" #=> "Employee salary"
|
215
|
+
# "author_id" #=> "Author"
|
216
|
+
def humanize
|
217
|
+
gsub(/_id$/, "").gsub(/_/, " ").capitalize
|
218
|
+
end
|
219
|
+
|
220
|
+
# Returns the plural form of the word in the string.
|
221
|
+
#
|
222
|
+
# Examples
|
223
|
+
# "post".pluralize #=> "posts"
|
224
|
+
# "octopus".pluralize #=> "octopi"
|
225
|
+
# "sheep".pluralize #=> "sheep"
|
226
|
+
# "words".pluralize #=> "words"
|
227
|
+
# "the blue mailman".pluralize #=> "the blue mailmen"
|
228
|
+
# "CamelOctopus".pluralize #=> "CamelOctopi"
|
229
|
+
def pluralize
|
230
|
+
result = dup
|
231
|
+
Inflections.plurals.each{|(rule, replacement)| break if result.gsub!(rule, replacement)} unless Inflections.uncountables.include?(downcase)
|
232
|
+
result
|
233
|
+
end
|
234
|
+
|
235
|
+
# The reverse of pluralize, returns the singular form of a word in a string.
|
236
|
+
#
|
237
|
+
# Examples
|
238
|
+
# "posts".singularize #=> "post"
|
239
|
+
# "octopi".singularize #=> "octopus"
|
240
|
+
# "sheep".singluarize #=> "sheep"
|
241
|
+
# "word".singluarize #=> "word"
|
242
|
+
# "the blue mailmen".singularize #=> "the blue mailman"
|
243
|
+
# "CamelOctopi".singularize #=> "CamelOctopus"
|
244
|
+
def singularize
|
245
|
+
result = dup
|
246
|
+
Inflections.singulars.each{|(rule, replacement)| break if result.gsub!(rule, replacement)} unless Inflections.uncountables.include?(downcase)
|
247
|
+
result
|
248
|
+
end
|
249
|
+
|
250
|
+
# Underscores and pluralizes the string.
|
251
|
+
#
|
252
|
+
# Examples
|
253
|
+
# "RawScaledScorer".tableize #=> "raw_scaled_scorers"
|
254
|
+
# "egg_and_ham".tableize #=> "egg_and_hams"
|
255
|
+
# "fancyCategory".tableize #=> "fancy_categories"
|
256
|
+
def tableize
|
257
|
+
underscore.pluralize
|
258
|
+
end
|
259
|
+
|
260
|
+
# Capitalizes all the words and replaces some characters in the string to create
|
261
|
+
# a nicer looking title. Titleize is meant for creating pretty output.
|
262
|
+
#
|
263
|
+
# titleize is also aliased as as titlecase
|
264
|
+
#
|
265
|
+
# Examples
|
266
|
+
# "man from the boondocks".titleize #=> "Man From The Boondocks"
|
267
|
+
# "x-men: the last stand".titleize #=> "X Men: The Last Stand"
|
268
|
+
def titleize
|
269
|
+
underscore.humanize.gsub(/\b([a-z])/){|x| x[-1..-1].upcase}
|
270
|
+
end
|
271
|
+
alias_method :titlecase, :titleize
|
272
|
+
|
273
|
+
# The reverse of camelize. Makes an underscored form from the expression in the string.
|
274
|
+
# Also changes '::' to '/' to convert namespaces to paths.
|
275
|
+
#
|
276
|
+
# Examples
|
277
|
+
# "ActiveRecord".underscore #=> "active_record"
|
278
|
+
# "ActiveRecord::Errors".underscore #=> active_record/errors
|
279
|
+
def underscore
|
280
|
+
gsub(/::/, '/').gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
281
|
+
gsub(/([a-z\d])([A-Z])/,'\1_\2').tr("-", "_").downcase
|
282
|
+
end
|
283
|
+
end
|