rake-deveiate 0.1.0
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.
- checksums.yaml +7 -0
- checksums.yaml.gz.sig +0 -0
- data/History.md +7 -0
- data/README.md +84 -0
- data/data/rake-deveiate/History.erb +5 -0
- data/data/rake-deveiate/README.erb +64 -0
- data/lib/rake/deveiate/checks.rb +200 -0
- data/lib/rake/deveiate/docs.rb +34 -0
- data/lib/rake/deveiate/gem_dep_finder.rb +97 -0
- data/lib/rake/deveiate/gemspec.rb +177 -0
- data/lib/rake/deveiate/generate.rb +103 -0
- data/lib/rake/deveiate/hg.rb +542 -0
- data/lib/rake/deveiate/packaging.rb +42 -0
- data/lib/rake/deveiate/releases.rb +40 -0
- data/lib/rake/deveiate/specs.rb +30 -0
- data/lib/rake/deveiate.rb +675 -0
- data.tar.gz.sig +0 -0
- metadata +213 -0
- metadata.gz.sig +0 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 53275d426cc35203e19ffb6354a49628d385b4b457b312863f98de52c1c205ae
|
4
|
+
data.tar.gz: 9cc9b5659a6612aef89b69d153777ac1f2c29fb9ad8504c4e80d66dfc295243a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 305c88f5e61673c7b898ac213daff8bb6013b0a9ea243c4eb46b175ea59f44e2913d0b632782a38f1f211a6afe9ac0dc640febfb3915564916c7dd22a99cebc2
|
7
|
+
data.tar.gz: 063f316622af921ba648aaf65ebf65efd486f71c17fedae4baab90e95c2a82eb6c407350984711c8d7b8084bc6ae6742d9d6ddd5de3e6e6b0a35903010405a85
|
checksums.yaml.gz.sig
ADDED
Binary file
|
data/History.md
ADDED
data/README.md
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
# Rake Tasks for DevEiate Libraries
|
2
|
+
|
3
|
+
home
|
4
|
+
: https://hg.sr.ht/~ged/rake-deveiate
|
5
|
+
|
6
|
+
github
|
7
|
+
: https://github.com/ged/rake-deveiate
|
8
|
+
|
9
|
+
docs
|
10
|
+
: https://deveiate.org/code/rake-deveiate/
|
11
|
+
|
12
|
+
|
13
|
+
## Description
|
14
|
+
|
15
|
+
This is a collection of Rake tasks I use for development. I distribute them as
|
16
|
+
a gem mostly so people who wish to contribute to the other Open Source
|
17
|
+
libraries I maintain can do so easily, but of course you're welcome to use them
|
18
|
+
yourself if you find them useful.
|
19
|
+
|
20
|
+
|
21
|
+
## Prerequisites
|
22
|
+
|
23
|
+
* Ruby 2.6+
|
24
|
+
|
25
|
+
|
26
|
+
## Installation
|
27
|
+
|
28
|
+
$ gem install rake-deveiate
|
29
|
+
|
30
|
+
|
31
|
+
## Usage
|
32
|
+
|
33
|
+
Make a Rakefile with the following content:
|
34
|
+
|
35
|
+
require 'rake/deveiate'
|
36
|
+
|
37
|
+
Rake::DevEiate.setup( 'gemname' )
|
38
|
+
|
39
|
+
You can also pass a block to customize the project settings:
|
40
|
+
|
41
|
+
Rake::DevEiate.setup( 'gemname' ) do |project|
|
42
|
+
project.description = <<~END_DESC
|
43
|
+
This is a gem that does some stuff. It does a few things well, a lot of
|
44
|
+
things sufficiently, and nothing badly.
|
45
|
+
END_DESC
|
46
|
+
project.authors = [ 'J. Random Hacker <jrandom@example.com>' ]
|
47
|
+
end
|
48
|
+
|
49
|
+
|
50
|
+
|
51
|
+
## Authors
|
52
|
+
|
53
|
+
- Michael Granger <ged@FaerieMUD.org>
|
54
|
+
|
55
|
+
|
56
|
+
## License
|
57
|
+
|
58
|
+
Copyright (c) 2019, Michael Granger
|
59
|
+
All rights reserved.
|
60
|
+
|
61
|
+
Redistribution and use in source and binary forms, with or without
|
62
|
+
modification, are permitted provided that the following conditions are met:
|
63
|
+
|
64
|
+
* Redistributions of source code must retain the above copyright notice,
|
65
|
+
this list of conditions and the following disclaimer.
|
66
|
+
|
67
|
+
* Redistributions in binary form must reproduce the above copyright notice,
|
68
|
+
this list of conditions and the following disclaimer in the documentation
|
69
|
+
and/or other materials provided with the distribution.
|
70
|
+
|
71
|
+
* Neither the name of the author/s, nor the names of the project's
|
72
|
+
contributors may be used to endorse or promote products derived from this
|
73
|
+
software without specific prior written permission.
|
74
|
+
|
75
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
76
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
77
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
78
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
79
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
80
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
81
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
82
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
83
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
84
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
@@ -0,0 +1,64 @@
|
|
1
|
+
<%= header_char %> <%= project.name.gsub(/\b([a-z])/) {|m| m.upcase } %>
|
2
|
+
|
3
|
+
home
|
4
|
+
: https://hg.sr.ht/~ged/<%= project.name %>
|
5
|
+
|
6
|
+
github
|
7
|
+
: https://github.com/ged/<%= project.name %>
|
8
|
+
|
9
|
+
docs
|
10
|
+
: https://deveiate.org/code/<%= project.name %>
|
11
|
+
|
12
|
+
|
13
|
+
<%= header_char * 2 %> Description
|
14
|
+
|
15
|
+
A gem of some sort.
|
16
|
+
|
17
|
+
|
18
|
+
<%= header_char * 2 %> Prerequisites
|
19
|
+
|
20
|
+
* Ruby <%= RUBY_VERSION.sub(/\.\d+$/, '') %>
|
21
|
+
|
22
|
+
|
23
|
+
<%= header_char * 2 %> Installation
|
24
|
+
|
25
|
+
$ gem install <%= project.name %>
|
26
|
+
|
27
|
+
|
28
|
+
<%= header_char * 2 %> Authors
|
29
|
+
|
30
|
+
<% project.authors.each do |author| -%>
|
31
|
+
- <%= author %>
|
32
|
+
<% end -%>
|
33
|
+
|
34
|
+
|
35
|
+
<%= header_char * 2 %> License
|
36
|
+
|
37
|
+
Copyright (c) <%= Date.today.year %>, <%= project.author_names.join(' and ') %>
|
38
|
+
All rights reserved.
|
39
|
+
|
40
|
+
Redistribution and use in source and binary forms, with or without
|
41
|
+
modification, are permitted provided that the following conditions are met:
|
42
|
+
|
43
|
+
* Redistributions of source code must retain the above copyright notice,
|
44
|
+
this list of conditions and the following disclaimer.
|
45
|
+
|
46
|
+
* Redistributions in binary form must reproduce the above copyright notice,
|
47
|
+
this list of conditions and the following disclaimer in the documentation
|
48
|
+
and/or other materials provided with the distribution.
|
49
|
+
|
50
|
+
* Neither the name of the author/s, nor the names of the project's
|
51
|
+
contributors may be used to endorse or promote products derived from this
|
52
|
+
software without specific prior written permission.
|
53
|
+
|
54
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
55
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
56
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
57
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
58
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
59
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
60
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
61
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
62
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
63
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
64
|
+
|
@@ -0,0 +1,200 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'rake'
|
5
|
+
|
6
|
+
require 'rake/deveiate' unless defined?( Rake::DevEiate )
|
7
|
+
|
8
|
+
|
9
|
+
# Sanity and quality check tasks
|
10
|
+
module Rake::DevEiate::Checks
|
11
|
+
extend Rake::DSL
|
12
|
+
|
13
|
+
# Emoji for style advisories
|
14
|
+
SADFACE = "\u{1f622}"
|
15
|
+
|
16
|
+
# Tab-arrow character
|
17
|
+
TAB_ARROW = "\u{21e5}"
|
18
|
+
|
19
|
+
# Regexp to match trailing whitespace
|
20
|
+
TRAILING_WHITESPACE_RE = /\p{Blank}+$/m
|
21
|
+
|
22
|
+
# Regexp to match lines with mixed indentation
|
23
|
+
MIXED_INDENT_RE = /(?<!#)([ ]\t)/
|
24
|
+
|
25
|
+
|
26
|
+
### Set up task defaults
|
27
|
+
def setup( _name, **options )
|
28
|
+
super if defined?( super )
|
29
|
+
|
30
|
+
@quality_check_whitelist = Rake::FileList.new
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
##
|
35
|
+
# The Rake::FileList containing files which should not be quality-checked.
|
36
|
+
attr_reader :quality_check_whitelist
|
37
|
+
|
38
|
+
|
39
|
+
### Define check tasks
|
40
|
+
def define_tasks
|
41
|
+
super if defined?( super )
|
42
|
+
|
43
|
+
self.define_quality_checker_tasks
|
44
|
+
self.define_sanity_checker_tasks
|
45
|
+
|
46
|
+
desc "Run several quality-checks on the code"
|
47
|
+
task :quality_checks => [ 'quality_checks:all' ]
|
48
|
+
|
49
|
+
desc "Run several sanity-checks on the code"
|
50
|
+
task :sanity_checks => [ 'sanity_checks:all' ]
|
51
|
+
|
52
|
+
task :check => [ :quality_checks, :sanity_checks ]
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
|
57
|
+
### Set up tasks that check for poor whitespace discipline
|
58
|
+
def define_quality_checker_tasks
|
59
|
+
|
60
|
+
namespace :quality_checks do
|
61
|
+
|
62
|
+
task :all => [ :whitespace ]
|
63
|
+
|
64
|
+
desc "Check source code for inconsistent whitespace"
|
65
|
+
task :whitespace => [
|
66
|
+
:for_trailing_whitespace,
|
67
|
+
:for_mixed_indentation,
|
68
|
+
]
|
69
|
+
|
70
|
+
desc "Check source code for trailing whitespace"
|
71
|
+
task :for_trailing_whitespace do
|
72
|
+
lines = find_matching_source_lines do |line, _|
|
73
|
+
line =~ TRAILING_WHITESPACE_RE
|
74
|
+
end
|
75
|
+
|
76
|
+
unless lines.empty?
|
77
|
+
desc = "Found some trailing whitespace"
|
78
|
+
describe_lines_that_need_fixing( desc, lines, TRAILING_WHITESPACE_RE )
|
79
|
+
fail
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
desc "Check source code for mixed indentation"
|
84
|
+
task :for_mixed_indentation do
|
85
|
+
lines = find_matching_source_lines do |line, _|
|
86
|
+
line =~ MIXED_INDENT_RE
|
87
|
+
end
|
88
|
+
|
89
|
+
unless lines.empty?
|
90
|
+
desc = "Found mixed indentation"
|
91
|
+
describe_lines_that_need_fixing( desc, lines, /[ ]\t/ )
|
92
|
+
fail
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
99
|
+
|
100
|
+
|
101
|
+
### Set up some sanity-checks as dependencies of higher-level tasks
|
102
|
+
def define_sanity_checker_tasks
|
103
|
+
|
104
|
+
namespace :sanity_checks do
|
105
|
+
|
106
|
+
desc "Check source code for common problems"
|
107
|
+
task :all
|
108
|
+
|
109
|
+
end
|
110
|
+
|
111
|
+
end
|
112
|
+
|
113
|
+
|
114
|
+
# Return tuples of the form:
|
115
|
+
#
|
116
|
+
# [ <filename>, <line number>, <line> ]
|
117
|
+
#
|
118
|
+
# for every line in the Gemspec's source files for which the block
|
119
|
+
# returns true.
|
120
|
+
def find_matching_source_lines
|
121
|
+
matches = []
|
122
|
+
|
123
|
+
source_files = self.project_files.grep( /\.(h|c|rb)$/ )
|
124
|
+
source_files -= self.quality_check_whitelist
|
125
|
+
|
126
|
+
source_files.each do |filename|
|
127
|
+
previous_line = nil
|
128
|
+
|
129
|
+
IO.foreach( filename ).with_index do |line, i|
|
130
|
+
matches << [filename, i + 1, line] if yield( line, previous_line )
|
131
|
+
previous_line = line
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
return matches
|
136
|
+
end
|
137
|
+
|
138
|
+
|
139
|
+
### Output a listing of the specified lines with the given +description+, highlighting
|
140
|
+
### the characters matched by the specified +re+.
|
141
|
+
def describe_lines_that_need_fixing( description, lines, re )
|
142
|
+
self.prompt.say "\n"
|
143
|
+
self.prompt.say SADFACE + " "
|
144
|
+
self.prompt.error( "Uh-oh! " + description )
|
145
|
+
|
146
|
+
grouped_lines = group_line_matches( lines )
|
147
|
+
|
148
|
+
grouped_lines.each do |filename, linegroups|
|
149
|
+
linegroups.each do |group, lines|
|
150
|
+
if group.min == group.max
|
151
|
+
self.prompt.say( "%s:%d" % [ filename, group.min ], color: :bold )
|
152
|
+
else
|
153
|
+
self.prompt.say( "%s:%d-%d" % [ filename, group.min, group.max ], color: :bold )
|
154
|
+
end
|
155
|
+
|
156
|
+
lines.each_with_index do |line, i|
|
157
|
+
self.prompt.say "%s: %s" % [
|
158
|
+
self.pastel.dark.white( group.to_a[i].to_s ),
|
159
|
+
highlight_problems( line, re )
|
160
|
+
]
|
161
|
+
end
|
162
|
+
self.prompt.say "\n"
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
|
168
|
+
# Return a Hash, keyed by filename, whose values are tuples of Ranges
|
169
|
+
# and lines extracted from the given [filename, linenumber, line] +tuples+.
|
170
|
+
def group_line_matches( tuples )
|
171
|
+
by_file = tuples.group_by {|tuple| tuple.first }
|
172
|
+
|
173
|
+
return by_file.each_with_object({}) do |(filename, lines), hash|
|
174
|
+
last_linenum = 0
|
175
|
+
linegroups = lines.slice_before do |filename, linenum|
|
176
|
+
gap = linenum > last_linenum + 1
|
177
|
+
last_linenum = linenum
|
178
|
+
gap
|
179
|
+
end
|
180
|
+
|
181
|
+
hash[ filename ] = linegroups.map do |group|
|
182
|
+
rng = group.first[1] .. group.last[1]
|
183
|
+
grouplines = group.transpose.last
|
184
|
+
[ rng, grouplines ]
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
|
190
|
+
### Transform invisibles in the specified line into visible analogues.
|
191
|
+
def highlight_problems( line, re )
|
192
|
+
line.
|
193
|
+
gsub( re ) { self.pastel.on_red( $& ) }.
|
194
|
+
gsub( /\t+/ ) { self.pastel.dark.white( "#{TAB_ARROW} " * $&.length ) }
|
195
|
+
end
|
196
|
+
|
197
|
+
|
198
|
+
end # module Rake::DevEiate::Docs
|
199
|
+
|
200
|
+
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'rake'
|
5
|
+
require 'rake/phony'
|
6
|
+
require 'rdoc/task'
|
7
|
+
|
8
|
+
require 'rake/deveiate' unless defined?( Rake::DevEiate )
|
9
|
+
|
10
|
+
|
11
|
+
# Documentation-generation tasks
|
12
|
+
module Rake::DevEiate::Docs
|
13
|
+
extend Rake::DSL
|
14
|
+
|
15
|
+
|
16
|
+
### Define documentation tasks
|
17
|
+
def define_tasks
|
18
|
+
super if defined?( super )
|
19
|
+
|
20
|
+
task :docs => :phony
|
21
|
+
|
22
|
+
RDoc::Task.new( 'docs' ) do |rdoc|
|
23
|
+
rdoc.main = self.readme_file.to_s
|
24
|
+
rdoc.rdoc_files = self.rdoc_files
|
25
|
+
rdoc.generator = :fivefish
|
26
|
+
rdoc.title = self.title
|
27
|
+
rdoc.rdoc_dir = Rake::DevEiate::DOCS_DIR.to_s
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
end # module Rake::DevEiate::Docs
|
33
|
+
|
34
|
+
|
@@ -0,0 +1,97 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'set'
|
5
|
+
require 'rubygems'
|
6
|
+
require 'rake/deveiate' unless defined?( Rake::DevEiate )
|
7
|
+
|
8
|
+
|
9
|
+
# A dependency finder that groks the GemDependencyApi
|
10
|
+
class Rake::DevEiate::GemDepFinder
|
11
|
+
|
12
|
+
### Create a new GemDepFinder that will find dependencies in the given
|
13
|
+
### +depfile+.
|
14
|
+
def initialize( depfile )
|
15
|
+
@depfile = Pathname( depfile )
|
16
|
+
@dependencies = Set.new
|
17
|
+
@current_groups = Set.new
|
18
|
+
end
|
19
|
+
|
20
|
+
|
21
|
+
|
22
|
+
######
|
23
|
+
public
|
24
|
+
######
|
25
|
+
|
26
|
+
##
|
27
|
+
# The Pathname of the file to find dependencies in
|
28
|
+
attr_reader :depfile
|
29
|
+
|
30
|
+
##
|
31
|
+
# The Set of Gem::Dependency objects that describe the loaded dependencies
|
32
|
+
attr_reader :dependencies
|
33
|
+
|
34
|
+
##
|
35
|
+
# The current set of groups to add to any declared gems
|
36
|
+
attr_reader :current_groups
|
37
|
+
|
38
|
+
|
39
|
+
### Load the dependencies file.
|
40
|
+
def load
|
41
|
+
source = self.depfile.read
|
42
|
+
self.instance_eval( source, self.depfile.to_s, 1 )
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
#
|
47
|
+
# Gem Dependency API methods
|
48
|
+
#
|
49
|
+
|
50
|
+
|
51
|
+
### Declare a dependency on a gem. Ignores every option except :group.
|
52
|
+
def gem( name, *requirements, **options )
|
53
|
+
if options[:group] == :development ||
|
54
|
+
options[:groups]&.include?( :development ) ||
|
55
|
+
self.current_groups.include?( :development )
|
56
|
+
|
57
|
+
requirements.push( :development )
|
58
|
+
end
|
59
|
+
|
60
|
+
dependency = Gem::Dependency.new( name, *requirements )
|
61
|
+
|
62
|
+
self.dependencies.add( dependency )
|
63
|
+
end
|
64
|
+
|
65
|
+
|
66
|
+
### Declare a group block.
|
67
|
+
def group( *names )
|
68
|
+
options = names.pop if names.last.is_a?( Hash )
|
69
|
+
previous_groups = self.current_groups.dup
|
70
|
+
self.current_groups.replace( names )
|
71
|
+
|
72
|
+
yield
|
73
|
+
ensure
|
74
|
+
self.current_groups.replace( previous_groups ) if previous_groups
|
75
|
+
end
|
76
|
+
|
77
|
+
|
78
|
+
### Raise, as the gemdeps file should be the authoritative source.
|
79
|
+
def gemspec( * )
|
80
|
+
raise "Circular dependency: can't depend on the gemspec to build itself"
|
81
|
+
end
|
82
|
+
|
83
|
+
|
84
|
+
### Ignore a gem dependency API call.
|
85
|
+
def no_op_method( * ) # :nodoc:
|
86
|
+
yield if block_given?
|
87
|
+
end
|
88
|
+
|
89
|
+
alias_method :source, :no_op_method
|
90
|
+
alias_method :git, :no_op_method
|
91
|
+
alias_method :platform, :no_op_method
|
92
|
+
alias_method :platforms, :no_op_method
|
93
|
+
alias_method :ruby, :no_op_method
|
94
|
+
|
95
|
+
|
96
|
+
end # class Rake::DevEiate::GemDepFinder
|
97
|
+
|
@@ -0,0 +1,177 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'etc'
|
5
|
+
require 'rubygems'
|
6
|
+
require 'rake'
|
7
|
+
require 'rake/clean'
|
8
|
+
require 'rake/deveiate' unless defined?( Rake::DevEiate )
|
9
|
+
|
10
|
+
|
11
|
+
# Gemspec-generation tasks
|
12
|
+
module Rake::DevEiate::Gemspec
|
13
|
+
extend Rake::DSL
|
14
|
+
|
15
|
+
# Pattern for splitting parsed authors list items into name and email
|
16
|
+
AUTHOR_PATTERN = /^(?<name>.*)\s<(?<email>.*)>$/
|
17
|
+
|
18
|
+
|
19
|
+
##
|
20
|
+
# The path to the file used to sign released gems
|
21
|
+
attr_accessor :signing_key
|
22
|
+
|
23
|
+
|
24
|
+
### Set some defaults when the task lib is set up.
|
25
|
+
def setup( _name, **options )
|
26
|
+
super if defined?( super )
|
27
|
+
|
28
|
+
@signing_key = options[:signing_key] || Gem.default_key_path
|
29
|
+
|
30
|
+
@gemspec = nil
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
### Reset any cached data when project attributes change.
|
35
|
+
def reset
|
36
|
+
super if defined?( super )
|
37
|
+
@gemspec = nil
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
### Define gemspec tasks
|
42
|
+
def define_tasks
|
43
|
+
super if defined?( super )
|
44
|
+
|
45
|
+
gemspec_file = "#{self.name}.gemspec"
|
46
|
+
|
47
|
+
if self.has_manifest?
|
48
|
+
file( self.manifest_file )
|
49
|
+
file( gemspec_file => self.manifest_file )
|
50
|
+
else
|
51
|
+
file( gemspec_file )
|
52
|
+
end
|
53
|
+
|
54
|
+
task( gemspec_file ) do |task|
|
55
|
+
self.prompt.say "Updating gemspec"
|
56
|
+
|
57
|
+
spec = self.make_prerelease_gemspec
|
58
|
+
|
59
|
+
File.open( task.name, 'w' ) do |fh|
|
60
|
+
fh.write( spec.to_ruby )
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
desc "(Re)Generate the gemspec file"
|
65
|
+
task :gemspec => gemspec_file
|
66
|
+
|
67
|
+
CLEAN.include( gemspec_file.to_s )
|
68
|
+
|
69
|
+
task :checkin => :gemspec
|
70
|
+
|
71
|
+
task( :gemspec_debug, &method(:do_gemspec_debug) )
|
72
|
+
task :debug => :gemspec_debug
|
73
|
+
end
|
74
|
+
|
75
|
+
|
76
|
+
### Task function -- output debugging for gemspec tasks.
|
77
|
+
def do_gemspec_debug( task, args )
|
78
|
+
gemspec = self.gemspec
|
79
|
+
gemspec_src = gemspec.to_yaml
|
80
|
+
|
81
|
+
self.prompt.say( "Gemspec:", color: :bright_green )
|
82
|
+
self.prompt.say( indent(gemspec_src, 4) )
|
83
|
+
self.prompt.say( "\n" )
|
84
|
+
end
|
85
|
+
|
86
|
+
|
87
|
+
### Return the project's Gem::Specification, creating it if necessary.
|
88
|
+
def gemspec
|
89
|
+
return @gemspec ||= self.make_gemspec
|
90
|
+
end
|
91
|
+
|
92
|
+
|
93
|
+
### Validate the gemspec, raising a Gem::InvalidSpecificationException if it's
|
94
|
+
### not valid.
|
95
|
+
def validate_gemspec( packaging=true, strict=false )
|
96
|
+
return self.gemspec.validate( packaging, strict )
|
97
|
+
end
|
98
|
+
|
99
|
+
|
100
|
+
### Return a Gem::Specification created from the project's metadata.
|
101
|
+
def make_gemspec
|
102
|
+
spec = Gem::Specification.new
|
103
|
+
|
104
|
+
spec.name = self.name
|
105
|
+
spec.description = self.description
|
106
|
+
spec.homepage = self.homepage
|
107
|
+
spec.summary = self.summary || self.extract_summary
|
108
|
+
spec.files = self.project_files
|
109
|
+
spec.signing_key = self.resolve_signing_key.to_s
|
110
|
+
spec.cert_chain = self.cert_files.map( &File.method(:expand_path) ).to_a
|
111
|
+
spec.version = self.version
|
112
|
+
spec.licenses = self.licenses
|
113
|
+
spec.date = Date.today
|
114
|
+
|
115
|
+
self.authors.each do |author|
|
116
|
+
if ( m = author.match(AUTHOR_PATTERN) )
|
117
|
+
spec.authors ||= []
|
118
|
+
spec.authors << m[:name]
|
119
|
+
spec.email ||= []
|
120
|
+
spec.email << m[:email] if m[:email]
|
121
|
+
else
|
122
|
+
self.prompt.warn "Couldn't extract author name + email from %p" % [ author ]
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
self.dependencies.each do |dep|
|
127
|
+
if dep.runtime?
|
128
|
+
spec.add_runtime_dependency( dep )
|
129
|
+
else
|
130
|
+
spec.add_development_dependency( dep )
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
return spec
|
135
|
+
end
|
136
|
+
|
137
|
+
|
138
|
+
### Return a Gem::Specification with its properties modified to be suitable for
|
139
|
+
### a pre-release gem.
|
140
|
+
def make_prerelease_gemspec
|
141
|
+
spec = self.make_gemspec
|
142
|
+
|
143
|
+
spec.version = self.prerelease_version
|
144
|
+
spec.signing_key = nil
|
145
|
+
spec.cert_chain = []
|
146
|
+
|
147
|
+
return spec
|
148
|
+
end
|
149
|
+
|
150
|
+
|
151
|
+
### Return a version string
|
152
|
+
def prerelease_version
|
153
|
+
return "#{self.version.bump}.0.pre.#{Time.now.strftime("%Y%m%d%H%M%S")}"
|
154
|
+
end
|
155
|
+
|
156
|
+
|
157
|
+
### Resolve the path of the signing key
|
158
|
+
def resolve_signing_key
|
159
|
+
path = Pathname( self.signing_key ).expand_path
|
160
|
+
path = path.readlink if path.symlink?
|
161
|
+
return path
|
162
|
+
end
|
163
|
+
|
164
|
+
|
165
|
+
#######
|
166
|
+
private
|
167
|
+
#######
|
168
|
+
|
169
|
+
### Return a copy of the given text prefixed by +spaces+ number of spaces.
|
170
|
+
def indent( text, spaces=4 )
|
171
|
+
prefix = ' ' * spaces
|
172
|
+
return text.gsub( /(?<=\A|\n)/m, prefix )
|
173
|
+
end
|
174
|
+
|
175
|
+
end # module Rake::DevEiate::Gemspec
|
176
|
+
|
177
|
+
|