rake-deveiate 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
|