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
@@ -0,0 +1,675 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'pathname'
|
5
|
+
require 'etc'
|
6
|
+
|
7
|
+
begin
|
8
|
+
gem 'rdoc'
|
9
|
+
rescue Gem::LoadError
|
10
|
+
end unless defined?(RDoc)
|
11
|
+
|
12
|
+
begin
|
13
|
+
gem 'rake'
|
14
|
+
rescue Gem::LoadError
|
15
|
+
end unless defined?(Rake)
|
16
|
+
|
17
|
+
|
18
|
+
require 'rake'
|
19
|
+
require 'rake/tasklib'
|
20
|
+
require 'rake/clean'
|
21
|
+
require 'rdoc'
|
22
|
+
require 'rdoc/markdown'
|
23
|
+
require 'tty/prompt'
|
24
|
+
require 'tty/table'
|
25
|
+
require 'pastel'
|
26
|
+
require 'rubygems/request_set'
|
27
|
+
|
28
|
+
|
29
|
+
# A task library for maintaining an open-source library.
|
30
|
+
class Rake::DevEiate < Rake::TaskLib
|
31
|
+
include Rake::TraceOutput
|
32
|
+
|
33
|
+
# Pattern for extracting a version constant
|
34
|
+
VERSION_PATTERN = /VERSION\s*=\s*(?<quote>['"])(?<version>\d+(\.\d+){2}.*)\k<quote>/
|
35
|
+
|
36
|
+
# The version of this library
|
37
|
+
VERSION = '0.1.0'
|
38
|
+
|
39
|
+
# The server to release to by default
|
40
|
+
DEFAULT_GEMSERVER = 'https://rubygems.org/'
|
41
|
+
|
42
|
+
# The description to use if none is set
|
43
|
+
DEFAULT_DESCRIPTION = "A gem of some sort."
|
44
|
+
|
45
|
+
# The version to use if one cannot be read from the source
|
46
|
+
DEFAULT_VERSION = '0.1.0'
|
47
|
+
|
48
|
+
# Paths
|
49
|
+
PROJECT_DIR = Pathname( '.' )
|
50
|
+
|
51
|
+
DOCS_DIR = PROJECT_DIR + 'docs'
|
52
|
+
LIB_DIR = PROJECT_DIR + 'lib'
|
53
|
+
EXT_DIR = PROJECT_DIR + 'ext'
|
54
|
+
SPEC_DIR = PROJECT_DIR + 'spec'
|
55
|
+
DATA_DIR = PROJECT_DIR + 'data'
|
56
|
+
CERTS_DIR = PROJECT_DIR + 'certs'
|
57
|
+
PKG_DIR = PROJECT_DIR + 'pkg'
|
58
|
+
CHECKSUM_DIR = PROJECT_DIR + 'checksum'
|
59
|
+
|
60
|
+
DEFAULT_MANIFEST_FILE = PROJECT_DIR + 'Manifest.txt'
|
61
|
+
DEFAULT_README_FILE = PROJECT_DIR + 'README.md'
|
62
|
+
DEFAULT_HISTORY_FILE = PROJECT_DIR + 'History.md'
|
63
|
+
DEFAULT_PROJECT_FILES = Rake::FileList[
|
64
|
+
'*.{rdoc,md,txt}',
|
65
|
+
'bin/*',
|
66
|
+
'lib/*.rb', 'lib/**/*.rb',
|
67
|
+
'ext/*.[ch]', 'ext/**/*.[ch]',
|
68
|
+
'data/**/*'
|
69
|
+
]
|
70
|
+
|
71
|
+
# The default license for the project in SPDX form: https://spdx.org/licenses
|
72
|
+
DEFAULT_LICENSE = 'BSD-3-Clause'
|
73
|
+
|
74
|
+
# The file that contains the project's dependencies
|
75
|
+
GEMDEPS_FILE = PROJECT_DIR + 'gem.deps.rb'
|
76
|
+
|
77
|
+
# The file suffixes to include in documentation
|
78
|
+
DOCUMENTATION_SUFFIXES = %w[
|
79
|
+
.rb
|
80
|
+
.c
|
81
|
+
.h
|
82
|
+
.md
|
83
|
+
.rdoc
|
84
|
+
.txt
|
85
|
+
]
|
86
|
+
|
87
|
+
# The path to the data directory for the Prestigio library.
|
88
|
+
DEVEIATE_DATADIR = if ENV['DEVEIATE_DATADIR']
|
89
|
+
Pathname( ENV['DEVEIATE_DATADIR'] )
|
90
|
+
elsif Gem.loaded_specs['rake-deveiate'] &&
|
91
|
+
File.directory?( Gem.loaded_specs['rake-deveiate'].datadir )
|
92
|
+
Pathname( Gem.loaded_specs['rake-deveiate'].datadir )
|
93
|
+
else
|
94
|
+
Pathname( __FILE__ ).dirname.parent.parent + 'data/rake-deveiate'
|
95
|
+
end
|
96
|
+
|
97
|
+
|
98
|
+
# Autoload utility classes
|
99
|
+
autoload :GemDepFinder, 'rake/deveiate/gem_dep_finder'
|
100
|
+
|
101
|
+
|
102
|
+
### Declare an attribute that should be cast to a Pathname when set.
|
103
|
+
def self::attr_pathname( name ) # :nodoc:
|
104
|
+
attr_reader( name )
|
105
|
+
define_method( "#{name}=" ) do |new_value|
|
106
|
+
instance_variable_set( "@#{name}", Pathname(new_value) )
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
|
111
|
+
### Set up common development tasks
|
112
|
+
def self::setup( name, **options, &block )
|
113
|
+
tasklib = self.new( name, **options, &block )
|
114
|
+
tasklib.define_tasks
|
115
|
+
return tasklib
|
116
|
+
end
|
117
|
+
|
118
|
+
|
119
|
+
|
120
|
+
### Create the devEiate tasks for a gem with the given +name+.
|
121
|
+
def initialize( name, **options, &block )
|
122
|
+
@name = validate_gemname( name )
|
123
|
+
@options = options
|
124
|
+
|
125
|
+
@manifest_file = DEFAULT_MANIFEST_FILE.dup
|
126
|
+
@project_files = self.read_manifest
|
127
|
+
@version = self.find_version || DEFAULT_VERSION
|
128
|
+
@readme_file = self.find_readme
|
129
|
+
@history_file = self.find_history_file
|
130
|
+
@readme = self.parse_readme
|
131
|
+
@rdoc_files = self.make_rdoc_filelist
|
132
|
+
@cert_files = Rake::FileList[ CERTS_DIR + '*.pem' ]
|
133
|
+
@licenses = [ DEFAULT_LICENSE ]
|
134
|
+
|
135
|
+
@docs_dir = DOCS_DIR.dup
|
136
|
+
|
137
|
+
@title = self.extract_default_title
|
138
|
+
@authors = self.extract_authors
|
139
|
+
@homepage = self.extract_homepage
|
140
|
+
@description = self.extract_description || DEFAULT_DESCRIPTION
|
141
|
+
@summary = nil
|
142
|
+
@dependencies = self.find_dependencies
|
143
|
+
|
144
|
+
@gemserver = DEFAULT_GEMSERVER
|
145
|
+
|
146
|
+
super()
|
147
|
+
|
148
|
+
self.load_task_libraries
|
149
|
+
|
150
|
+
if block
|
151
|
+
if block.arity.nonzero?
|
152
|
+
block.call( self )
|
153
|
+
else
|
154
|
+
self.instance_exec( self, &block )
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
|
160
|
+
######
|
161
|
+
public
|
162
|
+
######
|
163
|
+
|
164
|
+
##
|
165
|
+
# The name of the gem the task will build
|
166
|
+
attr_reader :name
|
167
|
+
|
168
|
+
##
|
169
|
+
# The options Hash the task lib was created with
|
170
|
+
attr_reader :options
|
171
|
+
|
172
|
+
##
|
173
|
+
# The descriotion of the gem
|
174
|
+
attr_accessor :description
|
175
|
+
|
176
|
+
##
|
177
|
+
# The summary description of the gem.
|
178
|
+
attr_accessor :summary
|
179
|
+
|
180
|
+
##
|
181
|
+
# The Gem::Version of the current library, extracted from the top-level
|
182
|
+
# namespace.
|
183
|
+
attr_reader :version
|
184
|
+
|
185
|
+
##
|
186
|
+
# The README of the project as an RDoc::Markup::Document
|
187
|
+
attr_accessor :readme
|
188
|
+
|
189
|
+
##
|
190
|
+
# The title of the library for things like docs, gemspec, etc.
|
191
|
+
attr_accessor :title
|
192
|
+
|
193
|
+
##
|
194
|
+
# The file that will be the main page of documentation
|
195
|
+
attr_pathname :readme_file
|
196
|
+
|
197
|
+
##
|
198
|
+
# The file that provides high-level change history
|
199
|
+
attr_pathname :history_file
|
200
|
+
|
201
|
+
##
|
202
|
+
# The file to read the list of distribution files from
|
203
|
+
attr_pathname :manifest_file
|
204
|
+
|
205
|
+
##
|
206
|
+
# The files which should be distributed with the project as a Rake::FileList
|
207
|
+
attr_accessor :project_files
|
208
|
+
|
209
|
+
##
|
210
|
+
# The files which should be used to generate documentation as a Rake::FileList
|
211
|
+
attr_accessor :rdoc_files
|
212
|
+
|
213
|
+
##
|
214
|
+
# The public cetificates that can be used to verify signed gems
|
215
|
+
attr_accessor :cert_files
|
216
|
+
|
217
|
+
##
|
218
|
+
# The licenses the project is distributed under; usual practice is to list the
|
219
|
+
# SPDX name: https://spdx.org/licenses
|
220
|
+
attr_accessor :licenses
|
221
|
+
|
222
|
+
##
|
223
|
+
# The gem's authors in the form of strings in the format: `Name <email>`
|
224
|
+
attr_accessor :authors
|
225
|
+
|
226
|
+
##
|
227
|
+
# The URI of the project's homepage as a String
|
228
|
+
attr_accessor :homepage
|
229
|
+
|
230
|
+
##
|
231
|
+
# The Gem::RequestSet that describes the gem's dependencies
|
232
|
+
attr_accessor :dependencies
|
233
|
+
|
234
|
+
##
|
235
|
+
# The gemserver to push gems to
|
236
|
+
attr_accessor :gemserver
|
237
|
+
|
238
|
+
|
239
|
+
#
|
240
|
+
# Task definition
|
241
|
+
#
|
242
|
+
|
243
|
+
### Load the deveiate task libraries.
|
244
|
+
def load_task_libraries
|
245
|
+
taskdir = Pathname( __FILE__.delete_suffix('.rb') )
|
246
|
+
tasklibs = Rake::FileList[ taskdir + '*.rb' ].pathmap( '%-2d/%n' )
|
247
|
+
|
248
|
+
self.trace( "Loading task libs: %p" % [ tasklibs ] )
|
249
|
+
tasklibs.each do |lib|
|
250
|
+
require( lib )
|
251
|
+
end
|
252
|
+
|
253
|
+
self.class.constants.
|
254
|
+
map {|c| self.class.const_get(c) }.
|
255
|
+
select {|c| c.respond_to?(:instance_methods) }.
|
256
|
+
select {|c| c.instance_methods(false).include?(:define_tasks) }.
|
257
|
+
each do |mod|
|
258
|
+
self.trace "Loading tasks from %p" % [ mod ]
|
259
|
+
extend( mod )
|
260
|
+
end
|
261
|
+
|
262
|
+
self.setup( self.name, **self.options )
|
263
|
+
end
|
264
|
+
|
265
|
+
|
266
|
+
### Post-loading callback.
|
267
|
+
def setup( name, **options )
|
268
|
+
# No-op
|
269
|
+
end
|
270
|
+
|
271
|
+
|
272
|
+
### Task-definition hook.
|
273
|
+
def define_tasks
|
274
|
+
self.define_default_tasks
|
275
|
+
self.define_debug_tasks
|
276
|
+
|
277
|
+
super if defined?( super )
|
278
|
+
end
|
279
|
+
|
280
|
+
|
281
|
+
### Set up a simple default task
|
282
|
+
def define_default_tasks
|
283
|
+
desc "The task that runs by default"
|
284
|
+
task( :default => :spec )
|
285
|
+
|
286
|
+
desc "Check in the current changes"
|
287
|
+
task :checkin => :precheckin
|
288
|
+
task :commit => :checkin
|
289
|
+
task :ci => :checkin
|
290
|
+
task :precheckin => [ :check, :gemspec, :spec ]
|
291
|
+
|
292
|
+
desc "Sanity-check the project"
|
293
|
+
task :check
|
294
|
+
|
295
|
+
desc "Update the history file"
|
296
|
+
task :update_history
|
297
|
+
|
298
|
+
desc "Package up and push a release"
|
299
|
+
task :release => [ :prerelease, :release_gem, :postrelease ]
|
300
|
+
task :prerelease
|
301
|
+
task :release_gem
|
302
|
+
task :postrelease
|
303
|
+
|
304
|
+
task :spec
|
305
|
+
task :test => :spec
|
306
|
+
end
|
307
|
+
|
308
|
+
|
309
|
+
### Set up tasks for debugging the task library.
|
310
|
+
def define_debug_tasks
|
311
|
+
task( :base_debug ) do
|
312
|
+
self.output_documentation_debugging
|
313
|
+
self.output_project_files_debugging
|
314
|
+
self.output_dependency_debugging
|
315
|
+
self.output_release_debugging
|
316
|
+
end
|
317
|
+
|
318
|
+
task :debug => :base_debug
|
319
|
+
end
|
320
|
+
|
321
|
+
|
322
|
+
#
|
323
|
+
# Utility methods
|
324
|
+
#
|
325
|
+
|
326
|
+
### Fetch the TTY-Prompt, creating it if necessary.
|
327
|
+
def prompt
|
328
|
+
return @prompt ||= TTY::Prompt.new( output: $stderr )
|
329
|
+
end
|
330
|
+
|
331
|
+
|
332
|
+
### Fetch the Pastel object, creating it if necessary.
|
333
|
+
def pastel
|
334
|
+
return @pastel ||= begin
|
335
|
+
pastel = Pastel.new( enabled: $stdout.tty? )
|
336
|
+
pastel.alias_color( :headline, :bold, :white, :on_black )
|
337
|
+
pastel.alias_color( :success, :bold, :green )
|
338
|
+
pastel.alias_color( :error, :bold, :red )
|
339
|
+
pastel.alias_color( :warning, :yellow )
|
340
|
+
pastel.alias_color( :added, :green )
|
341
|
+
pastel.alias_color( :removed, :red )
|
342
|
+
pastel.alias_color( :prompt, :cyan )
|
343
|
+
pastel.alias_color( :even_row, :bold )
|
344
|
+
pastel.alias_color( :odd_row, :reset )
|
345
|
+
pastel
|
346
|
+
end
|
347
|
+
end
|
348
|
+
|
349
|
+
|
350
|
+
### Output +args+ to $stderr if tracing is enabled.
|
351
|
+
def trace( *args )
|
352
|
+
Rake.application.trace( *args ) if Rake.application.options.trace
|
353
|
+
end
|
354
|
+
|
355
|
+
|
356
|
+
### Extract the default title from the README if possible, or derive it from the
|
357
|
+
### gem name.
|
358
|
+
def extract_default_title
|
359
|
+
return self.name unless self.readme&.table_of_contents&.first
|
360
|
+
title = self.readme.table_of_contents.first.text
|
361
|
+
title ||= self.name
|
362
|
+
end
|
363
|
+
|
364
|
+
|
365
|
+
### Extract a summary from the README if possible. Returns +nil+ if not.
|
366
|
+
def extract_summary
|
367
|
+
return self.description.split( /(?<=\.)\s+/ ).first.gsub( /\n/, ' ' )
|
368
|
+
end
|
369
|
+
|
370
|
+
|
371
|
+
### Extract a description from the README if possible. Returns +nil+ if not.
|
372
|
+
def extract_description
|
373
|
+
parts = self.readme&.parts or return nil
|
374
|
+
return parts.find {|part| part.is_a?(RDoc::Markup::Paragraph) }&.text
|
375
|
+
end
|
376
|
+
|
377
|
+
|
378
|
+
### Return just the name parts of the library's authors setting.
|
379
|
+
def author_names
|
380
|
+
return self.authors.map do |author|
|
381
|
+
author[ /^(.*?) </, 1 ]
|
382
|
+
end
|
383
|
+
end
|
384
|
+
|
385
|
+
|
386
|
+
### Extract authors in the form `Firstname Lastname <email@address>` from the README.
|
387
|
+
def extract_authors
|
388
|
+
return [] unless self.readme
|
389
|
+
|
390
|
+
heading, list = self.readme.parts.each_cons( 2 ).find do |heading, list|
|
391
|
+
heading.is_a?( RDoc::Markup::Heading ) && heading.text =~ /^authors?/i &&
|
392
|
+
list.is_a?( RDoc::Markup::List )
|
393
|
+
end
|
394
|
+
|
395
|
+
unless list
|
396
|
+
self.trace "Couldn't find an Author(s) section of the readme."
|
397
|
+
return []
|
398
|
+
end
|
399
|
+
|
400
|
+
return list.items.map do |item|
|
401
|
+
# unparse the name + email
|
402
|
+
raw = item.parts.first.text or next
|
403
|
+
name, email = raw.split( ' mailto:', 2 )
|
404
|
+
"%s <%s>" % [ name, email ]
|
405
|
+
end
|
406
|
+
end
|
407
|
+
|
408
|
+
|
409
|
+
### Extract the URI of the homepage from the `home` item of the first NOTE-type
|
410
|
+
### list in the README. Returns +nil+ if no such URI could be found.
|
411
|
+
def extract_homepage
|
412
|
+
return fail_extraction(:homepage, "no README") unless self.readme
|
413
|
+
|
414
|
+
list = self.readme.parts.find {|part| RDoc::Markup::List === part && part.type == :NOTE } or
|
415
|
+
return fail_extraction(:homepage, "No NOTE list")
|
416
|
+
item = list.items.find {|item| item.label.include?('home') } or
|
417
|
+
return fail_extraction(:homepage, "No `home` item")
|
418
|
+
|
419
|
+
return item.parts.first.text
|
420
|
+
end
|
421
|
+
|
422
|
+
|
423
|
+
### Find the file that contains the VERSION constant and return it as a
|
424
|
+
### Gem::Version.
|
425
|
+
def find_version
|
426
|
+
version_file = LIB_DIR + "%s.rb" % [ self.name.gsub(/-/, '/') ]
|
427
|
+
|
428
|
+
unless version_file.readable?
|
429
|
+
self.prompt.warn "Version could not be read from %s" % [ version_file ]
|
430
|
+
return nil
|
431
|
+
end
|
432
|
+
|
433
|
+
version_line = version_file.readlines.find {|l| l =~ VERSION_PATTERN } or
|
434
|
+
abort "Can't read the VERSION from #{version_file}!"
|
435
|
+
version = version_line[ VERSION_PATTERN, :version ] or
|
436
|
+
abort "Couldn't find a semantic version in %p" % [ version_line ]
|
437
|
+
|
438
|
+
return Gem::Version.new( version )
|
439
|
+
end
|
440
|
+
|
441
|
+
|
442
|
+
### Returns +true+ if the manifest file exists and is readable.
|
443
|
+
def has_manifest?
|
444
|
+
return self.manifest_file.readable?
|
445
|
+
end
|
446
|
+
|
447
|
+
|
448
|
+
### Read the manifest file if there is one, falling back to a default list if
|
449
|
+
### there isn't a manifest.
|
450
|
+
def read_manifest
|
451
|
+
if self.has_manifest?
|
452
|
+
entries = self.manifest_file.readlines.map( &:chomp )
|
453
|
+
return Rake::FileList[ *entries ]
|
454
|
+
else
|
455
|
+
self.prompt.warn "No manifest (%s): falling back to a default list" %
|
456
|
+
[ self.manifest_file ]
|
457
|
+
return DEFAULT_PROJECT_FILES.dup
|
458
|
+
end
|
459
|
+
end
|
460
|
+
|
461
|
+
|
462
|
+
### Make a Rake::FileList of the files that should be used to generate
|
463
|
+
### documentation.
|
464
|
+
def make_rdoc_filelist
|
465
|
+
list = self.project_files.dup
|
466
|
+
|
467
|
+
list.exclude do |fn|
|
468
|
+
fn =~ %r:^(spec|data)/: || !fn.end_with?( *DOCUMENTATION_SUFFIXES )
|
469
|
+
end
|
470
|
+
|
471
|
+
return list
|
472
|
+
end
|
473
|
+
|
474
|
+
|
475
|
+
### Find the README file in the list of project files and return it as a
|
476
|
+
### Pathname.
|
477
|
+
def find_readme
|
478
|
+
file = self.project_files.find {|file| file =~ /^README\.(md|rdoc)$/ }
|
479
|
+
if file
|
480
|
+
return Pathname( file )
|
481
|
+
else
|
482
|
+
self.prompt.warn "No README found in the project files."
|
483
|
+
return DEFAULT_README_FILE
|
484
|
+
end
|
485
|
+
end
|
486
|
+
|
487
|
+
|
488
|
+
### Find the history file in the list of project files and return it as a
|
489
|
+
### Pathname.
|
490
|
+
def find_history_file
|
491
|
+
file = self.project_files.find {|file| file =~ /^History\.(md|rdoc)$/ }
|
492
|
+
if file
|
493
|
+
return Pathname( file )
|
494
|
+
else
|
495
|
+
self.prompt.warn "No History.{md,rdoc} found in the project files."
|
496
|
+
return DEFAULT_HISTORY_FILE
|
497
|
+
end
|
498
|
+
end
|
499
|
+
|
500
|
+
|
501
|
+
### Generate a TTY::Table from the current project files and return it.
|
502
|
+
def generate_project_files_table
|
503
|
+
columns = [
|
504
|
+
self.project_files.sort,
|
505
|
+
self.rdoc_files.sort
|
506
|
+
]
|
507
|
+
|
508
|
+
max_length = columns.map( &:length ).max
|
509
|
+
columns.each do |col|
|
510
|
+
self.trace "Filling out columns %d-%d" % [ col.length, max_length ]
|
511
|
+
next if col.length == max_length
|
512
|
+
col.fill( '', col.length .. max_length - 1 )
|
513
|
+
end
|
514
|
+
|
515
|
+
table = TTY::Table.new(
|
516
|
+
header: ['Project', 'Documentation'],
|
517
|
+
rows: columns.transpose,
|
518
|
+
)
|
519
|
+
|
520
|
+
return table
|
521
|
+
end
|
522
|
+
|
523
|
+
|
524
|
+
### Generate a TTY::Table from the current dependency list and return it.
|
525
|
+
def generate_dependencies_table
|
526
|
+
table = TTY::Table.new( header: ['Gem', 'Version', 'Type'] )
|
527
|
+
|
528
|
+
self.dependencies.each do |dep|
|
529
|
+
table << [ dep.name, dep.requirement.to_s, dep.type ]
|
530
|
+
end
|
531
|
+
|
532
|
+
return table
|
533
|
+
end
|
534
|
+
|
535
|
+
|
536
|
+
### Parse the README into an RDoc::Markup::Document and return it
|
537
|
+
def parse_readme
|
538
|
+
return nil unless self.readme_file.readable?
|
539
|
+
|
540
|
+
case self.readme_file.extname
|
541
|
+
when '.md'
|
542
|
+
return RDoc::Markdown.parse( self.readme_file.read )
|
543
|
+
when '.rdoc'
|
544
|
+
return RDoc::Markup.parse( self.readme_file.read )
|
545
|
+
else
|
546
|
+
raise "Can't parse %s: unhandled format %p" % [ self.readme_file, README_FILE.extname ]
|
547
|
+
end
|
548
|
+
end
|
549
|
+
|
550
|
+
|
551
|
+
### Load the gemdeps file if it exists, and return a Gem::RequestSet with the
|
552
|
+
### regular dependencies contained in it.
|
553
|
+
def find_dependencies
|
554
|
+
unless GEMDEPS_FILE.readable?
|
555
|
+
self.prompt.warn "Deps file (%s) is missing or unreadable, assuming no dependencies." %
|
556
|
+
[ GEMDEPS_FILE ]
|
557
|
+
return []
|
558
|
+
end
|
559
|
+
|
560
|
+
finder = Rake::DevEiate::GemDepFinder.new( GEMDEPS_FILE )
|
561
|
+
finder.load
|
562
|
+
return finder.dependencies
|
563
|
+
end
|
564
|
+
|
565
|
+
|
566
|
+
### Return the character used to build headings give the filename of the file to
|
567
|
+
### be generated.
|
568
|
+
def header_char_for( filename )
|
569
|
+
case File.extname( filename )
|
570
|
+
when '.md' then return '#'
|
571
|
+
when '.rdoc' then return '='
|
572
|
+
else
|
573
|
+
raise "Don't know what header character is appropriate for %s" % [ filename ]
|
574
|
+
end
|
575
|
+
end
|
576
|
+
|
577
|
+
|
578
|
+
### Read a template with the given +name+ from the data directory and return it
|
579
|
+
### as an ERB object.
|
580
|
+
def read_template( name )
|
581
|
+
name = "%s.erb" % [ name ] unless name.to_s.end_with?( '.erb' )
|
582
|
+
template_path = DEVEIATE_DATADIR + name
|
583
|
+
template_src = template_path.read( encoding: 'utf-8' )
|
584
|
+
|
585
|
+
return ERB.new( template_src, trim_mode: '-' )
|
586
|
+
end
|
587
|
+
|
588
|
+
|
589
|
+
### Load the template at the specified +template_path+, and render it with suitable
|
590
|
+
### settings for the given +target_filename+.
|
591
|
+
def load_and_render_template( template_path, target_filename )
|
592
|
+
template = self.read_template( template_path )
|
593
|
+
header_char = self.header_char_for( target_filename )
|
594
|
+
|
595
|
+
return template.result_with_hash(
|
596
|
+
header_char: header_char,
|
597
|
+
project: self
|
598
|
+
)
|
599
|
+
end
|
600
|
+
|
601
|
+
|
602
|
+
### Output debugging information about documentation.
|
603
|
+
def output_documentation_debugging
|
604
|
+
summary = self.extract_summary
|
605
|
+
description = self.extract_description
|
606
|
+
|
607
|
+
self.prompt.say( "Documentation", color: :bright_green )
|
608
|
+
self.prompt.say( "Authors:" )
|
609
|
+
self.authors.each do |author|
|
610
|
+
self.prompt.say( " • " )
|
611
|
+
self.prompt.say( author, color: :bold )
|
612
|
+
end
|
613
|
+
self.prompt.say( "Summary: " )
|
614
|
+
self.prompt.say( summary, color: :bold )
|
615
|
+
self.prompt.say( "Description:" )
|
616
|
+
self.prompt.say( description, color: :bold )
|
617
|
+
self.prompt.say( "\n" )
|
618
|
+
end
|
619
|
+
|
620
|
+
|
621
|
+
### Output debugging info related to the list of project files the build
|
622
|
+
### operates on.
|
623
|
+
def output_project_files_debugging
|
624
|
+
self.prompt.say( "Project files:", color: :bright_green )
|
625
|
+
table = self.generate_project_files_table
|
626
|
+
if table.empty?
|
627
|
+
self.prompt.warn( "None." )
|
628
|
+
else
|
629
|
+
self.prompt.say( table.render(:unicode, padding: [0,1]) )
|
630
|
+
end
|
631
|
+
self.prompt.say( "\n" )
|
632
|
+
end
|
633
|
+
|
634
|
+
|
635
|
+
### Output debugging about the project's dependencies.
|
636
|
+
def output_dependency_debugging
|
637
|
+
self.prompt.say( "Dependencies", color: :bright_green )
|
638
|
+
table = self.generate_dependencies_table
|
639
|
+
if table.empty?
|
640
|
+
self.prompt.warn( "None." )
|
641
|
+
else
|
642
|
+
self.prompt.say( table.render(:unicode, padding: [0,1]) )
|
643
|
+
end
|
644
|
+
self.prompt.say( "\n" )
|
645
|
+
end
|
646
|
+
|
647
|
+
|
648
|
+
### Output debugging regarding where releases will be posted.
|
649
|
+
def output_release_debugging
|
650
|
+
self.prompt.say( "Will push releases to:", color: :bright_green )
|
651
|
+
self.prompt.say( " #{self.gemserver}" )
|
652
|
+
self.prompt.say( "\n" )
|
653
|
+
end
|
654
|
+
|
655
|
+
|
656
|
+
#######
|
657
|
+
private
|
658
|
+
#######
|
659
|
+
|
660
|
+
### Ensure the given +gemname+ is valid, raising if it isn't.
|
661
|
+
def validate_gemname( gemname )
|
662
|
+
raise ScriptError, "invalid gem name" unless
|
663
|
+
Gem::SpecificationPolicy::VALID_NAME_PATTERN.match?( gemname )
|
664
|
+
return gemname.freeze
|
665
|
+
end
|
666
|
+
|
667
|
+
|
668
|
+
### Log a reason that extraction of the specified +item+ failed for the given
|
669
|
+
### +reason+ and then return +nil+.
|
670
|
+
def fail_extraction( item, reason )
|
671
|
+
self.prompt.warn "Extraction of %s failed: %s" % [ item, reason ]
|
672
|
+
return nil
|
673
|
+
end
|
674
|
+
|
675
|
+
end # class Rake::DevEiate
|
data.tar.gz.sig
ADDED
Binary file
|