namelessjon-jeweler 0.6.2 → 0.6.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ # jeweler 0.6.5
2
+
3
+ * `jeweler --create-repo foo` now enables gem creation in addition to creating the repository
4
+
5
+ # jeweler 0.6.4
6
+
7
+ * Added tasks `build` and `install` as shortcuts for `gem:build` and `gem:install`
data/README.markdown CHANGED
@@ -1,39 +1,14 @@
1
- # Jeweler: Let us craft you the perfect gem
1
+ # Jeweler: Craft the perfect RubyGem
2
2
 
3
- Rubygems are the awesome way of distributing your code to others. GitHub is the awesome way of managing the source code of your project. GitHub can even generate a Rubygem if you include a gemspec.
3
+ Jeweler provides two things:
4
4
 
5
- Trouble is when developing your Rubygems on GitHub, you generally do one of the following:
5
+ * Rake tasks for managing gems and versioning of a <a href="http://github.com">GitHub</a> project
6
+ * A generator for creating kickstarting a new project
6
7
 
7
- * Manage the gemspec by hand
8
- * ... why bother doing something by hand when you can automate it?
9
- * Write your own Rake stuff to create the Gem::Specification and output it to a gemspec file, and deal with keeping the Rakefile and gemspec in sync
10
- * ... why keep reinventing the wheel?
11
- * Use hoe or echoe for generating the gemspec
12
- * ... why use utilities made for the days before GitHub existed?
13
- * ... why have extra stuff you aren't going to use?
8
+ ## Setting up in an existing project
14
9
 
15
- Jeweler was created with a few goals in mind:
10
+ It's easy to get up and running. Update your instantiate a `Jeweler::Tasks`, and give it a block with details about your project.
16
11
 
17
- * Only use a Gem::Specification as configuration
18
- * Be one command away from version bumping and releasing
19
- * Store version information in one place
20
- * Only concern itself with git, gems, and versioning
21
- * Not be a requirement for using your Rakefile (you just wouldn't be able to use its tasks)
22
- * Use Jeweler internally. Oh the meta!
23
-
24
- ## Installation
25
-
26
- Run the following if you haven't already:
27
-
28
- gem sources -a http://gems.github.com
29
-
30
- Install the gem:
31
-
32
- sudo gem install technicalpickles-jeweler
33
-
34
- ## Configuration for an existing project
35
-
36
- Armed with the gem, we can begin diving into an example. [the-perfect-gem](http://github.com/technicalpickles/the-perfect-gem/tree) was setup as a Jeweler showcase, and a simple example:
37
12
 
38
13
  begin
39
14
  require 'jeweler'
@@ -49,132 +24,60 @@ Armed with the gem, we can begin diving into an example. [the-perfect-gem](http:
49
24
  puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
50
25
  end
51
26
 
52
- Here's a rundown of what's happening:
53
-
54
- * Wrap everything in a begin block, and rescue from LoadError
55
- * This lets us degrade gracefully if jeweler isn't installed
56
- * Make a new `Jeweler::Tasks`
57
- * It gets yielded a new `Gem::Specification`
58
- * This is where all the configuration happens
59
- * Things you definitely need to specify:
60
- * `name`
61
- * Things you probably want to specify:
62
- * `summary`
63
- * `email`
64
- * `homepage`
65
- * `description`
66
- * `authors`
67
- * Things you can specify, but have defaults
68
- * `files`, defaults to `FileList["[A-Z]*.*", "{bin,generators,lib,test,spec}/**/*"]`
69
- * Things you shouldn't specify:
70
- * `version`, because Jeweler takes care of this for you
71
- * Other things of interest
72
- * `executables`, if you have any scripts
73
- * `add_dependency`, if you have any dependencies
74
- * Keep in mind that this is a `Gem::Specification`, so you can do whatever you would need to do to get your gem in shape
75
-
76
- ## Bootstrap a new project
77
-
78
- Before proceeding, take a minute to setup your git environment, specifically your name, email address, and GitHub username
79
-
80
- $ git config --global user.email johndoe@example.com
81
- $ git config --global user.name 'John Doe'
82
- $ git config --global github.user johndoe
83
- $ git config --global github.token 55555555555555
84
-
85
- Jeweler provides a generator of sorts, `jeweler`. It requires only argument, the name of a repo you want to create. It also takes a few options: --[shoulda](http://github.com/thoughtbot/shoulda) and --[bacon](http://github.com/chneukirchen/bacon/tree/master). These control what type of tests are created, with the default being shoulda.
86
-
87
- $ jeweler --create-repo the-perfect-gem
88
-
89
- Basically, this does:
90
-
91
- * Creates the the-perfect-gem directory
92
- * Seeds it with some basic files:
93
- * `.gitignore`, with the usual suspects predefined
94
- * `Rakefile`, setup with tasks for jeweler, test, rdoc, and rcov
95
- * `README`, with your project name
96
- * `LICENSE`, MIT, with your name prefilled
97
- * `test/test_helper`, setup with shoulda, mocha, and a re-opened `Test::Unit::TestCase`
98
- * `test/the_perfect_gem.rb`, placeholder failing test
99
- * `lib/the_perfect_gem.rb`, placeholder library file
100
- * Makes it a git repo
101
- * Sets up `git@github.com:johndoe/jeweler.git` as the `origin` git remote
102
- * Makes an initial commit
103
- * Sets up a new repository on GitHub and pushes to it (omit --create-repo to skip this)
104
-
105
- You also probably should [enable RubyGem creation for you repository](http://github.com/blog/51-github-s-rubygem-server): Go to your project's edit page and check the 'RubyGem' box.
106
-
107
- ## Overview of Jeweler workflow
108
-
109
- Here's the general idea:
110
-
111
- * Hack, commit, hack, commit, etc, etc
112
- * Version bump
113
- * Release
114
- * Have a delicious scotch
115
-
116
- The hacking and the scotch are up to you, but Jeweler provides rake tasks for the rest.
117
-
118
- ### Versioning
119
-
120
- Versioning information is stored in `VERSION.yml`. It's a plain ol' YAML file which contains three things:
121
-
122
- * major
123
- * minor
124
- * patch
27
+ In this example, `s` is a Gem::Specification object. See the documentation for what possible values you can set on it.
125
28
 
126
- Consider, for a second, `1.5.3`.
29
+ ## Kicking off a new project
127
30
 
128
- * major = 1
129
- * minor = 5
130
- * patch = 3
31
+ Jeweler provides a generator:
131
32
 
132
- #### Your first time
33
+ jeweler the-perfect-gem
133
34
 
134
- When you first start using Jeweler, there won't be a `VERSION.yml`, so it'll assume 0.0.0.
35
+ This will prepare a project in the 'the-perfect-gem' directory, setup to use Jeweler.
135
36
 
136
- If you need some arbitrary version, you can do one of the following:
37
+ It supports a number of options:
137
38
 
138
- * `rake version:write MAJOR=6 MINOR=0 PATCH=3`
139
- * Write `VERSION.yml` by hand (lame)
39
+ * --create-repo: in addition to preparing a project, it create an repo up on GitHub and enable RubyGem generation
40
+ * --shoulda: generate test_helper.rb and empty test ready for shoulda (this is the default)
41
+ * --bacon: generate spec_helper.rb and empty spec ready for bacon
140
42
 
43
+ ## Gemspec
141
44
 
142
- #### After that
45
+ Jeweler handles generating a gemspec file for your project:
143
46
 
144
- You have a few rake tasks for doing the version bump:
47
+ rake gemspec
145
48
 
146
- $ rake version:bump:patch # 1.5.1 -> 1.5.2
147
- $ rake version:bump:minor # 1.5.1 -> 1.6.0
148
- $ rake version:bump:major # 1.5.1 -> 2.0.0
49
+ This creates a gemspec for your project. It's based on the info you give `Jeweler::Tasks`, the current version of your project, and some defaults that Jeweler provides.
149
50
 
150
- If you need to do an arbitrary bump, use the same task you used to create `VERSION.yml`:
51
+ ## Gem
151
52
 
152
- $ rake version:write MAJOR=6 MINOR=0 PATCH=3
53
+ Jeweler gives you tasks for building and installing your gem:
153
54
 
154
- The process of version bumping does a commit to your repo, so make sure your repo is in a clean state (ie nothing uncommitted).
55
+ rake build
56
+ rake install
155
57
 
156
- ### Release it
58
+ ## Versioning
157
59
 
158
- It's pretty straight forward:
60
+ Jeweler tracks the version of your project. It assumes you will be using a version in the format `x.y.z`. `x` is the 'major' version, `y` is the 'minor' version, and `z` is the patch version.
159
61
 
160
- $ rake release
62
+ Initially, your project starts out at 0.0.0. Jeweler provides Rake tasks for bumping the version:
161
63
 
162
- This takes care of:
64
+ rake version:bump:major
65
+ rake version:bump:minor
66
+ rake version:bump:patch
163
67
 
164
- * Generating a `.gemspec` for you project, with the version you just bumped to
165
- * Commit and push the updated `.gemspec`
166
- * Create a tag
167
- * Push the tag
68
+ ## Releasing
168
69
 
169
- ### Play the waiting game
70
+ Jeweler handles releasing your gem into the wild:
170
71
 
171
- How do you know when your gem is built? [Has My Gem Built Yet](http://hasmygembuiltyet.org/) was specifically designed to answer that question.
72
+ rake release
172
73
 
173
- If it happens to be down, you can also check out the GitHub Gem repo's [list](http://gems.github.com/list). Just search for youname-yourrepo.s
74
+ It does the following for you:
174
75
 
175
- ### Putting it all together
76
+ * Regenerate the gemspec to the latest version of your project
77
+ * Push to GitHub (which results in a gem being build)
78
+ * Tag the version and push to GitHub
176
79
 
177
- <hack, hack, hack, commit>
178
- $ rake version:bump:patch release
80
+ ## Links
179
81
 
180
- Now browse to http://gems.github.com/yourname/yourproject, and wait for it to be built.
82
+ * [Bugs](http://technicalpickles.lighthouseapp.com/projects/23560-jeweler/overview)
83
+ * [Donate](http://pledgie.org/campaigns/2604)
data/Rakefile CHANGED
@@ -12,16 +12,16 @@ $:.unshift('lib')
12
12
 
13
13
  begin
14
14
  require 'jeweler'
15
- Jeweler::Tasks.new do |gemspec|
16
- gemspec.name = "jeweler"
17
- gemspec.executables = "jeweler"
18
- gemspec.summary = "Simple and opinionated helper for creating Rubygem projects on GitHub"
19
- gemspec.email = "josh@technicalpickles.com"
20
- gemspec.homepage = "http://github.com/technicalpickles/jeweler"
21
- gemspec.description = "Simple and opinionated helper for creating Rubygem projects on GitHub"
22
- gemspec.authors = ["Josh Nichols"]
23
- gemspec.files = FileList["[A-Z]*", "{bin,generators,lib,test}/**/*", 'lib/jeweler/templates/.gitignore']
24
- gemspec.add_dependency 'schacon-git'
15
+ Jeweler::Tasks.new do |s|
16
+ s.name = "jeweler"
17
+ s.executables = "jeweler"
18
+ s.summary = "Simple and opinionated helper for creating Rubygem projects on GitHub"
19
+ s.email = "josh@technicalpickles.com"
20
+ s.homepage = "http://github.com/technicalpickles/jeweler"
21
+ s.description = "Simple and opinionated helper for creating Rubygem projects on GitHub"
22
+ s.authors = ["Josh Nichols"]
23
+ s.files = FileList["[A-Z]*", "{bin,generators,lib,test}/**/*", 'lib/jeweler/templates/.gitignore']
24
+ s.add_dependency 'schacon-git'
25
25
  end
26
26
  rescue LoadError
27
27
  puts "Jeweler, or one of its dependencies, is not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
data/TODO CHANGED
@@ -1,7 +1,18 @@
1
+ * use some sort of logger instead of stdout and stderr
2
+ * jeweler --delete-repo
3
+ * output gemspec as yaml
4
+ * move interactions with github into separate class
5
+ * use Net::HTTP.post_form instead of `` for enabling gem creation
1
6
  * Generators
2
7
  * Rails generator for making a plugin that's Jeweler enabled
3
8
  * Support rspec?
9
+ * Support test/unit
10
+ * Change generated test filename (test_foo not foo_test)
11
+ * better error handling during generation
12
+ * directory existing
13
+ * no github.token configured
14
+ * no github.username configured
4
15
  * Releasing
5
- * Create tag based on version
6
- * Push tags
7
- * Open hasmygembuiltyet.org
16
+ * Open hasmygembuiltyet.org
17
+ * enable runcoderun by default
18
+ * Add --summary option to generator
data/VERSION.yml CHANGED
@@ -1,4 +1,4 @@
1
1
  ---
2
- patch: 2
3
- major: 0
4
- minor: 6
2
+ :patch: 5
3
+ :major: 0
4
+ :minor: 6
data/lib/jeweler.rb CHANGED
@@ -1,20 +1,15 @@
1
1
  require 'date'
2
+ require 'rubygems/builder'
2
3
 
3
- require 'jeweler/bumping'
4
- require 'jeweler/versioning'
4
+ require 'jeweler/version'
5
5
  require 'jeweler/gemspec'
6
6
  require 'jeweler/errors'
7
7
  require 'jeweler/generator'
8
- require 'jeweler/release'
9
8
 
10
9
  require 'jeweler/tasks'
11
10
 
12
11
  # A Jeweler helps you craft the perfect Rubygem. Give him a gemspec, and he takes care of the rest.
13
12
  class Jeweler
14
- include Jeweler::Bumping
15
- include Jeweler::Versioning
16
- include Jeweler::Gemspec
17
- include Jeweler::Release
18
13
 
19
14
  attr_reader :gemspec
20
15
  attr_accessor :base_dir
@@ -23,12 +18,214 @@ class Jeweler
23
18
  raise(GemspecError, "Can't create a Jeweler with a nil gemspec") if gemspec.nil?
24
19
  @gemspec = gemspec
25
20
  @base_dir = base_dir
21
+
22
+ if @gemspec.files.nil? || @gemspec.files.empty?
23
+ @gemspec.files = FileList["[A-Z]*.*", "{bin,generators,lib,test,spec}/**/*"]
24
+ end
26
25
 
27
- @gemspec.files ||= FileList["[A-Z]*.*", "{bin,generators,lib,test,spec}/**/*"]
26
+ @gemspec.has_rdoc = true
27
+ @gemspec.rdoc_options << '--inline-source' << '--charset=UTF-8'
28
+ @gemspec.extra_rdoc_files ||= FileList["[A-Z]*.*"]
28
29
 
29
30
  if File.exists?(File.join(base_dir, '.git'))
30
31
  @repo = Git.open(base_dir)
31
32
  end
33
+
34
+ @version = Jeweler::Version.new(@base_dir)
35
+ end
36
+
37
+ # Major version, as defined by the gemspec's Version module.
38
+ # For 1.5.3, this would return 1.
39
+ def major_version
40
+ @version.major
41
+ end
42
+
43
+ # Minor version, as defined by the gemspec's Version module.
44
+ # For 1.5.3, this would return 5.
45
+ def minor_version
46
+ @version.minor
47
+ end
48
+
49
+ # Patch version, as defined by the gemspec's Version module.
50
+ # For 1.5.3, this would return 5.
51
+ def patch_version
52
+ @version.patch
53
+ end
54
+
55
+ # Human readable version, which is used in the gemspec.
56
+ def version
57
+ @version.to_s
58
+ end
59
+
60
+ # Writes out the gemspec
61
+ def write_gemspec
62
+ self.refresh_version
63
+
64
+ helper = gemspec_helper do |s|
65
+ s.version = self.version
66
+ s.date = Time.now
67
+ end
68
+
69
+ helper.write
70
+
71
+ puts "Generated: #{helper.path}"
72
+ end
73
+
74
+ # Validates the project's gemspec from disk in an environment similar to how
75
+ # GitHub would build from it. See http://gist.github.com/16215
76
+ def validate_gemspec
77
+ begin
78
+ gemspec_helper.parse
79
+ puts "#{gemspec_path} is valid."
80
+ rescue Exception => e
81
+ puts "#{gemspec_path} is invalid. See the backtrace for more details."
82
+ raise
83
+ end
32
84
  end
85
+
86
+
87
+ # is the project's gemspec from disk valid?
88
+ def valid_gemspec?
89
+ gemspec_helper.valid?
90
+ end
91
+
92
+ # parses the project's gemspec from disk without extra sanity checks
93
+ def unsafe_parse_gemspec(data = nil)
94
+ data ||= File.read(gemspec_path)
95
+ eval(data, binding, gemspec_path)
96
+ end
97
+
98
+ def build_gem
99
+ parsed_gemspec = unsafe_parse_gemspec()
100
+ Gem::Builder.new(parsed_gemspec).build
101
+
102
+ pkg_dir = File.join(@base_dir, 'pkg')
103
+ FileUtils.mkdir_p pkg_dir
104
+
105
+ gem_filename = File.join(@base_dir, parsed_gemspec.file_name)
106
+ FileUtils.mv gem_filename, pkg_dir
107
+ end
108
+
109
+ def install_gem
110
+ command = "sudo gem install #{gem_path}"
111
+ $stdout.puts "Executing #{command.inspect}:"
112
+ sh command
113
+ end
114
+
115
+ # Bumps the patch version.
116
+ #
117
+ # 1.5.1 -> 1.5.2
118
+ def bump_patch_version(options = {})
119
+ options = version_writing_options(options)
120
+
121
+ @version.bump_patch
122
+ @version.write
123
+
124
+ commit_version if options[:commit]
125
+ end
126
+
127
+ # Bumps the minor version.
128
+ #
129
+ # 1.5.1 -> 1.6.0
130
+ def bump_minor_version(options = {})
131
+ options = version_writing_options(options)
132
+
133
+ @version.bump_minor
134
+ @version.write
135
+
136
+ commit_version if options[:commit]
137
+ end
138
+
139
+ # Bumps the major version.
140
+ #
141
+ # 1.5.1 -> 2.0.0
142
+ def bump_major_version(options = {})
143
+ options = version_writing_options(options)
144
+
145
+ @version.bump_major
146
+ @version.write
147
+
148
+ commit_version if options[:commit]
149
+ end
150
+
151
+ # Bumps the version, to the specific major/minor/patch version, writing out the appropriate version.rb, and then reloads it.
152
+ def write_version(major, minor, patch, options = {})
153
+ options = version_writing_options(options)
154
+
155
+ @version.update_to major, minor, patch
156
+ @version.write
157
+
158
+ @gemspec.version = @version.to_s
159
+
160
+ commit_version if options[:commit]
161
+ end
162
+
163
+
164
+ def release
165
+ @repo.checkout('master')
166
+
167
+ raise "Hey buddy, try committing them files first" if any_pending_changes?
168
+
169
+ write_gemspec()
170
+
171
+ @repo.add(gemspec_path)
172
+ $stdout.puts "Committing #{gemspec_path}"
173
+ @repo.commit("Regenerated gemspec for version #{version}")
174
+
175
+ $stdout.puts "Pushing master to origin"
176
+ @repo.push
177
+
178
+ $stdout.puts "Tagging #{release_tag}"
179
+ @repo.add_tag(release_tag)
180
+
181
+ $stdout.puts "Pushing #{release_tag} to origin"
182
+ @repo.push('origin', release_tag)
183
+ end
184
+
185
+ def release_tag
186
+ @release_tag ||= "v#{version}"
187
+ end
188
+
189
+ protected
190
+
191
+ def version_writing_options(options)
192
+ {:commit => true}.merge(options)
193
+ end
194
+
195
+ def commit_version
196
+ if @repo
197
+ @repo.add('VERSION.yml')
198
+ @repo.commit("Version bump to #{version}", 'VERSION.yml')
199
+ end
200
+ end
201
+
202
+ def refresh_version
203
+ @version.refresh
204
+ end
205
+
206
+ def gemspec_helper(&block)
207
+ GemSpecHelper.new(@gemspec, @base_dir, &block)
208
+ end
209
+
210
+ def gemspec_path
211
+ gemspec_helper.path
212
+ end
213
+
214
+ def gem_path
215
+ parsed_gemspec = unsafe_parse_gemspec()
216
+ File.join(@base_dir, 'pkg', parsed_gemspec.file_name)
217
+ end
218
+
219
+ def any_pending_changes?
220
+ unless ENV['JEWELER_DEBUG'].nil? || ENV['JEWELER_DEBUG'].squeeze == ''
221
+ require 'ruby-debug'; breakpoint
222
+ end
223
+ !(@repo.status.added.empty? && @repo.status.deleted.empty? && @repo.status.changed.empty?)
224
+ end
225
+
226
+ protected
227
+ def any_pending_changes?
228
+ !(@repo.status.added.empty? && @repo.status.deleted.empty? && @repo.status.changed.empty?)
229
+ end
33
230
  end
34
231