Module: Rake::DevEiate::Gemspec

Extended by:
Rake::DSL
Defined in:
lib/rake/deveiate/gemspec.rb

Overview

Gemspec-generation tasks

Constant Summary collapse

AUTHOR_PATTERN =

Pattern for splitting parsed authors list items into name and email

/^(?<name>.*)\s<(?<email>.*)>$/
RELEASE_USER_ENV =

Environment variable for overriding the name of the user packaging up a release.

'RELEASE_USER'

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#post_install_message ⇒ Object

A message to be displayed after the gem is installed.



41
42
43
# File 'lib/rake/deveiate/gemspec.rb', line 41

def post_install_message
  @post_install_message
end

#signing_key ⇒ Object

The path to the file used to sign released gems



25
26
27
# File 'lib/rake/deveiate/gemspec.rb', line 25

def signing_key
  @signing_key
end

Instance Method Details

#define_tasks ⇒ Object

Define gemspec tasks



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/rake/deveiate/gemspec.rb', line 53

def define_tasks
  super if defined?( super )

  gemspec_file = "#{self.name}.gemspec"

  if self.has_manifest?
    file( self.manifest_file )
    file( gemspec_file => self.manifest_file )
  else
    file( gemspec_file )
  end

  task( gemspec_file ) do |task|
    self.prompt.say "Updating gemspec"

    spec = self.make_prerelease_gemspec

    File.open( task.name, 'w' ) do |fh|
      fh.write( spec.to_ruby )
    end
  end

  desc "(Re)Generate the gemspec file"
  task :gemspec => gemspec_file

  CLEAN.include( gemspec_file.to_s )

  task :precheckin => :gemspec

  task( :gemspec_debug, &method(:do_gemspec_debug) )
  task :debug => :gemspec_debug
end

#do_gemspec_debug(task, args) ⇒ Object

Task function -- output debugging for gemspec tasks.



88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/rake/deveiate/gemspec.rb', line 88

def do_gemspec_debug( task, args )
  gemspec = self.gemspec
  gemspec_src = gemspec.to_yaml

  if self.post_install_message
    self.prompt.say( "Post-install message:", color: :bright_green )
    self.prompt.say( self.indent(self.post_install_message, 4) )
    self.prompt.say( "\n" )
  end

  self.prompt.say( "Gemspec:", color: :bright_green )
  self.prompt.say( self.indent(gemspec_src, 4) )
  self.prompt.say( "\n" )
end

#extract_documentation_uri ⇒ Object

Extract the documentation URI from the docs item of the first NOTE-type list in the README. Returns nil if no such URI could be found.



226
227
228
229
230
231
232
233
234
235
# File 'lib/rake/deveiate/gemspec.rb', line 226

def extract_documentation_uri
  return fail_extraction( :documentation, "no README" ) unless self.readme

  list = self.readme.parts.find {|part| RDoc::Markup::List === part && part.type == :NOTE } or
    return fail_extraction(:documentation, "No NOTE list")
  item = list.items.find {|item| item.label.include?('docs') } or
    return fail_extraction(:documentation, "No `docs` item")

  return URI( item.parts.first.text )
end

#extract_source_uri ⇒ Object

Extract the source URI from the docs item of the first NOTE-type list in the README. Returns nil if no such URI could be found.



240
241
242
243
244
245
246
247
248
249
# File 'lib/rake/deveiate/gemspec.rb', line 240

def extract_source_uri
  return fail_extraction( :source, "no README" ) unless self.readme

  list = self.readme.parts.find {|part| RDoc::Markup::List === part && part.type == :NOTE } or
    return fail_extraction(:code, "No NOTE list")
  item = list.items.find {|item| item.label.include?('code') } or
    return fail_extraction(:code, "No `code` item")

  return URI( item.parts.first.text )
end

#find_signing_cert ⇒ Object

Return the path to the cert belonging to the user packaging up the release. Returns nil if no such cert exists.



268
269
270
271
272
273
# File 'lib/rake/deveiate/gemspec.rb', line 268

def find_signing_cert
  current_user = ENV[ RELEASE_USER_ENV ] || Etc.getlogin
  certfile = self.cert_files.find {|fn| fn.end_with?("#{current_user}.pem") } or
    return nil
  return File.expand_path( certfile )
end

#gemspec ⇒ Object

Return the project's Gem::Specification, creating it if necessary.



105
106
107
# File 'lib/rake/deveiate/gemspec.rb', line 105

def gemspec
  return @gemspec ||= self.make_gemspec
end

#make_gem_metadata ⇒ Object

Build the hash of metadata that should be attached to the gem.



178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
# File 'lib/rake/deveiate/gemspec.rb', line 178

def 
    # "bug_tracker_uri"   => "https://example.com/user/bestgemever/issues",
    # "changelog_uri"     => "https://example.com/user/bestgemever/CHANGELOG.md",
    # "documentation_uri" => "https://www.example.info/gems/bestgemever/0.0.1",
    # "homepage_uri"      => "https://bestgemever.example.io",
    # "mailing_list_uri"  => "https://groups.example.com/bestgemever",
    # "source_code_uri"   => "https://example.com/user/bestgemever",
    # "wiki_uri"          => "https://example.com/user/bestgemever/wiki"

   = {
    "homepage_uri" => self.homepage
  }

  if docs_uri = self.extract_documentation_uri
    ['documentation_uri'] = docs_uri.to_s
    if docs_uri.path.end_with?( '/', self.name )
      cl_uri = docs_uri.dup
      cl_uri.path = File.join( cl_uri.path, 'History_md.html' )
      ['changelog_uri'] = cl_uri.to_s
    end
  end

  if source_uri = self.extract_source_uri
    ['source_uri'] = source_uri.to_s
    case source_uri.host
    when /\.sr\.ht/
      bt_uri = source_uri.dup
      bt_uri.host = 'todo.sr.ht'
      ['bug_tracker_uri'] = bt_uri.to_s
    when /\.gitlab\.com/
      bt_uri = source_uri.dup
      bt_uri.path += '-/issues'
      ['bug_tracker_uri'] = bt_uri.to_s
    when /\.github\.com/
      bt_uri = source_uri.dup
      bt_uri.path += '/issues'
      ['bug_tracker_uri'] = bt_uri.to_s
    else
      self.trace "No idea what bug tracker URIs for %s look like!" % [ source_uri.host ]
    end
  end

  return 
end

#make_gemspec ⇒ Object

Return a Gem::Specification created from the project's metadata.



118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
# File 'lib/rake/deveiate/gemspec.rb', line 118

def make_gemspec
  spec = Gem::Specification.new

  spec.name         = self.name
  spec.description  = self.description
  spec.homepage     = self.homepage
  spec.summary      = self.summary || self.extract_summary
  spec.files        = self.project_files
  spec.executables  = self.executables
  spec.extensions   = self.extensions.to_a
  spec.signing_key  = self.resolve_signing_key.to_s
  spec.cert_chain   = [ self.find_signing_cert ].compact
  spec.version      = self.version
  spec.licenses     = self.licenses
  spec.date         = Date.today

  spec.     = self.

  spec.required_ruby_version = self.required_ruby_version if
    self.required_ruby_version
  spec.['allowed_push_host'] = self.allowed_push_host if self.allowed_push_host
  spec.post_install_message = self.post_install_message

  self.authors.each do |author|
    if ( m = author.match(AUTHOR_PATTERN) )
      spec.authors ||= []
      spec.authors << m[:name]
      spec.email ||= []
      spec.email << m[:email] if m[:email]
    else
      self.prompt.warn "Couldn't extract author name + email from %p" % [ author ]
    end
  end

  self.dependencies.each do |dep|
    if dep.runtime?
      spec.add_runtime_dependency( dep )
    else
      spec.add_development_dependency( dep )
    end
  end

  return spec
end

#make_prerelease_gemspec ⇒ Object

Return a Gem::Specification with its properties modified to be suitable for a pre-release gem.



166
167
168
169
170
171
172
173
174
# File 'lib/rake/deveiate/gemspec.rb', line 166

def make_prerelease_gemspec
  spec = self.make_gemspec

  spec.version     = self.prerelease_version
  spec.signing_key = nil
  spec.cert_chain  = []

  return spec
end

#prerelease_version ⇒ Object

Return a version string



253
254
255
# File 'lib/rake/deveiate/gemspec.rb', line 253

def prerelease_version
  return "#{self.version.bump}.0-#{Time.now.strftime("%Y%m%d%H%M%S")}"
end

#reset ⇒ Object

Reset any cached data when project attributes change.



45
46
47
48
49
# File 'lib/rake/deveiate/gemspec.rb', line 45

def reset
  super if defined?( super )
  @gemspec = nil
  @post_install_message = nil
end

#resolve_signing_key ⇒ Object

Resolve the path of the signing key



259
260
261
262
263
# File 'lib/rake/deveiate/gemspec.rb', line 259

def resolve_signing_key
  path = Pathname( self.signing_key ).expand_path
  path = path.readlink if path.symlink?
  return path
end

#setup(_name, **options) ⇒ Object

Set some defaults when the task lib is set up.



29
30
31
32
33
34
35
36
# File 'lib/rake/deveiate/gemspec.rb', line 29

def setup( _name, **options )
  super if defined?( super )

  @signing_key = options[:signing_key] || Gem.default_key_path
  @post_install_message = options[:post_install_message]

  @gemspec = nil
end

#validate_gemspec(packaging = true, strict = false) ⇒ Object

Validate the gemspec, raising a Gem::InvalidSpecificationException if it's not valid.



112
113
114
# File 'lib/rake/deveiate/gemspec.rb', line 112

def validate_gemspec( packaging=true, strict=false )
  return self.gemspec.validate( packaging, strict )
end