starter 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -1,4 +1,5 @@
1
1
  $:.unshift("lib")
2
2
  require "starter/tasks/gems"
3
+ require "starter/tasks/github"
3
4
  require "starter/tasks/git"
4
5
 
@@ -0,0 +1,47 @@
1
+ # "local" methods are those defined directly on a class or module,
2
+ # as opposed to those inherited or mixed in
3
+ module Starter
4
+ module Extensions
5
+
6
+ module Module
7
+
8
+ def self.basename(mod)
9
+ mod.name.split('::').last
10
+ end
11
+
12
+ def self.local_methods(mod)
13
+ mod.public_methods.select do |m|
14
+ owner = mod.method(m).owner
15
+ owner == mod.singleton_class || owner == mod
16
+ end
17
+ end
18
+
19
+ def self.local_instance_methods(mod)
20
+ mod.public_instance_methods.select do |m|
21
+ owner = mod.instance_method(m).owner
22
+ owner == mod
23
+ end
24
+ end
25
+
26
+ # For every locally-defined class method, create an instance method
27
+ # of the same name which operates on the instance. This allows you
28
+ # to create Modules which can be used as mixins, but the methods are
29
+ # also available on the module itself, in case a user does not want
30
+ # to include the module.
31
+ def self.create_instance_methods(mod)
32
+ self.local_methods(mod).each do |method_name|
33
+ mod.module_eval <<-METHOD, __FILE__, __LINE__
34
+ def #{method_name}(*args)
35
+ #{mod}.#{method_name}(self, *args)
36
+ end
37
+ METHOD
38
+ end
39
+ end
40
+
41
+ self.create_instance_methods(self)
42
+
43
+ end
44
+
45
+ end
46
+ end
47
+
@@ -0,0 +1,62 @@
1
+ require "starter/extensions/module"
2
+ module Starter
3
+ module Extensions
4
+
5
+ module String
6
+
7
+ def self.camel_case(string)
8
+ string.split('_').map do |word|
9
+ "#{word.slice(/^\w/).upcase}#{word.slice(/^\w(\w+)/, 1)}"
10
+ end.join
11
+ end
12
+
13
+ def self.snake_case(string)
14
+ string.gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').gsub(/([a-z\d])([A-Z])/,'\1_\2').downcase
15
+ end
16
+
17
+ def self.title_case(string)
18
+ # FIXME: I think that the block form of gsub is not thread safe.
19
+ string.gsub( /\b\w/ ) { |x| x.upcase }
20
+ end
21
+
22
+ def self.hex(string)
23
+ string.unpack("H*")[0]
24
+ end
25
+
26
+ def self.unhex(string)
27
+ [string].pack("H*")
28
+ end
29
+
30
+ def self.xor(str1, str2)
31
+ a1 = str1.unpack('C*')
32
+ a2 = str2.unpack('C*') * (str1.length / str2.length + 1)
33
+ xor = ""
34
+ 0.upto(a1.length - 1) do |i|
35
+ x = a1[i] ^ a2[i].to_i
36
+ xor << x.chr()
37
+ end
38
+ xor
39
+ end
40
+
41
+ Starter::Extensions::Module.create_instance_methods(self)
42
+
43
+ module Compression
44
+ def self.included(mod)
45
+ require "zlib"
46
+ end
47
+
48
+ def self.gzip(string)
49
+ sio = StringIO.new
50
+ gz = Zlib::GzipWriter.new(sio)
51
+ gz.write(string)
52
+ gz.close
53
+ sio.string
54
+ end
55
+
56
+ Starter::Extensions::Module.create_instance_methods(self)
57
+ end
58
+
59
+ end
60
+
61
+ end
62
+ end
@@ -0,0 +1,12 @@
1
+ module Starter
2
+
3
+ module HTTP
4
+
5
+ def self.basic_auth(user, pass)
6
+ # TODO: I wrote a clearer version of this somewhere. Find and replace.
7
+ "Basic #{["#{user}:#{pass}"].pack('m').delete("\r\n")}"
8
+ end
9
+
10
+ end
11
+
12
+ end
@@ -0,0 +1,22 @@
1
+
2
+ module Starter
3
+ module Misc
4
+
5
+ def marshalize(filename, &block)
6
+ if File.exist?(filename)
7
+ File.open(filename) { |f| Marshal.load(f) }
8
+ elsif File.exist?(filename + ".gz")
9
+ system "gunzip #{filename}.gz"
10
+ File.open(filename) { |f| Marshal.load(f) }
11
+ else
12
+ val = yield
13
+ File.open(filename, "w") do |f|
14
+ Marshal.dump(val, f)
15
+ end
16
+ val
17
+ end
18
+ end
19
+
20
+
21
+ end
22
+ end
@@ -0,0 +1,72 @@
1
+ require "starter/extensions/module"
2
+ module Starter
3
+ module Mixins
4
+
5
+ module Stats
6
+
7
+ def self.summary(items)
8
+ sorted = items.sort
9
+ [
10
+ [:mean, sorted.mean],
11
+ [:stddev, sorted.standard_deviation],
12
+ [:min, sorted.first],
13
+ [:q1, sorted._quartile(1)],
14
+ [:median, sorted._median],
15
+ [:q3, sorted._quartile(3)],
16
+ [:max, sorted.last],
17
+ [:sample_size, sorted.size]
18
+ ]
19
+ end
20
+
21
+ def self.sum(items)
22
+ s = 0; items.each { |element| s += element }; s
23
+ end
24
+
25
+ def self.mean(items)
26
+ items.sum.to_f / items.size
27
+ end
28
+
29
+ def self.variance(items)
30
+ denom = items.size - 1
31
+ m = items.mean
32
+ s = 0
33
+ items.each { |element| s += (element - m)**2; }
34
+ s / denom
35
+ end
36
+
37
+ def self.standard_deviation(items)
38
+ Math.sqrt( items.variance )
39
+ end
40
+
41
+ def self.median(items)
42
+ self._median(items.sort)
43
+ end
44
+
45
+ def self.quartile(items, n)
46
+ raise ArgumentError unless n > 0 && n < 4
47
+ self._quartile(items.sort, n)
48
+ end
49
+
50
+ private
51
+
52
+ def self._quartile(sorted, n)
53
+ s = sorted.size
54
+ sorted[n * s/4]
55
+ end
56
+
57
+ def self._median(sorted)
58
+ s = sorted.size
59
+ i = s % 2
60
+ case i
61
+ when 0 then sorted[s/2 - 1, 2].mean
62
+ when 1 then sorted[s/2].to_f
63
+ end if sorted.size > 0
64
+ end
65
+
66
+ Starter::Extensions::Module.create_instance_methods(self)
67
+
68
+ end
69
+
70
+ end
71
+ end
72
+
@@ -0,0 +1,28 @@
1
+ require "starter/prompt"
2
+ module Starter
3
+
4
+ class Password < String
5
+ extend Prompt
6
+
7
+ def self.request(service)
8
+ begin
9
+ system "stty -echo"
10
+ value = prompt "Password for #{service}:"
11
+ ensure
12
+ system "stty echo"
13
+ puts
14
+ end
15
+ self.new(value)
16
+ end
17
+
18
+ def initialize(*args)
19
+ super
20
+ end
21
+
22
+ def inspect
23
+ "#<Starter::Password>"
24
+ end
25
+
26
+ end
27
+
28
+ end
@@ -0,0 +1,24 @@
1
+ module Starter
2
+
3
+ module Prompt
4
+ extend self
5
+
6
+ def prompt(string)
7
+ print "#{string} "
8
+ value = STDIN.gets.chomp
9
+ if value.size > 1
10
+ return value
11
+ else
12
+ puts "No, I really need a value. Try again."
13
+ prompt(string)
14
+ end
15
+ end
16
+
17
+ def confirm(string)
18
+ print "#{string} [y/N] "
19
+ true if STDIN.gets.chomp =~ /^y/i
20
+ end
21
+
22
+ end
23
+ end
24
+
@@ -0,0 +1,243 @@
1
+ require "openssl"
2
+ module Starter
3
+ module Random
4
+
5
+ def self.nonce(length)
6
+ OpenSSL::Random.random_bytes(length).unpack("H*").join
7
+ end
8
+
9
+ # Taken from http://redshift.sourceforge.net/sci/
10
+ # sci-0.2/lib/sci/random.rb
11
+ # Contact Joel VanderWerf, vjoel@users.sourceforge.net
12
+ # No license specified in original. Copyright assumed to be Joel VanderWerf.
13
+
14
+ # Base class for sequences that sample different kinds of distributions.
15
+ # The actual PRNG must be plugged in at initialization, or else ruby's
16
+ # global PRNG is used.
17
+ class Sequence
18
+ include Math
19
+
20
+ class RubyGlobalGenerator
21
+ def initialize(seed = nil)
22
+ srand(seed) if seed
23
+ end
24
+ def next
25
+ rand
26
+ end
27
+ end
28
+
29
+ attr_reader :generator
30
+
31
+ # Options are :seed and :generator.
32
+ #
33
+ # The :generator must either have a method #next that returns
34
+ # a float between 0 and 1, or a method #new that returns an instance
35
+ # that has such a #next method.
36
+ #
37
+ # If generator is not given, uses ruby's Kernel#rand (beware global state)
38
+ # and the :seed option.
39
+ #
40
+ def initialize opt = {}
41
+ gen = opt[:generator] || RubyGlobalGenerator
42
+ if gen.respond_to?(:new)
43
+ @generator = gen.new(opt[:seed])
44
+ else
45
+ @generator = gen
46
+ end
47
+ end
48
+
49
+ def self.serial_count
50
+ @count ||= 0
51
+ @count += 1
52
+ end
53
+
54
+ # A utility method for getting a random seed.
55
+ def self.random_seed
56
+ Sequence.random_pool_seed ||
57
+ ((Time.now.to_f * 1_000_000_000).to_i % 1_000_000_000) +
58
+ Sequence.serial_count + Process.pid
59
+ end
60
+
61
+ @@have_dev_random = true # assume so until evidence to contrary
62
+
63
+ def self.random_pool_seed
64
+ ## could also get random data from net
65
+ if @@have_dev_random
66
+ @random_pool ||= ""
67
+ if @random_pool.length < 4
68
+ File.open('/dev/random') do |dr|
69
+ if select([dr],nil,nil,0)
70
+ @random_pool << dr.sysread(100)
71
+ end
72
+ end
73
+ end
74
+ if @random_pool.length >= 4
75
+ @random_pool.slice!(-4..-1).unpack('L')[0]
76
+ end
77
+ end
78
+ rescue SystemCallError
79
+ @@have_dev_random = false
80
+ end
81
+
82
+ def next
83
+ @generator.next
84
+ end
85
+ end
86
+
87
+ class ConstantSequence < Sequence
88
+ attr_reader :mean
89
+
90
+ def initialize opt = {}
91
+ @mean = Float(opt[:mean] || 0)
92
+ end
93
+
94
+ def next
95
+ @mean
96
+ end
97
+ end
98
+
99
+ class UniformSequence < Sequence
100
+ attr_reader :min, :max
101
+
102
+ def initialize opt = {}
103
+ super
104
+ @min = Float(opt[:min] || 0)
105
+ @max = Float(opt[:max] || 1)
106
+ @delta = @max - @min
107
+ end
108
+
109
+ def next
110
+ @min + @delta*super
111
+ end
112
+ end
113
+
114
+ class ExponentialSequence < Sequence
115
+ attr_reader :mean
116
+
117
+ def initialize opt = {}
118
+ super
119
+ @mean = Float(opt[:mean] || 1)
120
+ end
121
+
122
+ def next
123
+ while (x=super) == 0.0; end
124
+ return -log(x) * @mean
125
+ end
126
+ end
127
+
128
+ class GaussianSequence < Sequence
129
+ attr_reader :mean, :stdev, :min, :max
130
+
131
+ def initialize opt = {}
132
+ super
133
+ @mean = Float(opt[:mean] || 0)
134
+ @stdev = Float(opt[:stdev] || 1)
135
+ @min = opt[:min]; @min = Float(@min) if @min
136
+ @max = opt[:max]; @max = Float(@max) if @max
137
+ @nextnext = nil
138
+ end
139
+
140
+ def next
141
+ if @nextnext
142
+ result = @mean + @nextnext*@stdev
143
+ @nextnext = nil
144
+
145
+ else
146
+ begin
147
+ v1 = 2 * super - 1
148
+ v2 = 2 * super - 1
149
+ rsq = v1*v1 + v2*v2
150
+ end while rsq >= 1 || rsq == 0
151
+
152
+ fac = sqrt(-2*log(rsq) / rsq)
153
+ @nextnext = v1*fac
154
+ result = @mean + v2*fac*@stdev
155
+ end
156
+
157
+ if @min and result < @min
158
+ result = @min
159
+ elsif @max and result > @max
160
+ result = @max
161
+ end
162
+
163
+ return result
164
+ end
165
+ end
166
+
167
+ # Based on newran02:
168
+ #
169
+ # Real VariLogNormal::Next(Real mean, Real sd)
170
+ # {
171
+ # // should have special version of log for small sd/mean
172
+ # Real n_var = log(1 + square(sd / mean));
173
+ # return mean * exp(N.Next() * sqrt(n_var) - 0.5 * n_var);
174
+ # }
175
+ #
176
+ class LogNormalSequence < Sequence
177
+ attr_reader :mean, :stdev
178
+
179
+ def initialize opt = {}
180
+ @gaussian_seq = GaussianSequence.new(
181
+ :mean => 0,
182
+ :stdev => 1,
183
+ :seed => opt[:seed],
184
+ :generator => opt[:generator]
185
+ )
186
+
187
+ super :generator => @gaussian_seq
188
+
189
+ @mean = Float(opt[:mean] || 1)
190
+ @stdev = Float(opt[:stdev] || 1)
191
+
192
+ n_var = log(1 + (stdev / mean)**2)
193
+ @sqrt_n_var = sqrt(n_var)
194
+ @half_n_var = 0.5 * n_var
195
+ end
196
+
197
+ def next
198
+ mean * exp(super() * @sqrt_n_var - @half_n_var)
199
+ end
200
+ end
201
+
202
+ class DiscreteSequence < Sequence
203
+ attr_reader :distrib
204
+
205
+ def initialize opt = {}
206
+ super
207
+ @distrib = opt[:distrib] || { 0 => 1.0 }
208
+
209
+ sum = @distrib.inject(0) {|sum, (pt, prob)| sum + prob}
210
+ sum = sum.to_f # so division is ok
211
+
212
+ @distrib.keys.each do |point|
213
+ @distrib[point] /= sum
214
+ end
215
+ end
216
+
217
+ def next
218
+ loop do
219
+ r = super
220
+ @distrib.each do |point, probability|
221
+ if r < probability
222
+ return point
223
+ end
224
+ r -= probability
225
+ end
226
+ # repeat if failed to get a result (due to floating point imprecision)
227
+ end
228
+ ## this would be faster using an rbtree
229
+ end
230
+ end
231
+
232
+ Constant = ConstantSequence
233
+ Uniform = UniformSequence
234
+ Exponential = ExponentialSequence
235
+ Gaussian = GaussianSequence
236
+ Normal = NormalSequence = GaussianSequence
237
+ LogNormal = LogNormalSequence
238
+ Discrete = DiscreteSequence
239
+
240
+ end
241
+
242
+
243
+ end
@@ -1,4 +1,4 @@
1
- require "starter/tasks/helpers"
1
+ require "starter/tasks/starter"
2
2
 
3
3
  $STARTER[:directory] = File.basename(Dir.pwd)
4
4
  $STARTER[:gemspec_file] = "#{$STARTER[:directory]}.gemspec"
@@ -1,4 +1,4 @@
1
- require "starter/tasks/helpers"
1
+ require "starter/tasks/starter"
2
2
 
3
3
  gemspec_path = FileList["*.gemspec"].first || "#{$STARTER[:directory]}.gemspec"
4
4
  project_name = gemspec_path.chomp(".gemspec")
@@ -13,14 +13,14 @@ directory "lib"
13
13
  file "lib/#{project_name}.rb" do |target|
14
14
  File.open(target.name, "w") do |file|
15
15
  file.puts <<-TXT
16
- module #{Starter::String.camel_case(project_name)}
16
+ module #{Starter::Extensions::String.camel_case(project_name)}
17
17
 
18
18
  end
19
19
  TXT
20
20
  end
21
21
  end
22
22
 
23
- file gemspec_path => %w[ determine_author ] do |target|
23
+ file gemspec_path do |target|
24
24
  File.open(target.name, "w") do |file|
25
25
  file.puts gemspec_template(
26
26
  :author => $STARTER[:author],
@@ -51,6 +51,15 @@ task "gem:dependencies" => "gemspec" do
51
51
  require "pp"
52
52
  pp gemspec.dependencies.first
53
53
  # install dependencies from gemspec
54
+
55
+ #require 'rubygems/dependency_installer'
56
+ #gems = Gem::SourceIndex.from_installed_gems
57
+ #installer = Gem::DependencyInstaller.new
58
+ #spec.dependencies.each do |dep|
59
+ #if gems.find_name(dep.name, dep.requirement).empty?
60
+ #installer.install(dep.name, dep.requirement)
61
+ #end
62
+ #end
54
63
  end
55
64
 
56
65
  task "version" => "read_gemspec" do
@@ -1,4 +1,4 @@
1
- require "starter/tasks/helpers"
1
+ require "starter/tasks/starter"
2
2
 
3
3
  task "release" => %w[ git:tag ]
4
4
 
@@ -0,0 +1,93 @@
1
+ require "starter/tasks/starter"
2
+
3
+ desc "Create an issue on GitHub"
4
+ task "github:issue" => "github_repo" do
5
+
6
+ repo = $STARTER[:github_repo]
7
+ options = {}
8
+ $stdout.print "Title: "; $stdout.flush
9
+ options[:title] = $stdin.readline.strip
10
+ $stdout.print "Description: "; $stdout.flush
11
+ options[:description] = $stdin.readline.strip
12
+ labels = repo.labels.map { |label| label["name"] }.join(" ")
13
+ $stdout.print "Labels (separate with spaces: [#{labels}]): "; $stdout.flush
14
+ options[:labels] = $stdin.readline.strip.split(" ")
15
+ $stdout.puts "Milestone:"
16
+ repo.milestones.each do |milestone|
17
+ $stdout.puts "#{milestone['number']} - #{milestone['title']}"
18
+ end
19
+ milestone = $stdin.readline.strip
20
+ options[:milestone] = milestone unless milestone.empty?
21
+
22
+ print "Issue details: "
23
+ if Starter::Prompt.confirm("Create this issue?")
24
+ result = repo.issues.create(options)
25
+ if result["errors"]
26
+ result["errors"].each do |error|
27
+ $stderr.puts "#{error['resource']}: #{error['message']}"
28
+ end
29
+ else
30
+ $stdout.puts "Issue ##{result['number']} created."
31
+ end
32
+ end
33
+ end
34
+
35
+
36
+ task "github_repo" => %w[ github_settings github_password ] do
37
+ require 'ghee'
38
+
39
+ settings = $STARTER[:settings][:github]
40
+ user, password, repo = settings.values_at(:user, :password, :repo)
41
+ ghee = Ghee.basic_auth(user,password)
42
+
43
+ repo = ghee.repos(repo[:owner], repo[:name])
44
+ if repo["message"]
45
+ puts repo["message"]
46
+ exit
47
+ else
48
+ $STARTER[:github_repo] = repo
49
+ end
50
+
51
+ end
52
+
53
+
54
+ task "github_password" => "github_settings" do
55
+ require "starter/password"
56
+ if $STARTER[:settings][:github][:password] == nil
57
+ password = Starter::Password.request("GitHub")
58
+ $STARTER[:settings][:github][:password] = password
59
+ end
60
+ end
61
+
62
+
63
+ task "read_settings" do
64
+ require "yaml"
65
+ begin
66
+ $STARTER[:settings] = YAML.load_file("settings.yml")
67
+ rescue Errno::ENOENT
68
+ $stderr.puts "You do not appear to have a settings.yml file."
69
+ if Starter::Prompt.confirm("Create a stubbed settings file?")
70
+ File.open("settings.yml", "w") do |f|
71
+ settings = {
72
+ :github => {
73
+ :user => "YOURUSERNAME",
74
+ :repo => {:owner => "OWNERNAME", :name => $STARTER[:directory]}
75
+ }
76
+ }
77
+ YAML.dump(settings, f)
78
+ puts "Created settings.yml. Now go edit it and add it to .gitignore."
79
+ end
80
+ end
81
+ exit
82
+ end
83
+ end
84
+
85
+
86
+ task "github_settings" => "read_settings" do
87
+ if $STARTER[:settings][:github] == nil
88
+ $stderr.puts "Looks like your settings.yml file isn't set up with a github stanza."
89
+ exit
90
+ end
91
+ end
92
+
93
+
@@ -13,7 +13,7 @@ end
13
13
  def readme(options)
14
14
  project_name = options[:project_name]
15
15
  text = <<-TXT
16
- # #{Starter::String.camel_case(project_name)}
16
+ # #{Starter::Extensions::String.camel_case(project_name)}
17
17
 
18
18
  TXT
19
19
  end
@@ -3,13 +3,40 @@
3
3
  task "bootstrap" => %w[ package.json ]
4
4
 
5
5
  file "package.json" => %w[ determine_author ] do |target|
6
- string = package_template(options)
7
6
  File.open(target.name, "w") do |file|
7
+ file.puts package(
8
+ :project_name => $STARTER[:directory],
9
+ :author => $STARTER[:author],
10
+ )
8
11
  end
9
12
  end
10
13
 
11
- def package_template(options={})
14
+
15
+ task "npm:release" => %w[ npm:publish ]
16
+
17
+ task "npm:publish" do
18
+ sh "npm publish"
19
+ end
20
+
21
+
22
+
23
+ def package(options={})
24
+ project_name, author = options.values_at(:project_name, :author)
12
25
  package = <<-TXT
26
+ {
27
+ "name": "#{project_name}",
28
+ "description": "A new project, a nascent bundle of win, whose author hasn't described it yet.",
29
+ "author": "#{author}",
30
+ "version": "0.1.0",
31
+ "main": "./lib/#{project_name}.js",
32
+ "files": [
33
+ "lib"
34
+ ],
35
+ "dependencies": {
36
+ },
37
+ "devDependencies": {
38
+ }
39
+ }
13
40
  TXT
14
41
  end
15
42
 
@@ -1,13 +1,16 @@
1
1
  require "pp"
2
- require "starter/string"
2
+ require "starter/prompt"
3
+ require "starter/extensions/string"
3
4
  require "git"
4
5
 
5
6
  $STARTER ||= {}
6
7
 
7
8
  $STARTER[:directory] = File.basename(Dir.pwd)
8
9
 
10
+ # Interface task declarations
11
+
9
12
  desc "Bootstrap your project"
10
- task "bootstrap"
13
+ task "bootstrap" => "determine_author"
11
14
 
12
15
  desc "Build everything that needs building"
13
16
  task "build"
@@ -15,11 +18,12 @@ task "build"
15
18
  desc "Release the dogs that shoot bees from their mouths"
16
19
  task "release" => %w[ build ]
17
20
 
21
+
18
22
  task "determine_author" => %w[ read_git_config ] do
19
23
  if author = $STARTER[:git].config["user.name"]
20
24
  $STARTER[:author] = author
21
25
  else
22
- $STARTER[:author] = prompt("Project author?")
26
+ $STARTER[:author] = Starter::Prompt.prompt("Project author?")
23
27
  end
24
28
  end
25
29
 
@@ -28,10 +32,9 @@ task "read_git_config" do
28
32
  $STARTER[:git] = g
29
33
  end
30
34
 
35
+
31
36
  def confirm_command(command)
32
- print "Issue command '#{command}' [y/N] "
33
- case STDIN.gets.chomp
34
- when /^y/i
37
+ if Starter::Prompt.confirm("Issue command '#{command}'?")
35
38
  sh command
36
39
  else
37
40
  puts "Cancelled."
@@ -39,14 +42,4 @@ def confirm_command(command)
39
42
  end
40
43
  end
41
44
 
42
- def prompt(string)
43
- print "#{string} "
44
- value = STDIN.gets.chomp
45
- if value.size > 1
46
- return value
47
- else
48
- puts "No, I really need a value. Try again."
49
- prompt(string)
50
- end
51
- end
52
45
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: starter
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-09-08 00:00:00.000000000 Z
12
+ date: 2012-09-14 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description:
15
15
  email:
@@ -20,13 +20,21 @@ files:
20
20
  - LICENSE
21
21
  - Rakefile
22
22
  - README.md
23
- - lib/starter/string.rb
23
+ - lib/starter/extensions/module.rb
24
+ - lib/starter/extensions/string.rb
25
+ - lib/starter/http.rb
26
+ - lib/starter/misc.rb
27
+ - lib/starter/mixins/statistics.rb
28
+ - lib/starter/password.rb
29
+ - lib/starter/prompt.rb
30
+ - lib/starter/random.rb
24
31
  - lib/starter/tasks/bootstrap.rb
25
32
  - lib/starter/tasks/gems.rb
26
33
  - lib/starter/tasks/git.rb
27
- - lib/starter/tasks/helpers.rb
34
+ - lib/starter/tasks/github.rb
28
35
  - lib/starter/tasks/markdown.rb
29
36
  - lib/starter/tasks/npm.rb
37
+ - lib/starter/tasks/starter.rb
30
38
  homepage: https://github.com/automatthew/starter
31
39
  licenses: []
32
40
  post_install_message:
@@ -1,16 +0,0 @@
1
-
2
- module Starter
3
- module String
4
- extend self
5
- def camel_case( string )
6
- string.split('_').map do |word|
7
- "#{word.slice(/^\w/).upcase}#{word.slice(/^\w(\w+)/, 1)}"
8
- end.join
9
- end
10
-
11
- def snake_case( string )
12
- string.gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').gsub(/([a-z\d])([A-Z])/,'\1_\2').downcase
13
- end
14
- end
15
- end
16
-