Class: Hoe
Overview
Hoe is a simple rake/rubygems helper for project Rakefiles. It helps generate rubygems and includes a dynamic plug-in system allowing for easy extensibility. Hoe ships with plug-ins for all your usual project tasks including rdoc generation, testing, packaging, and deployment.
Using Hoe
Basics
Sow generates a new project from scratch. Sow uses a simple ERB templating system allowing you to capture patterns common to your projects. Run ‘sow` and then see ~/.hoe_template for more info:
% sow project_name
...
% cd project_name
and have at it.
Extra Configuration Options:
Hoe maintains a config file for cross-project values. The file is located at ~/.hoerc
. The file is a YAML formatted config file with the following settings (extended by plugins):
- exclude
-
A regular expression of files to exclude from
check_manifest
.
Run `rake config_hoe`
and see ~/.hoerc for examples.
Extending Hoe
Hoe can be extended via its plugin system. Hoe searches out all installed files matching 'hoe/*.rb'
and loads them. Those files are expected to define a module matching the file name. The module must define a define task method and can optionally define an initialize method. Both methods must be named to match the file. eg
module Hoe::Blah
def initialize_blah # optional
# ...
end
def define_blah_tasks
# ...
end
end
Hoe Plugin Loading Sequence
Hoe.spec
Hoe.load_plugins
require
activate_plugins
extend plugin_module
initialize_plugins
initialize_XXX
activate_plugin_deps
activate_XXX_deps
yield spec
post_initialize
define_spec # gemspec, not hoespec
load_plugin_tasks
add_dependencies
Defined Under Namespace
Modules: Clean, Compiler, Cov, Debug, Deps, Flay, Flog, GemPreludeSucks, Gemcutter, Inline, Newb, Package, Publish, Racc, Rdoc, Signing, Test
Constant Summary collapse
- VERSION =
duh
"4.2.2"
- RUBY_DEBUG =
Used to add extra flags to RUBY_FLAGS.
- RUBY_FLAGS =
Used to specify flags to ruby [has smart default].
ENV["RUBY_FLAGS"] || default_ruby_flags
- URLS_TO_META_MAP =
Map from the commonly used url names to gemspec’s metadata keys See guides.rubygems.org/specification-reference/#metadata
{ "bugs" => "bug_tracker_uri", "clog" => "changelog_uri", "doco" => "documentation_uri", "docs" => "documentation_uri", "home" => "homepage_uri", "code" => "source_code_uri", "wiki" => "wiki_uri", "mail" => "mailing_list_uri", }
- DEFAULT_CONFIG =
Default configuration values for .hoerc. Plugins should populate this on load.
{ "exclude" => /\/tmp\/|CVS|\.svn|\.git|TAGS|extconf.h|\.bundle$|\.o$|\.log$/, }
- WINDOZE =
True if you’re a masochistic developer. Used for building commands.
RbConfig::CONFIG["host_os"] =~ /mswin|mingw/
- @@plugins =
[:clean, :debug, :deps, :flay, :flog, :newb, :package, :publish, :gemcutter, :signing, :test]
Instance Attribute Summary collapse
-
#author ⇒ Object
MANDATORY: The author(s) of the package.
-
#bindir ⇒ Object
Optional: The name of the executables directory.
-
#changes ⇒ Object
Optional: A description of the release’s latest changes.
-
#description ⇒ Object
Optional: A description of the project.
-
#description_sections ⇒ Object
Optional: What sections from the readme to use for auto-description.
-
#email ⇒ Object
MANDATORY: The author’s email address(es).
-
#extra_deps ⇒ Object
Optional: An array of rubygem dependencies.
-
#extra_dev_deps ⇒ Object
Optional: An array of rubygem developer dependencies.
-
#extra_rdoc_files ⇒ Object
Optional: Extra files you want to add to RDoc.
-
#group_name ⇒ Object
Optional: The name of the group authoring the project.
-
#history_file ⇒ Object
Optional: The filename for the project history.
-
#homepage ⇒ Object
Optional: The homepage of the project.
-
#licenses ⇒ Object
Optional: An array containing the license(s) under which this gem is released.
-
#name ⇒ Object
MANDATORY: The name of the release.
-
#post_install_message ⇒ Object
Optional: A post-install message to be displayed when gem is installed.
-
#readme_file ⇒ Object
Optional: The filename for the project readme.
-
#spec ⇒ Object
The Gem::Specification.
-
#spec_extras ⇒ Object
Optional: A hash of extra values to set in the gemspec.
-
#summary ⇒ Object
Optional: A short summary of the project.
-
#summary_sentences ⇒ Object
Optional: Number of sentences from description for summary.
-
#test_globs ⇒ Object
Optional: An array of test file patterns [default: test/*/test_.rb].
-
#urls ⇒ Object
Optional: The urls of the project.
-
#version ⇒ Object
MANDATORY: The version.
Class Method Summary collapse
-
.add_include_dirs(*dirs) ⇒ Object
Add extra dirs to both $: and RUBY_FLAGS (for test runs and rakefile deps).
-
.bad_plugins ⇒ Object
Returns plugins that could not be loaded by Hoe.load_plugins.
-
.load_plugins(plugins = Hoe.plugins) ⇒ Object
Find and load all plugin files.
-
.normalize_names(project) ⇒ Object
Normalize a project name into the project, file, klass and test names that follow Ruby package naming guidelines.
-
.plugin(*plugins) ⇒ Object
Activates
plugins
. -
.plugins ⇒ Object
The list of active plugins.
-
.spec(name, &block) ⇒ Object
Execute the Hoe DSL to define your project’s Hoe specification (which interally creates a gem specification).
Instance Method Summary collapse
-
#activate_plugin_deps ⇒ Object
Run all activate_*_deps methods for plugins.
-
#activate_plugins ⇒ Object
Activate plugin modules and add them to the current instance.
-
#add_dependencies ⇒ Object
Add standard and user defined dependencies to the spec.
-
#attr_accessor ⇒ Object
Optional: Extra directories to use (eg for test runs).
-
#check_for_version ⇒ Object
:nodoc:.
-
#define_spec ⇒ Object
Define the Gem::Specification.
-
#dependency(name, version, type = :runtime) ⇒ Object
Add a dependency declaration to your spec.
-
#dependency_target ⇒ Object
Returns the proper dependency list for the thingy.
-
#developer(name, email) ⇒ Object
Convenience method to set add to both the author and email fields.
-
#have_gem?(name) ⇒ Boolean
Returns true if the gem
name
is installed. -
#initialize(name, version = nil) ⇒ Hoe
constructor
Create a newly initialized hoe spec.
-
#initialize_plugins ⇒ Object
Run all initialize_* methods for plugins.
-
#intuit_values(input) ⇒ Object
Intuit values from the readme and history files.
-
#license(name) ⇒ Object
Specify a license for your gem.
-
#load_plugin_tasks ⇒ Object
Load activated plugins by calling their define tasks method.
-
#maybe_load_yaml(path) ⇒ Object
:nodoc:.
-
#missing(name) ⇒ Object
Bitch about a file that is missing data or unparsable for intuiting values.
-
#normalize_deps(deps) ⇒ Object
Normalize the dependencies.
-
#paragraphs_of(path, *paragraphs) ⇒ Object
Reads a file at
path
and spits out an array of theparagraphs
specified. -
#parse_urls(text) ⇒ Object
Parse the urls section of the readme file.
-
#pluggable! ⇒ Object
Tell the world you’re a pluggable package (ie you require rubygems 1.3.1+).
-
#plugin?(name) ⇒ Boolean
Is a plugin activated? Used for guarding missing plugins in your hoe spec:.
-
#post_initialize ⇒ Object
Finalize configuration.
-
#read_manifest ⇒ Object
Reads Manifest.txt and returns an Array of lines in the manifest.
-
#require_ruby_version(*versions) ⇒ Object
Declare that your gem requires a specific ruby version.
-
#require_rubygems_version(*versions) ⇒ Object
Declare that your gem requires a specific rubygems version.
-
#ruby20! ⇒ Object
Declare that this gem requires ruby to be in the 2.0+ family.
-
#ruby21! ⇒ Object
Declare that this gem requires ruby to be in the 2.1+ family.
-
#ruby22! ⇒ Object
Declare that this gem requires ruby to be in the 2.2+ family.
-
#ruby23! ⇒ Object
Declare that this gem requires ruby to be in the 2.3+ family.
-
#run_spec_extras ⇒ Object
:nodoc:.
-
#skip_intuit_values? ⇒ Boolean
:nodoc:.
-
#timebomb(n, m, finis = nil, start = nil) ⇒ Object
Provide a linear degrading value from n to m over start to finis dates.
-
#validate_fields ⇒ Object
Verify that mandatory fields are set.
-
#with_config {|config, rc| ... } ⇒ Object
Loads ~/.hoerc, merges it with a .hoerc in the current pwd (if any) and yields the configuration and its path.
Constructor Details
#initialize(name, version = nil) ⇒ Hoe
Create a newly initialized hoe spec.
634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 |
# File 'lib/hoe.rb', line 634 def initialize name, version = nil # :nodoc: self.name = name self.version = version self. = [] self.changes = nil self.description = nil self.description_sections = %w[description] self.email = [] self.extra_deps = [] self.extra_dev_deps = [] self.extra_rdoc_files = [] self.licenses = [] self. = nil self.group_name = name.downcase self.spec = nil self.spec_extras = {} self.summary = nil self.summary_sentences = 1 self.test_globs = ["test/**/{test,spec}_*.rb", "test/**/*_{test,spec}.rb"] manifest = read_manifest if manifest then self.readme_file = manifest.grep(/^README\./).first self.history_file = manifest.grep(/^History\./).first end self.history_file ||= Dir.glob("History.{rdoc,txt,md}").first || "History.txt" self.readme_file ||= Dir.glob("README.{rdoc,txt,md}").first || "README.txt" abort "Hoe.new {...} removed. Switch to Hoe.spec." if block_given? end |
Instance Attribute Details
#author ⇒ Object
MANDATORY: The author(s) of the package. (can be array)
Use the #developer method to fill in both author and email cleanly.
143 144 145 |
# File 'lib/hoe.rb', line 143 def @author end |
#bindir ⇒ Object
Optional: The name of the executables directory. [default: bin]
228 229 230 |
# File 'lib/hoe.rb', line 228 def bindir @bindir end |
#changes ⇒ Object
Optional: A description of the release’s latest changes. Auto-populates to the top entry of History.txt.
149 150 151 |
# File 'lib/hoe.rb', line 149 def changes @changes end |
#description ⇒ Object
Optional: A description of the project. Auto-populates from the first paragraph of the DESCRIPTION section of README.txt.
See also: Hoe#summary and Hoe.paragraphs_of.
157 158 159 |
# File 'lib/hoe.rb', line 157 def description @description end |
#description_sections ⇒ Object
Optional: What sections from the readme to use for auto-description. Defaults to %w(description).
163 164 165 |
# File 'lib/hoe.rb', line 163 def description_sections @description_sections end |
#email ⇒ Object
MANDATORY: The author’s email address(es). (can be array)
Use the #developer method to fill in both author and email cleanly.
170 171 172 |
# File 'lib/hoe.rb', line 170 def email @email end |
#extra_deps ⇒ Object
Optional: An array of rubygem dependencies.
extra_deps << ['blah', '~> 1.0']
177 178 179 |
# File 'lib/hoe.rb', line 177 def extra_deps @extra_deps end |
#extra_dev_deps ⇒ Object
Optional: An array of rubygem developer dependencies.
182 183 184 |
# File 'lib/hoe.rb', line 182 def extra_dev_deps @extra_dev_deps end |
#extra_rdoc_files ⇒ Object
Optional: Extra files you want to add to RDoc.
.txt files are automatically included (excluding the obvious).
189 190 191 |
# File 'lib/hoe.rb', line 189 def extra_rdoc_files @extra_rdoc_files end |
#group_name ⇒ Object
Optional: The name of the group authoring the project. [default: name.downcase]
223 224 225 |
# File 'lib/hoe.rb', line 223 def group_name @group_name end |
#history_file ⇒ Object
Optional: The filename for the project history. [default: History.txt]
194 195 196 |
# File 'lib/hoe.rb', line 194 def history_file @history_file end |
#homepage ⇒ Object
Optional: The homepage of the project. Auto-populates to the home key of the urls read from the README.txt
235 236 237 |
# File 'lib/hoe.rb', line 235 def homepage @homepage end |
#licenses ⇒ Object
Optional: An array containing the license(s) under which this gem is released.
Warns and defaults to “MIT” if not set.
201 202 203 |
# File 'lib/hoe.rb', line 201 def licenses @licenses end |
#name ⇒ Object
MANDATORY: The name of the release.
Set via Hoe.spec.
208 209 210 |
# File 'lib/hoe.rb', line 208 def name @name end |
#post_install_message ⇒ Object
Optional: A post-install message to be displayed when gem is installed.
213 214 215 |
# File 'lib/hoe.rb', line 213 def @post_install_message end |
#readme_file ⇒ Object
Optional: The filename for the project readme. [default: README.txt]
218 219 220 |
# File 'lib/hoe.rb', line 218 def readme_file @readme_file end |
#spec ⇒ Object
The Gem::Specification.
240 241 242 |
# File 'lib/hoe.rb', line 240 def spec @spec end |
#spec_extras ⇒ Object
Optional: A hash of extra values to set in the gemspec. Value may be a proc.
spec_extras[:required_rubygems_version] = '>= 1.3.2'
(tho, see #pluggable! if that’s all you want to do)
249 250 251 |
# File 'lib/hoe.rb', line 249 def spec_extras @spec_extras end |
#summary ⇒ Object
Optional: A short summary of the project. Auto-populates from the first sentence of the description.
See also: Hoe#description and Hoe.paragraphs_of.
257 258 259 |
# File 'lib/hoe.rb', line 257 def summary @summary end |
#summary_sentences ⇒ Object
Optional: Number of sentences from description for summary. Defaults to 1.
262 263 264 |
# File 'lib/hoe.rb', line 262 def summary_sentences @summary_sentences end |
#test_globs ⇒ Object
Optional: An array of test file patterns [default: test/*/test_.rb]
267 268 269 |
# File 'lib/hoe.rb', line 267 def test_globs @test_globs end |
#urls ⇒ Object
Optional: The urls of the project. This can be an array or (preferably) a hash. Auto-populates to the urls read from the beginning of README.txt.
See parse_urls for more details
276 277 278 |
# File 'lib/hoe.rb', line 276 def urls @urls end |
#version ⇒ Object
MANDATORY: The version. Don’t hardcode! use a constant in the project.
281 282 283 |
# File 'lib/hoe.rb', line 281 def version @version end |
Class Method Details
.add_include_dirs(*dirs) ⇒ Object
Add extra dirs to both $: and RUBY_FLAGS (for test runs and rakefile deps)
296 297 298 299 300 301 302 |
# File 'lib/hoe.rb', line 296 def self.add_include_dirs(*dirs) dirs = dirs.flatten include_dirs.concat dirs $:.unshift(*dirs) s = File::PATH_SEPARATOR RUBY_FLAGS.sub!(/-I/, "-I#{dirs.join(s)}#{s}") end |
.bad_plugins ⇒ Object
Returns plugins that could not be loaded by Hoe.load_plugins.
307 308 309 |
# File 'lib/hoe.rb', line 307 def self.bad_plugins @bad_plugins end |
.load_plugins(plugins = Hoe.plugins) ⇒ Object
Find and load all plugin files.
It is called at the end of hoe.rb
316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 |
# File 'lib/hoe.rb', line 316 def self.load_plugins plugins = Hoe.plugins @found ||= {} @loaded ||= {} @files ||= Gem.find_files "hoe/*.rb" @files.reverse.each do |path| # reverse so first one wins @found[File.basename(path, ".rb").intern] = path end :keep_doing_this while @found.map { |name, plugin| next unless plugins.include? name next if @loaded[name] begin warn "loading #{plugin}" if $DEBUG @loaded[name] = require plugin rescue LoadError => e warn "error loading #{plugin.inspect}: #{e.}. skipping..." end }.any? bad_plugins = plugins - @loaded.keys bad_plugins.each do |bad_plugin| plugins.delete bad_plugin end @bad_plugins.concat bad_plugins @bad_plugins.uniq! return @loaded, @found end |
.normalize_names(project) ⇒ Object
Normalize a project name into the project, file, klass and test names that follow Ruby package naming guidelines.
Project names are lowercase with _ separating package parts and - separating extension parts.
File names are lowercase with _ separating pacagke parts and / separating extension parts. net-http-persistent becomes net/http/persistent.
- Klass names are CamelCase with
-
separating extension parts.
Test klass names are same as Klass with Test prepended to each part.
361 362 363 364 365 366 367 368 369 |
# File 'lib/hoe.rb', line 361 def self.normalize_names project # :nodoc: project = project.gsub(/([A-Z])/, '_\1').downcase.sub(/^_/, "") klass = project.gsub(/(?:^|_)([a-z])/) { $1.upcase } klass = klass. gsub(/(?:^|-)([a-z])/) { "::#{$1.upcase}" } test_klass = klass. gsub(/(^|::)([A-Z])/) { "#{$1}Test#{$2}" } file_name = project.gsub(/-/, "/") return project, file_name, klass, test_klass end |
.plugin(*plugins) ⇒ Object
Activates plugins
. If a plugin cannot be loaded it will be ignored.
Plugins may also be activated through a plugins
array in ~/.hoerc
. This should only be used for plugins that aren’t critical to your project and plugins that you want to use on other projects.
379 380 381 382 |
# File 'lib/hoe.rb', line 379 def self.plugin *plugins self.plugins.concat plugins self.plugins.uniq! end |
.plugins ⇒ Object
The list of active plugins.
387 388 389 |
# File 'lib/hoe.rb', line 387 def self.plugins @@plugins end |
.spec(name, &block) ⇒ Object
Execute the Hoe DSL to define your project’s Hoe specification (which interally creates a gem specification). All hoe attributes and methods are available within block
. Eg:
Hoe.spec name do
# ... project specific data ...
end
400 401 402 403 404 405 406 407 408 |
# File 'lib/hoe.rb', line 400 def self.spec name, &block Hoe.load_plugins spec = self.new name spec.activate_plugins spec.instance_eval(&block) spec.post_initialize spec # TODO: remove? end |
Instance Method Details
#activate_plugin_deps ⇒ Object
Run all activate_*_deps methods for plugins
448 449 450 451 452 453 454 |
# File 'lib/hoe.rb', line 448 def activate_plugin_deps Hoe.plugins.each do |plugin| msg = "activate_#{plugin}_deps" warn msg if $DEBUG send msg if self.respond_to? msg end end |
#activate_plugins ⇒ Object
Activate plugin modules and add them to the current instance.
413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 |
# File 'lib/hoe.rb', line 413 def activate_plugins with_config do |config, _| config_plugins = config["plugins"] break unless config_plugins Hoe.plugins.concat config_plugins.map(&:intern) end Hoe.load_plugins Hoe.plugins names = Hoe.constants.map(&:to_s) names.reject! { |n| n =~ /^[A-Z_]+$/ } names.each do |name| next unless Hoe.plugins.include? name.downcase.intern warn "extend #{name}" if $DEBUG self.extend Hoe.const_get(name) end initialize_plugins end |
#add_dependencies ⇒ Object
Add standard and user defined dependencies to the spec.
484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 |
# File 'lib/hoe.rb', line 484 def add_dependencies self.extra_deps = normalize_deps extra_deps self.extra_dev_deps = normalize_deps extra_dev_deps case name when "hoe" then # do nothing? these deps are already in the hoe spec in the Rakefile else version = VERSION.split(/\./).first(2).join(".") dependency "hoe", "~> #{version}", :development end seen = {} extra_deps.each do |dep| next if seen[dep.first] seen[dep.first] = true spec.add_dependency(*dep) end extra_dev_deps.each do |dep| next if seen[dep.first] seen[dep.first] = true spec.add_development_dependency(*dep) end end |
#attr_accessor ⇒ Object
Optional: Extra directories to use (eg for test runs). See Hoe.add_include_dirs
.
291 |
# File 'lib/hoe.rb', line 291 mc.send :attr_accessor, :include_dirs |
#check_for_version ⇒ Object
:nodoc:
580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 |
# File 'lib/hoe.rb', line 580 def check_for_version # :nodoc: return if self.version version = nil version_re = /VERSION += +([\"\'])([\d][\w\.]+)\1/ spec.files.each do |file| next unless File.exist? file version = File.read_utf(file)[version_re, 2] rescue nil break if version end spec.version = self.version = version if version unless self.version then spec.version = self.version = "0.borked" warn "** Add 'VERSION = \"x.y.z\"' to your code," warn " add a version to your hoe spec," warn " or fix your Manifest.txt" end end |
#define_spec ⇒ Object
Define the Gem::Specification.
523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 |
# File 'lib/hoe.rb', line 523 def define_spec self.spec = Gem::Specification.new do |s| dirs = Dir["lib"] manifest = read_manifest abort [ "Manifest is missing or couldn't be read.", "The Manifest is kind of a big deal.", "Maybe you're using a gem packaged by a linux project.", "It seems like they enjoy breaking other people's code.", ].join "\n" unless manifest s.name = name s.version = version if version s.summary = summary s.email = email s.homepage = homepage || urls["home"] || urls.values.first s.description = description s.files = manifest s.bindir = bindir || "bin" s.executables = s.files.grep(/^#{s.bindir}/) { |f| File.basename(f) } s.require_paths = dirs unless dirs.empty? s. = ["--main", readme_file] s. = s. = (urls.keys & URLS_TO_META_MAP.keys).map { |name| [URLS_TO_META_MAP[name], urls[name]] }.to_h if urls missing "Manifest.txt" if s.files.empty? case when Array s. = else s. = end s.extra_rdoc_files += s.files.grep(/\.(txt|rdoc|md)$/) s.extra_rdoc_files.reject! { |f| f =~ %r%^(test|spec|vendor|template|data|tmp)/% } s.extra_rdoc_files += @extra_rdoc_files end check_for_version if licenses.empty? warn "Defaulting gemspec to MIT license." warn "Call license in hoe spec to change." license "MIT" end spec.licenses = licenses run_spec_extras end |
#dependency(name, version, type = :runtime) ⇒ Object
Add a dependency declaration to your spec. Pass :dev to type
for developer dependencies.
468 469 470 471 472 473 474 475 476 477 478 479 |
# File 'lib/hoe.rb', line 468 def dependency name, version, type = :runtime raise "Unknown dependency type: #{type}" unless [:runtime, :dev, :development, :developer].include? type ary = if type == :runtime then extra_deps else extra_dev_deps end ary << [name, version] end |
#dependency_target ⇒ Object
Returns the proper dependency list for the thingy.
516 517 518 |
# File 'lib/hoe.rb', line 516 def dependency_target self.name == "hoe" ? extra_deps : extra_dev_deps end |
#developer(name, email) ⇒ Object
Convenience method to set add to both the author and email fields.
617 618 619 620 |
# File 'lib/hoe.rb', line 617 def developer name, email self. << name self.email << email end |
#have_gem?(name) ⇒ Boolean
Returns true if the gem name
is installed.
625 626 627 628 629 |
# File 'lib/hoe.rb', line 625 def have_gem? name Gem::Specification.find_by_name name.to_s rescue Gem::LoadError false end |
#initialize_plugins ⇒ Object
Run all initialize_* methods for plugins
437 438 439 440 441 442 443 |
# File 'lib/hoe.rb', line 437 def initialize_plugins Hoe.plugins.each do |plugin| msg = "initialize_#{plugin}" warn msg if $DEBUG send msg if self.respond_to? msg end end |
#intuit_values(input) ⇒ Object
Intuit values from the readme and history files.
672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 |
# File 'lib/hoe.rb', line 672 def intuit_values input readme = input .lines .chunk { |l| l[/^(?:=+|#+)/] || "" } .map(&:last) .each_slice(2) .to_h { |k, v| raise "No body for %p section" % [k[0].strip] \ unless v kp = k.map { |s| s.strip.chomp(":").sub(/(?:=+|#+)\s*/, '').downcase }.join("\n") [kp, v.join.strip] } unless readme.empty? then desc = readme.values_at(*description_sections).join("\n\n") summ = desc.split(/\.\s+/).first(summary_sentences).join(". ") self.urls ||= parse_urls(readme.values.first) self.description ||= desc self.summary ||= summ else missing readme_file end self.changes ||= begin h = File.read_utf(history_file) h.split(/^(={2,}|\#{2,})/)[1..2].join.strip rescue missing history_file "" end end |
#license(name) ⇒ Object
Specify a license for your gem.
Call it multiple times if you are releasing under multiple licenses.
460 461 462 |
# File 'lib/hoe.rb', line 460 def license name self.licenses << name.to_s end |
#load_plugin_tasks ⇒ Object
Load activated plugins by calling their define tasks method.
739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 |
# File 'lib/hoe.rb', line 739 def load_plugin_tasks bad = [] $plugin_max = self.class.plugins.map { |s| s.to_s.size }.max self.class.plugins.each do |plugin| warn "define: #{plugin}" if $DEBUG old_tasks = Rake::Task.tasks.dup begin send "define_#{plugin}_tasks" rescue NoMethodError warn "warning: couldn't activate the #{plugin} plugin, skipping" bad << plugin next end (Rake::Task.tasks - old_tasks).each do |task| task.plugin = plugin end end @@plugins -= bad end |
#maybe_load_yaml(path) ⇒ Object
:nodoc:
938 939 940 941 942 943 944 945 946 947 948 |
# File 'lib/hoe.rb', line 938 def maybe_load_yaml path # :nodoc: if File.exist? path then if YAML.respond_to? :safe_load_file then YAML.safe_load_file path, permitted_classes: [Regexp, Symbol] else YAML.load_file path end else {} end end |
#missing(name) ⇒ Object
Bitch about a file that is missing data or unparsable for intuiting values.
768 769 770 771 |
# File 'lib/hoe.rb', line 768 def missing name warn "** #{name} is missing or in the wrong format for auto-intuiting." warn " run `sow blah` and look at its text files" end |
#normalize_deps(deps) ⇒ Object
Normalize the dependencies.
776 777 778 779 780 781 782 783 784 |
# File 'lib/hoe.rb', line 776 def normalize_deps deps deps = Array(deps) deps.each do |o| abort "ERROR: Add '~> x.y' to the '#{o}' dependency." if String === o end deps end |
#paragraphs_of(path, *paragraphs) ⇒ Object
Reads a file at path
and spits out an array of the paragraphs
specified.
changes = p.paragraphs_of('History.txt', 0..1).join("\n\n")
summary, *description = p.paragraphs_of('README.txt', 3, 3..8)
792 793 794 |
# File 'lib/hoe.rb', line 792 def paragraphs_of path, *paragraphs File.read_utf(path).delete("\r").split(/\n\n+/).values_at(*paragraphs) end |
#parse_urls(text) ⇒ Object
Parse the urls section of the readme file. Returns a hash or an array depending on the format of the section.
label1 :: url1
label2 :: url2
label3 :: url3
vs:
* url1
* url2
* url3
The hash format is preferred as it will be used to populate gem metadata. The array format will work, but will warn that you should update the readme.
726 727 728 729 730 731 732 733 734 |
# File 'lib/hoe.rb', line 726 def parse_urls text lines = text.gsub(/^\* /, "").delete("<>").split(/\n/).grep(/\S+/) if lines.first =~ /::/ then Hash[lines.map { |line| line.split(/\s*::\s*/) }] else raise "Please switch readme to hash format for urls." end end |
#pluggable! ⇒ Object
Tell the world you’re a pluggable package (ie you require rubygems 1.3.1+)
This uses require_rubygems_version. Last one wins. Make sure you account for that.
802 803 804 805 |
# File 'lib/hoe.rb', line 802 def pluggable! abort "update rubygems to >= 1.3.1" unless Gem.respond_to? :find_files require_rubygems_version ">= 1.3.1" end |
#plugin?(name) ⇒ Boolean
817 818 819 |
# File 'lib/hoe.rb', line 817 def plugin? name self.class.plugins.include? name end |
#post_initialize ⇒ Object
Finalize configuration
824 825 826 827 828 829 830 831 832 833 |
# File 'lib/hoe.rb', line 824 def post_initialize activate_plugin_deps unless skip_intuit_values? intuit_values File.read_utf readme_file if readme_file end validate_fields define_spec load_plugin_tasks add_dependencies end |
#read_manifest ⇒ Object
Reads Manifest.txt and returns an Array of lines in the manifest.
Returns nil if no manifest was found.
840 841 842 |
# File 'lib/hoe.rb', line 840 def read_manifest File.read_utf("Manifest.txt").split(/\r?\n\r?/) rescue nil end |
#require_ruby_version(*versions) ⇒ Object
Declare that your gem requires a specific ruby version. Last one wins.
854 855 856 |
# File 'lib/hoe.rb', line 854 def require_ruby_version *versions spec_extras[:required_ruby_version] = versions end |
#require_rubygems_version(*versions) ⇒ Object
Declare that your gem requires a specific rubygems version. Last one wins.
847 848 849 |
# File 'lib/hoe.rb', line 847 def require_rubygems_version *versions spec_extras[:required_rubygems_version] = versions end |
#ruby20! ⇒ Object
Declare that this gem requires ruby to be in the 2.0+ family.
861 862 863 |
# File 'lib/hoe.rb', line 861 def ruby20! require_ruby_version "~> 2.0" end |
#ruby21! ⇒ Object
Declare that this gem requires ruby to be in the 2.1+ family.
868 869 870 |
# File 'lib/hoe.rb', line 868 def ruby21! require_ruby_version "~> 2.1" end |
#ruby22! ⇒ Object
Declare that this gem requires ruby to be in the 2.2+ family.
875 876 877 |
# File 'lib/hoe.rb', line 875 def ruby22! require_ruby_version "~> 2.2" end |
#ruby23! ⇒ Object
Declare that this gem requires ruby to be in the 2.3+ family.
882 883 884 |
# File 'lib/hoe.rb', line 882 def ruby23! require_ruby_version "~> 2.3" end |
#run_spec_extras ⇒ Object
:nodoc:
602 603 604 605 606 607 608 609 610 611 612 |
# File 'lib/hoe.rb', line 602 def run_spec_extras # :nodoc: # Do any extra stuff the user wants self.spec_extras.each do |msg, val| case val when Proc val.call spec.send(msg) else spec.send "#{msg}=", val end end end |
#skip_intuit_values? ⇒ Boolean
:nodoc:
914 915 916 |
# File 'lib/hoe.rb', line 914 def skip_intuit_values? # :nodoc: %w[summary description homepage].all? { |field| send field } end |
#timebomb(n, m, finis = nil, start = nil) ⇒ Object
Provide a linear degrading value from n to m over start to finis dates. If not provided, start and finis will default to 1/1 and 12/31 of the current year.
894 895 896 897 898 899 900 901 902 |
# File 'lib/hoe.rb', line 894 def timebomb n, m, finis = nil, start = nil require "time" finis = Time.parse(finis || "#{Time.now.year}-12-31") start = Time.parse(start || "#{Time.now.year}-01-01") rest = (finis - Time.now) full = (finis - start) [((n - m) * rest / full).to_i + m, m].max end |
#validate_fields ⇒ Object
Verify that mandatory fields are set.
907 908 909 910 911 912 |
# File 'lib/hoe.rb', line 907 def validate_fields %w[email author].each do |field| value = self.send(field) abort "Hoe #{field} value not set. aborting" if value.nil? or value.empty? end end |
#with_config {|config, rc| ... } ⇒ Object
Loads ~/.hoerc, merges it with a .hoerc in the current pwd (if any) and yields the configuration and its path
922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 |
# File 'lib/hoe.rb', line 922 def with_config config = Hoe::DEFAULT_CONFIG rc = File.("~/.hoerc") homeconfig = maybe_load_yaml rc config = config.merge homeconfig localrc = File.join Dir.pwd, ".hoerc" localconfig = maybe_load_yaml(localrc) config = config.merge localconfig yield config, rc end |