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
@@ -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
|