Move test fixtures to samples/

This commit is contained in:
Joshua Peek
2012-06-22 10:09:24 -05:00
parent b571c47a1c
commit 5521dd08a0
247 changed files with 13 additions and 14 deletions

3
samples/ruby/Capfile Normal file
View File

@@ -0,0 +1,3 @@
load 'deploy'
Dir['vendor/plugins/*/recipes/*.rb'].each { |plugin| load(plugin) }
load 'config/deploy'

3
samples/ruby/Rakefile Normal file
View File

@@ -0,0 +1,3 @@
task :default do
puts "Rake"
end

2
samples/ruby/foo.rb Normal file
View File

@@ -0,0 +1,2 @@
module Foo
end

703
samples/ruby/formula.rb Normal file
View File

@@ -0,0 +1,703 @@
require 'download_strategy'
require 'dependencies'
require 'formula_support'
require 'hardware'
require 'bottles'
require 'extend/fileutils'
require 'patches'
require 'compilers'
# Derive and define at least @url, see Library/Formula for examples
class Formula
include FileUtils
attr_reader :name, :path, :url, :version, :homepage, :specs, :downloader
attr_reader :standard, :unstable, :head
attr_reader :bottle_version, :bottle_url, :bottle_sha1
# The build folder, usually in /tmp.
# Will only be non-nil during the stage method.
attr_reader :buildpath
# Homebrew determines the name
def initialize name='__UNKNOWN__', path=nil
set_instance_variable 'homepage'
set_instance_variable 'url'
set_instance_variable 'bottle_version'
set_instance_variable 'bottle_url'
set_instance_variable 'bottle_sha1'
set_instance_variable 'head'
set_instance_variable 'specs'
set_instance_variable 'standard'
set_instance_variable 'unstable'
if @head and (not @url or ARGV.build_head?)
@url = @head
@version = 'HEAD'
@spec_to_use = @unstable
else
if @standard.nil?
@spec_to_use = SoftwareSpecification.new(@url, @specs)
else
@spec_to_use = @standard
end
end
raise "No url provided for formula #{name}" if @url.nil?
@name = name
validate_variable :name
# If we got an explicit path, use that, else determine from the name
@path = path.nil? ? self.class.path(name) : Pathname.new(path)
# Use a provided version, if any
set_instance_variable 'version'
# Otherwise detect the version from the URL
@version ||= @spec_to_use.detect_version
# Only validate if a version was set; GitHubGistFormula needs to get
# the URL to determine the version
validate_variable :version if @version
CHECKSUM_TYPES.each { |type| set_instance_variable type }
@downloader = download_strategy.new @spec_to_use.url, name, version, @spec_to_use.specs
@bottle_url ||= bottle_base_url + bottle_filename(self) if @bottle_sha1
end
# if the dir is there, but it's empty we consider it not installed
def installed?
return installed_prefix.children.length > 0
rescue
return false
end
def explicitly_requested?
# `ARGV.formulae` will throw an exception if it comes up with an empty list.
# FIXME: `ARGV.formulae` shouldn't be throwing exceptions, see issue #8823
return false if ARGV.named.empty?
ARGV.formulae.include? self
end
def linked_keg
HOMEBREW_REPOSITORY/'Library/LinkedKegs'/@name
end
def installed_prefix
head_prefix = HOMEBREW_CELLAR+@name+'HEAD'
if @version == 'HEAD' || head_prefix.directory?
head_prefix
else
prefix
end
end
def prefix
validate_variable :name
validate_variable :version
HOMEBREW_CELLAR+@name+@version
end
def rack; prefix.parent end
def bin; prefix+'bin' end
def doc; prefix+'share/doc'+name end
def include; prefix+'include' end
def info; prefix+'share/info' end
def lib; prefix+'lib' end
def libexec; prefix+'libexec' end
def man; prefix+'share/man' end
def man1; man+'man1' end
def man2; man+'man2' end
def man3; man+'man3' end
def man4; man+'man4' end
def man5; man+'man5' end
def man6; man+'man6' end
def man7; man+'man7' end
def man8; man+'man8' end
def sbin; prefix+'sbin' end
def share; prefix+'share' end
# configuration needs to be preserved past upgrades
def etc; HOMEBREW_PREFIX+'etc' end
# generally we don't want var stuff inside the keg
def var; HOMEBREW_PREFIX+'var' end
# plist name, i.e. the name of the launchd service
def plist_name; 'homebrew.mxcl.'+name end
def plist_path; prefix+(plist_name+'.plist') end
# Use the @spec_to_use to detect the download strategy.
# Can be overriden to force a custom download strategy
def download_strategy
@spec_to_use.download_strategy
end
def cached_download
@downloader.cached_location
end
# tell the user about any caveats regarding this package, return a string
def caveats; nil end
# any e.g. configure options for this package
def options; [] end
# patches are automatically applied after extracting the tarball
# return an array of strings, or if you need a patch level other than -p1
# return a Hash eg.
# {
# :p0 => ['http://foo.com/patch1', 'http://foo.com/patch2'],
# :p1 => 'http://bar.com/patch2',
# :p2 => ['http://moo.com/patch5', 'http://moo.com/patch6']
# }
# The final option is to return DATA, then put a diff after __END__. You
# can still return a Hash with DATA as the value for a patch level key.
def patches; end
# rarely, you don't want your library symlinked into the main prefix
# see gettext.rb for an example
def keg_only?
self.class.keg_only_reason || false
end
def fails_with? cc
return false if self.class.cc_failures.nil?
cc = Compiler.new(cc) unless cc.is_a? Compiler
return self.class.cc_failures.find do |failure|
next unless failure.compiler == cc.name
failure.build.zero? or failure.build >= cc.build
end
end
# sometimes the clean process breaks things
# skip cleaning paths in a formula with a class method like this:
# skip_clean [bin+"foo", lib+"bar"]
# redefining skip_clean? now deprecated
def skip_clean? path
return true if self.class.skip_clean_all?
to_check = path.relative_path_from(prefix).to_s
self.class.skip_clean_paths.include? to_check
end
# yields self with current working directory set to the uncompressed tarball
def brew
validate_variable :name
validate_variable :version
stage do
begin
patch
# we allow formulas to do anything they want to the Ruby process
# so load any deps before this point! And exit asap afterwards
yield self
rescue Interrupt, RuntimeError, SystemCallError => e
puts if Interrupt === e # don't print next to the ^C
unless ARGV.debug?
%w(config.log CMakeCache.txt).select{|f| File.exist? f}.each do |f|
HOMEBREW_LOGS.install f
puts "#{f} was copied to #{HOMEBREW_LOGS}"
end
raise
end
onoe e.inspect
puts e.backtrace
ohai "Rescuing build..."
if (e.was_running_configure? rescue false) and File.exist? 'config.log'
puts "It looks like an autotools configure failed."
puts "Gist 'config.log' and any error output when reporting an issue."
puts
end
puts "When you exit this shell Homebrew will attempt to finalise the installation."
puts "If nothing is installed or the shell exits with a non-zero error code,"
puts "Homebrew will abort. The installation prefix is:"
puts prefix
interactive_shell self
end
end
end
def == b
name == b.name
end
def eql? b
self == b and self.class.equal? b.class
end
def hash
name.hash
end
def <=> b
name <=> b.name
end
def to_s
name
end
# Standard parameters for CMake builds.
# Using Build Type "None" tells cmake to use our CFLAGS,etc. settings.
# Setting it to Release would ignore our flags.
# Setting CMAKE_FIND_FRAMEWORK to "LAST" tells CMake to search for our
# libraries before trying to utilize Frameworks, many of which will be from
# 3rd party installs.
# Note: there isn't a std_autotools variant because autotools is a lot
# less consistent and the standard parameters are more memorable.
def std_cmake_args
%W[
-DCMAKE_INSTALL_PREFIX=#{prefix}
-DCMAKE_BUILD_TYPE=None
-DCMAKE_FIND_FRAMEWORK=LAST
-Wno-dev
]
end
def self.class_s name
#remove invalid characters and then camelcase it
name.capitalize.gsub(/[-_.\s]([a-zA-Z0-9])/) { $1.upcase } \
.gsub('+', 'x')
end
# an array of all Formula names
def self.names
Dir["#{HOMEBREW_REPOSITORY}/Library/Formula/*.rb"].map{ |f| File.basename f, '.rb' }.sort
end
# an array of all Formula, instantiated
def self.all
map{ |f| f }
end
def self.map
rv = []
each{ |f| rv << yield(f) }
rv
end
def self.each
names.each do |n|
begin
yield Formula.factory(n)
rescue
# Don't let one broken formula break commands. But do complain.
onoe "Formula #{n} will not import."
end
end
end
def inspect
name
end
def self.aliases
Dir["#{HOMEBREW_REPOSITORY}/Library/Aliases/*"].map{ |f| File.basename f }.sort
end
def self.canonical_name name
name = name.to_s if name.kind_of? Pathname
formula_with_that_name = HOMEBREW_REPOSITORY+"Library/Formula/#{name}.rb"
possible_alias = HOMEBREW_REPOSITORY+"Library/Aliases/#{name}"
possible_cached_formula = HOMEBREW_CACHE_FORMULA+"#{name}.rb"
if name.include? "/"
if name =~ %r{(.+)/(.+)/(.+)}
tapd = HOMEBREW_REPOSITORY/"Library/Taps"/"#$1-#$2".downcase
tapd.find_formula do |relative_pathname|
return "#{tapd}/#{relative_pathname}" if relative_pathname.stem.to_s == $3
end if tapd.directory?
end
# Otherwise don't resolve paths or URLs
name
elsif formula_with_that_name.file? and formula_with_that_name.readable?
name
elsif possible_alias.file?
possible_alias.realpath.basename('.rb').to_s
elsif possible_cached_formula.file?
possible_cached_formula.to_s
else
name
end
end
def self.factory name
# If an instance of Formula is passed, just return it
return name if name.kind_of? Formula
# Otherwise, convert to String in case a Pathname comes in
name = name.to_s
# If a URL is passed, download to the cache and install
if name =~ %r[(https?|ftp)://]
url = name
name = Pathname.new(name).basename
target_file = HOMEBREW_CACHE_FORMULA+name
name = name.basename(".rb").to_s
HOMEBREW_CACHE_FORMULA.mkpath
FileUtils.rm target_file, :force => true
curl url, '-o', target_file
require target_file
install_type = :from_url
else
name = Formula.canonical_name(name)
# If name was a path or mapped to a cached formula
if name.include? "/"
require name
# require allows filenames to drop the .rb extension, but everything else
# in our codebase will require an exact and fullpath.
name = "#{name}.rb" unless name =~ /\.rb$/
path = Pathname.new(name)
name = path.stem
install_type = :from_path
target_file = path.to_s
else
# For names, map to the path and then require
require Formula.path(name)
install_type = :from_name
end
end
begin
klass_name = self.class_s(name)
klass = Object.const_get klass_name
rescue NameError
# TODO really this text should be encoded into the exception
# and only shown if the UI deems it correct to show it
onoe "class \"#{klass_name}\" expected but not found in #{name}.rb"
puts "Double-check the name of the class in that formula."
raise LoadError
end
return klass.new(name) if install_type == :from_name
return klass.new(name, target_file)
rescue LoadError
raise FormulaUnavailableError.new(name)
end
def tap
if path.realpath.to_s =~ %r{#{HOMEBREW_REPOSITORY}/Library/Taps/(\w+)-(\w+)}
"#$1/#$2"
else
# remotely installed formula are not mxcl/master but this will do for now
"mxcl/master"
end
end
def self.path name
HOMEBREW_REPOSITORY+"Library/Formula/#{name.downcase}.rb"
end
def mirrors; self.class.mirrors or []; end
def deps; self.class.dependencies.deps; end
def external_deps; self.class.dependencies.external_deps; end
# deps are in an installable order
# which means if a depends on b then b will be ordered before a in this list
def recursive_deps
Formula.expand_deps(self).flatten.uniq
end
def self.expand_deps f
f.deps.map do |dep|
f_dep = Formula.factory dep.to_s
expand_deps(f_dep) << f_dep
end
end
protected
# Pretty titles the command and buffers stdout/stderr
# Throws if there's an error
def system cmd, *args
# remove "boring" arguments so that the important ones are more likely to
# be shown considering that we trim long ohai lines to the terminal width
pretty_args = args.dup
pretty_args.delete "--disable-dependency-tracking" if cmd == "./configure" and not ARGV.verbose?
ohai "#{cmd} #{pretty_args*' '}".strip
removed_ENV_variables = case if args.empty? then cmd.split(' ').first else cmd end
when "xcodebuild"
ENV.remove_cc_etc
end
if ARGV.verbose?
safe_system cmd, *args
else
rd, wr = IO.pipe
pid = fork do
rd.close
$stdout.reopen wr
$stderr.reopen wr
args.collect!{|arg| arg.to_s}
exec(cmd, *args) rescue nil
exit! 1 # never gets here unless exec threw or failed
end
wr.close
out = ''
out << rd.read until rd.eof?
Process.wait
unless $?.success?
puts out
raise
end
end
removed_ENV_variables.each do |key, value|
ENV[key] = value # ENV.kind_of? Hash # => false
end if removed_ENV_variables
rescue
raise BuildError.new(self, cmd, args, $?)
end
public
# For brew-fetch and others.
def fetch
if install_bottle? self
downloader = CurlBottleDownloadStrategy.new bottle_url, name, version, nil
mirror_list = []
else
downloader = @downloader
# Don't attempt mirrors if this install is not pointed at a "stable" URL.
# This can happen when options like `--HEAD` are invoked.
mirror_list = @spec_to_use == @standard ? mirrors : []
end
# Ensure the cache exists
HOMEBREW_CACHE.mkpath
begin
fetched = downloader.fetch
rescue CurlDownloadStrategyError => e
raise e if mirror_list.empty?
puts "Trying a mirror..."
url, specs = mirror_list.shift.values_at :url, :specs
downloader = download_strategy.new url, name, version, specs
retry
end
return fetched, downloader
end
# Detect which type of checksum is being used, or nil if none
def checksum_type
CHECKSUM_TYPES.detect { |type| instance_variable_defined?("@#{type}") }
end
# For FormulaInstaller.
def verify_download_integrity fn, *args
require 'digest'
if args.length != 2
type = checksum_type || :md5
supplied = instance_variable_get("@#{type}")
# Convert symbol to readable string
type = type.to_s.upcase
else
supplied, type = args
end
hasher = Digest.const_get(type)
hash = fn.incremental_hash(hasher)
if supplied and not supplied.empty?
message = <<-EOF
#{type} mismatch
Expected: #{supplied}
Got: #{hash}
Archive: #{fn}
(To retry an incomplete download, remove the file above.)
EOF
raise message unless supplied.upcase == hash.upcase
else
opoo "Cannot verify package integrity"
puts "The formula did not provide a download checksum"
puts "For your reference the #{type} is: #{hash}"
end
end
private
CHECKSUM_TYPES=[:md5, :sha1, :sha256].freeze
def stage
fetched, downloader = fetch
verify_download_integrity fetched if fetched.kind_of? Pathname
mktemp do
downloader.stage
# Set path after the downloader changes the working folder.
@buildpath = Pathname.pwd
yield
@buildpath = nil
end
end
def patch
patch_list = Patches.new(patches)
return if patch_list.empty?
if patch_list.external_patches?
ohai "Downloading patches"
patch_list.download!
end
ohai "Patching"
patch_list.each do |p|
case p.compression
when :gzip then safe_system "/usr/bin/gunzip", p.compressed_filename
when :bzip2 then safe_system "/usr/bin/bunzip2", p.compressed_filename
end
# -f means don't prompt the user if there are errors; just exit with non-zero status
safe_system '/usr/bin/patch', '-f', *(p.patch_args)
end
end
def validate_variable name
v = instance_variable_get("@#{name}")
raise "Invalid @#{name}" if v.to_s.empty? or v =~ /\s/
end
def set_instance_variable(type)
return if instance_variable_defined? "@#{type}"
class_value = self.class.send(type)
instance_variable_set("@#{type}", class_value) if class_value
end
def self.method_added method
raise 'You cannot override Formula.brew' if method == :brew
end
class << self
# The methods below define the formula DSL.
attr_reader :standard, :unstable
def self.attr_rw(*attrs)
attrs.each do |attr|
class_eval %Q{
def #{attr}(val=nil)
val.nil? ? @#{attr} : @#{attr} = val
end
}
end
end
attr_rw :version, :homepage, :mirrors, :specs
attr_rw :keg_only_reason, :skip_clean_all, :cc_failures
attr_rw :bottle_version, :bottle_url, :bottle_sha1
attr_rw(*CHECKSUM_TYPES)
def head val=nil, specs=nil
return @head if val.nil?
@unstable = SoftwareSpecification.new(val, specs)
@head = val
@specs = specs
end
def url val=nil, specs=nil
return @url if val.nil?
@standard = SoftwareSpecification.new(val, specs)
@url = val
@specs = specs
end
def stable &block
raise "url and md5 must be specified in a block" unless block_given?
instance_eval(&block) unless ARGV.build_devel? or ARGV.build_head?
end
def devel &block
raise "url and md5 must be specified in a block" unless block_given?
if ARGV.build_devel?
@mirrors = nil # clear out mirrors from the stable release
instance_eval(&block)
end
end
def bottle url=nil, &block
return unless block_given?
bottle_block = Class.new do
def self.version version
@version = version
end
def self.url url
@url = url
end
def self.sha1 sha1
case sha1
when Hash
key, value = sha1.shift
@sha1 = key if value == MacOS.cat
when String
@sha1 = sha1 if MacOS.lion?
end
end
def self.data
@version = 0 unless @version
return @version, @url, @sha1 if @sha1 && @url
return @version, nil, @sha1 if @sha1
end
end
bottle_block.instance_eval(&block)
@bottle_version, @bottle_url, @bottle_sha1 = bottle_block.data
end
def mirror val, specs=nil
@mirrors ||= []
@mirrors << {:url => val, :specs => specs}
# Added the uniq after some inspection with Pry---seems `mirror` gets
# called three times. The first two times only one copy of the input is
# left in `@mirrors`. On the final call, two copies are present. This
# happens with `@deps` as well. Odd.
@mirrors.uniq!
end
def dependencies
@dependencies ||= DependencyCollector.new
end
def depends_on dep
dependencies.add(dep)
end
def skip_clean paths
if paths == :all
@skip_clean_all = true
return
end
@skip_clean_paths ||= []
[paths].flatten.each do |p|
@skip_clean_paths << p.to_s unless @skip_clean_paths.include? p.to_s
end
end
def skip_clean_all?
@skip_clean_all
end
def skip_clean_paths
@skip_clean_paths or []
end
def keg_only reason, explanation=nil
@keg_only_reason = KegOnlyReason.new(reason, explanation.to_s.chomp)
end
def fails_with compiler, &block
@cc_failures ||= CompilerFailures.new
@cc_failures << if block_given?
CompilerFailure.new(compiler, &block)
else
CompilerFailure.new(compiler)
end
end
end
end
require 'formula_specialties'

2
samples/ruby/grit.rb Normal file
View File

@@ -0,0 +1,2 @@
module Grit
end

323
samples/ruby/inflector.rb Normal file
View File

@@ -0,0 +1,323 @@
# encoding: utf-8
require 'active_support/inflector/inflections'
module ActiveSupport
# The Inflector transforms words from singular to plural, class names to table names, modularized class names to ones without,
# and class names to foreign keys. The default inflections for pluralization, singularization, and uncountable words are kept
# in inflections.rb.
#
# The Rails core team has stated patches for the inflections library will not be accepted
# in order to avoid breaking legacy applications which may be relying on errant inflections.
# If you discover an incorrect inflection and require it for your application, you'll need
# to correct it yourself (explained below).
module Inflector
extend self
# Returns the plural form of the word in the string.
#
# "post".pluralize # => "posts"
# "octopus".pluralize # => "octopi"
# "sheep".pluralize # => "sheep"
# "words".pluralize # => "words"
# "CamelOctopus".pluralize # => "CamelOctopi"
def pluralize(word)
apply_inflections(word, inflections.plurals)
end
# The reverse of +pluralize+, returns the singular form of a word in a string.
#
# "posts".singularize # => "post"
# "octopi".singularize # => "octopus"
# "sheep".singularize # => "sheep"
# "word".singularize # => "word"
# "CamelOctopi".singularize # => "CamelOctopus"
def singularize(word)
apply_inflections(word, inflections.singulars)
end
# By default, +camelize+ converts strings to UpperCamelCase. If the argument to +camelize+
# is set to <tt>:lower</tt> then +camelize+ produces lowerCamelCase.
#
# +camelize+ will also convert '/' to '::' which is useful for converting paths to namespaces.
#
# "active_model".camelize # => "ActiveModel"
# "active_model".camelize(:lower) # => "activeModel"
# "active_model/errors".camelize # => "ActiveModel::Errors"
# "active_model/errors".camelize(:lower) # => "activeModel::Errors"
#
# As a rule of thumb you can think of +camelize+ as the inverse of +underscore+,
# though there are cases where that does not hold:
#
# "SSLError".underscore.camelize # => "SslError"
def camelize(term, uppercase_first_letter = true)
string = term.to_s
if uppercase_first_letter
string = string.sub(/^[a-z\d]*/) { inflections.acronyms[$&] || $&.capitalize }
else
string = string.sub(/^(?:#{inflections.acronym_regex}(?=\b|[A-Z_])|\w)/) { $&.downcase }
end
string.gsub(/(?:_|(\/))([a-z\d]*)/i) { "#{$1}#{inflections.acronyms[$2] || $2.capitalize}" }.gsub('/', '::')
end
# Makes an underscored, lowercase form from the expression in the string.
#
# Changes '::' to '/' to convert namespaces to paths.
#
# "ActiveModel".underscore # => "active_model"
# "ActiveModel::Errors".underscore # => "active_model/errors"
#
# As a rule of thumb you can think of +underscore+ as the inverse of +camelize+,
# though there are cases where that does not hold:
#
# "SSLError".underscore.camelize # => "SslError"
def underscore(camel_cased_word)
word = camel_cased_word.to_s.dup
word.gsub!('::', '/')
word.gsub!(/(?:([A-Za-z\d])|^)(#{inflections.acronym_regex})(?=\b|[^a-z])/) { "#{$1}#{$1 && '_'}#{$2.downcase}" }
word.gsub!(/([A-Z\d]+)([A-Z][a-z])/,'\1_\2')
word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
word.tr!("-", "_")
word.downcase!
word
end
# Capitalizes the first word and turns underscores into spaces and strips a
# trailing "_id", if any. Like +titleize+, this is meant for creating pretty output.
#
# "employee_salary" # => "Employee salary"
# "author_id" # => "Author"
def humanize(lower_case_and_underscored_word)
result = lower_case_and_underscored_word.to_s.dup
inflections.humans.each { |(rule, replacement)| break if result.sub!(rule, replacement) }
result.gsub!(/_id$/, "")
result.tr!('_', ' ')
result.gsub(/([a-z\d]*)/i) { |match|
"#{inflections.acronyms[match] || match.downcase}"
}.gsub(/^\w/) { $&.upcase }
end
# Capitalizes all the words and replaces some characters in the string to create
# a nicer looking title. +titleize+ is meant for creating pretty output. It is not
# used in the Rails internals.
#
# +titleize+ is also aliased as +titlecase+.
#
# "man from the boondocks".titleize # => "Man From The Boondocks"
# "x-men: the last stand".titleize # => "X Men: The Last Stand"
# "TheManWithoutAPast".titleize # => "The Man Without A Past"
# "raiders_of_the_lost_ark".titleize # => "Raiders Of The Lost Ark"
def titleize(word)
humanize(underscore(word)).gsub(/\b(?<!['`])[a-z]/) { $&.capitalize }
end
# Create the name of a table like Rails does for models to table names. This method
# uses the +pluralize+ method on the last word in the string.
#
# "RawScaledScorer".tableize # => "raw_scaled_scorers"
# "egg_and_ham".tableize # => "egg_and_hams"
# "fancyCategory".tableize # => "fancy_categories"
def tableize(class_name)
pluralize(underscore(class_name))
end
# Create a class name from a plural table name like Rails does for table names to models.
# Note that this returns a string and not a Class. (To convert to an actual class
# follow +classify+ with +constantize+.)
#
# "egg_and_hams".classify # => "EggAndHam"
# "posts".classify # => "Post"
#
# Singular names are not handled correctly:
# "business".classify # => "Busines"
def classify(table_name)
# strip out any leading schema name
camelize(singularize(table_name.to_s.sub(/.*\./, '')))
end
# Replaces underscores with dashes in the string.
#
# "puni_puni".dasherize # => "puni-puni"
def dasherize(underscored_word)
underscored_word.tr('_', '-')
end
# Removes the module part from the expression in the string:
#
# "ActiveRecord::CoreExtensions::String::Inflections".demodulize # => "Inflections"
# "Inflections".demodulize # => "Inflections"
#
# See also +deconstantize+.
def demodulize(path)
path = path.to_s
if i = path.rindex('::')
path[(i+2)..-1]
else
path
end
end
# Removes the rightmost segment from the constant expression in the string:
#
# "Net::HTTP".deconstantize # => "Net"
# "::Net::HTTP".deconstantize # => "::Net"
# "String".deconstantize # => ""
# "::String".deconstantize # => ""
# "".deconstantize # => ""
#
# See also +demodulize+.
def deconstantize(path)
path.to_s[0...(path.rindex('::') || 0)] # implementation based on the one in facets' Module#spacename
end
# Creates a foreign key name from a class name.
# +separate_class_name_and_id_with_underscore+ sets whether
# the method should put '_' between the name and 'id'.
#
# "Message".foreign_key # => "message_id"
# "Message".foreign_key(false) # => "messageid"
# "Admin::Post".foreign_key # => "post_id"
def foreign_key(class_name, separate_class_name_and_id_with_underscore = true)
underscore(demodulize(class_name)) + (separate_class_name_and_id_with_underscore ? "_id" : "id")
end
# Tries to find a constant with the name specified in the argument string:
#
# "Module".constantize # => Module
# "Test::Unit".constantize # => Test::Unit
#
# The name is assumed to be the one of a top-level constant, no matter whether
# it starts with "::" or not. No lexical context is taken into account:
#
# C = 'outside'
# module M
# C = 'inside'
# C # => 'inside'
# "C".constantize # => 'outside', same as ::C
# end
#
# NameError is raised when the name is not in CamelCase or the constant is
# unknown.
def constantize(camel_cased_word)
names = camel_cased_word.split('::')
names.shift if names.empty? || names.first.empty?
names.inject(Object) do |constant, name|
if constant == Object
constant.const_get(name)
else
candidate = constant.const_get(name)
next candidate if constant.const_defined?(name, false)
next candidate unless Object.const_defined?(name)
# Go down the ancestors to check it it's owned
# directly before we reach Object or the end of ancestors.
constant = constant.ancestors.inject do |const, ancestor|
break const if ancestor == Object
break ancestor if ancestor.const_defined?(name, false)
const
end
# owner is in Object, so raise
constant.const_get(name, false)
end
end
end
# Tries to find a constant with the name specified in the argument string:
#
# "Module".safe_constantize # => Module
# "Test::Unit".safe_constantize # => Test::Unit
#
# The name is assumed to be the one of a top-level constant, no matter whether
# it starts with "::" or not. No lexical context is taken into account:
#
# C = 'outside'
# module M
# C = 'inside'
# C # => 'inside'
# "C".safe_constantize # => 'outside', same as ::C
# end
#
# nil is returned when the name is not in CamelCase or the constant (or part of it) is
# unknown.
#
# "blargle".safe_constantize # => nil
# "UnknownModule".safe_constantize # => nil
# "UnknownModule::Foo::Bar".safe_constantize # => nil
#
def safe_constantize(camel_cased_word)
begin
constantize(camel_cased_word)
rescue NameError => e
raise unless e.message =~ /(uninitialized constant|wrong constant name) #{const_regexp(camel_cased_word)}$/ ||
e.name.to_s == camel_cased_word.to_s
rescue ArgumentError => e
raise unless e.message =~ /not missing constant #{const_regexp(camel_cased_word)}\!$/
end
end
# Returns the suffix that should be added to a number to denote the position
# in an ordered sequence such as 1st, 2nd, 3rd, 4th.
#
# ordinal(1) # => "st"
# ordinal(2) # => "nd"
# ordinal(1002) # => "nd"
# ordinal(1003) # => "rd"
# ordinal(-11) # => "th"
# ordinal(-1021) # => "st"
def ordinal(number)
if (11..13).include?(number.to_i.abs % 100)
"th"
else
case number.to_i.abs % 10
when 1; "st"
when 2; "nd"
when 3; "rd"
else "th"
end
end
end
# Turns a number into an ordinal string used to denote the position in an
# ordered sequence such as 1st, 2nd, 3rd, 4th.
#
# ordinalize(1) # => "1st"
# ordinalize(2) # => "2nd"
# ordinalize(1002) # => "1002nd"
# ordinalize(1003) # => "1003rd"
# ordinalize(-11) # => "-11th"
# ordinalize(-1021) # => "-1021st"
def ordinalize(number)
"#{number}#{ordinal(number)}"
end
private
# Mount a regular expression that will match part by part of the constant.
# For instance, Foo::Bar::Baz will generate Foo(::Bar(::Baz)?)?
def const_regexp(camel_cased_word) #:nodoc:
parts = camel_cased_word.split("::")
last = parts.pop
parts.reverse.inject(last) do |acc, part|
part.empty? ? acc : "#{part}(::#{acc})?"
end
end
# Applies inflection rules for +singularize+ and +pluralize+.
#
# apply_inflections("post", inflections.plurals) # => "posts"
# apply_inflections("posts", inflections.singulars) # => "post"
def apply_inflections(word, rules)
result = word.to_s.dup
if word.empty? || inflections.uncountables.include?(result.downcase[/\b\w+\Z/])
result
else
rules.each { |(rule, replacement)| break if result.sub!(rule, replacement) }
result
end
end
end
end

138
samples/ruby/jekyll.rb Normal file
View File

@@ -0,0 +1,138 @@
$:.unshift File.dirname(__FILE__) # For use/testing when no gem is installed
# Require all of the Ruby files in the given directory.
#
# path - The String relative path from here to the directory.
#
# Returns nothing.
def require_all(path)
glob = File.join(File.dirname(__FILE__), path, '*.rb')
Dir[glob].each do |f|
require f
end
end
# rubygems
require 'rubygems'
# stdlib
require 'fileutils'
require 'time'
require 'yaml'
require 'English'
# 3rd party
require 'liquid'
require 'maruku'
require 'albino'
# internal requires
require 'jekyll/core_ext'
require 'jekyll/site'
require 'jekyll/convertible'
require 'jekyll/layout'
require 'jekyll/page'
require 'jekyll/post'
require 'jekyll/filters'
require 'jekyll/static_file'
require 'jekyll/errors'
# extensions
require 'jekyll/plugin'
require 'jekyll/converter'
require 'jekyll/generator'
require_all 'jekyll/converters'
require_all 'jekyll/generators'
require_all 'jekyll/tags'
module Jekyll
VERSION = '0.11.2'
# Default options. Overriden by values in _config.yml or command-line opts.
# (Strings rather symbols used for compatability with YAML).
DEFAULTS = {
'safe' => false,
'auto' => false,
'server' => false,
'server_port' => 4000,
'source' => Dir.pwd,
'destination' => File.join(Dir.pwd, '_site'),
'plugins' => File.join(Dir.pwd, '_plugins'),
'future' => true,
'lsi' => false,
'pygments' => false,
'markdown' => 'maruku',
'permalink' => 'date',
'include' => ['.htaccess'],
'paginate_path' => 'page:num',
'markdown_ext' => 'markdown,mkd,mkdn,md',
'textile_ext' => 'textile',
'maruku' => {
'use_tex' => false,
'use_divs' => false,
'png_engine' => 'blahtex',
'png_dir' => 'images/latex',
'png_url' => '/images/latex'
},
'rdiscount' => {
'extensions' => []
},
'redcarpet' => {
'extensions' => []
},
'kramdown' => {
'auto_ids' => true,
'footnote_nr' => 1,
'entity_output' => 'as_char',
'toc_levels' => '1..6',
'smart_quotes' => 'lsquo,rsquo,ldquo,rdquo',
'use_coderay' => false,
'coderay' => {
'coderay_wrap' => 'div',
'coderay_line_numbers' => 'inline',
'coderay_line_number_start' => 1,
'coderay_tab_width' => 4,
'coderay_bold_every' => 10,
'coderay_css' => 'style'
}
},
'redcloth' => {
'hard_breaks' => true
}
}
# Public: Generate a Jekyll configuration Hash by merging the default
# options with anything in _config.yml, and adding the given options on top.
#
# override - A Hash of config directives that override any options in both
# the defaults and the config file. See Jekyll::DEFAULTS for a
# list of option names and their defaults.
#
# Returns the final configuration Hash.
def self.configuration(override)
# _config.yml may override default source location, but until
# then, we need to know where to look for _config.yml
source = override['source'] || Jekyll::DEFAULTS['source']
# Get configuration from <source>/_config.yml
config_file = File.join(source, '_config.yml')
begin
config = YAML.load_file(config_file)
raise "Invalid configuration - #{config_file}" if !config.is_a?(Hash)
$stdout.puts "Configuration from #{config_file}"
rescue => err
$stderr.puts "WARNING: Could not read configuration. " +
"Using defaults (and options)."
$stderr.puts "\t" + err.to_s
config = {}
end
# Merge DEFAULTS < _config.yml < override
Jekyll::DEFAULTS.deep_merge(config).deep_merge(override)
end
end

2
samples/ruby/macruby-script Executable file
View File

@@ -0,0 +1,2 @@
#!/usr/bin/env macruby
puts "MacRuby"

385
samples/ruby/resque.rb Normal file
View File

@@ -0,0 +1,385 @@
require 'redis/namespace'
require 'resque/version'
require 'resque/errors'
require 'resque/failure'
require 'resque/failure/base'
require 'resque/helpers'
require 'resque/stat'
require 'resque/job'
require 'resque/worker'
require 'resque/plugin'
require 'resque/queue'
require 'resque/multi_queue'
require 'resque/coder'
require 'resque/multi_json_coder'
module Resque
include Helpers
extend self
# Accepts:
# 1. A 'hostname:port' String
# 2. A 'hostname:port:db' String (to select the Redis db)
# 3. A 'hostname:port/namespace' String (to set the Redis namespace)
# 4. A Redis URL String 'redis://host:port'
# 5. An instance of `Redis`, `Redis::Client`, `Redis::DistRedis`,
# or `Redis::Namespace`.
def redis=(server)
case server
when String
if server =~ /redis\:\/\//
redis = Redis.connect(:url => server, :thread_safe => true)
else
server, namespace = server.split('/', 2)
host, port, db = server.split(':')
redis = Redis.new(:host => host, :port => port,
:thread_safe => true, :db => db)
end
namespace ||= :resque
@redis = Redis::Namespace.new(namespace, :redis => redis)
when Redis::Namespace
@redis = server
else
@redis = Redis::Namespace.new(:resque, :redis => server)
end
@queues = Hash.new { |h,name|
h[name] = Resque::Queue.new(name, @redis, coder)
}
end
# Encapsulation of encode/decode. Overwrite this to use it across Resque.
# This defaults to MultiJson for backwards compatibilty.
def coder
@coder ||= MultiJsonCoder.new
end
attr_writer :coder
# Returns the current Redis connection. If none has been created, will
# create a new one.
def redis
return @redis if @redis
self.redis = Redis.respond_to?(:connect) ? Redis.connect : "localhost:6379"
self.redis
end
def redis_id
# support 1.x versions of redis-rb
if redis.respond_to?(:server)
redis.server
elsif redis.respond_to?(:nodes) # distributed
redis.nodes.map { |n| n.id }.join(', ')
else
redis.client.id
end
end
# The `before_first_fork` hook will be run in the **parent** process
# only once, before forking to run the first job. Be careful- any
# changes you make will be permanent for the lifespan of the
# worker.
#
# Call with a block to set the hook.
# Call with no arguments to return the hook.
def before_first_fork(&block)
block ? (@before_first_fork = block) : @before_first_fork
end
# Set a proc that will be called in the parent process before the
# worker forks for the first time.
attr_writer :before_first_fork
# The `before_fork` hook will be run in the **parent** process
# before every job, so be careful- any changes you make will be
# permanent for the lifespan of the worker.
#
# Call with a block to set the hook.
# Call with no arguments to return the hook.
def before_fork(&block)
block ? (@before_fork = block) : @before_fork
end
# Set the before_fork proc.
attr_writer :before_fork
# The `after_fork` hook will be run in the child process and is passed
# the current job. Any changes you make, therefore, will only live as
# long as the job currently being processed.
#
# Call with a block to set the hook.
# Call with no arguments to return the hook.
def after_fork(&block)
block ? (@after_fork = block) : @after_fork
end
# Set the after_fork proc.
attr_writer :after_fork
def to_s
"Resque Client connected to #{redis_id}"
end
attr_accessor :inline
# If 'inline' is true Resque will call #perform method inline
# without queuing it into Redis and without any Resque callbacks.
# The 'inline' is false Resque jobs will be put in queue regularly.
alias :inline? :inline
#
# queue manipulation
#
# Pushes a job onto a queue. Queue name should be a string and the
# item should be any JSON-able Ruby object.
#
# Resque works generally expect the `item` to be a hash with the following
# keys:
#
# class - The String name of the job to run.
# args - An Array of arguments to pass the job. Usually passed
# via `class.to_class.perform(*args)`.
#
# Example
#
# Resque.push('archive', :class => 'Archive', :args => [ 35, 'tar' ])
#
# Returns nothing
def push(queue, item)
queue(queue) << item
end
# Pops a job off a queue. Queue name should be a string.
#
# Returns a Ruby object.
def pop(queue)
begin
queue(queue).pop(true)
rescue ThreadError
nil
end
end
# Returns an integer representing the size of a queue.
# Queue name should be a string.
def size(queue)
queue(queue).size
end
# Returns an array of items currently queued. Queue name should be
# a string.
#
# start and count should be integer and can be used for pagination.
# start is the item to begin, count is how many items to return.
#
# To get the 3rd page of a 30 item, paginatied list one would use:
# Resque.peek('my_list', 59, 30)
def peek(queue, start = 0, count = 1)
queue(queue).slice start, count
end
# Does the dirty work of fetching a range of items from a Redis list
# and converting them into Ruby objects.
def list_range(key, start = 0, count = 1)
if count == 1
decode redis.lindex(key, start)
else
Array(redis.lrange(key, start, start+count-1)).map do |item|
decode item
end
end
end
# Returns an array of all known Resque queues as strings.
def queues
Array(redis.smembers(:queues))
end
# Given a queue name, completely deletes the queue.
def remove_queue(queue)
queue(queue).destroy
@queues.delete(queue.to_s)
end
# Return the Resque::Queue object for a given name
def queue(name)
@queues[name.to_s]
end
#
# job shortcuts
#
# This method can be used to conveniently add a job to a queue.
# It assumes the class you're passing it is a real Ruby class (not
# a string or reference) which either:
#
# a) has a @queue ivar set
# b) responds to `queue`
#
# If either of those conditions are met, it will use the value obtained
# from performing one of the above operations to determine the queue.
#
# If no queue can be inferred this method will raise a `Resque::NoQueueError`
#
# Returns true if the job was queued, nil if the job was rejected by a
# before_enqueue hook.
#
# This method is considered part of the `stable` API.
def enqueue(klass, *args)
enqueue_to(queue_from_class(klass), klass, *args)
end
# Just like `enqueue` but allows you to specify the queue you want to
# use. Runs hooks.
#
# `queue` should be the String name of the queue you're targeting.
#
# Returns true if the job was queued, nil if the job was rejected by a
# before_enqueue hook.
#
# This method is considered part of the `stable` API.
def enqueue_to(queue, klass, *args)
# Perform before_enqueue hooks. Don't perform enqueue if any hook returns false
before_hooks = Plugin.before_enqueue_hooks(klass).collect do |hook|
klass.send(hook, *args)
end
return nil if before_hooks.any? { |result| result == false }
Job.create(queue, klass, *args)
Plugin.after_enqueue_hooks(klass).each do |hook|
klass.send(hook, *args)
end
return true
end
# This method can be used to conveniently remove a job from a queue.
# It assumes the class you're passing it is a real Ruby class (not
# a string or reference) which either:
#
# a) has a @queue ivar set
# b) responds to `queue`
#
# If either of those conditions are met, it will use the value obtained
# from performing one of the above operations to determine the queue.
#
# If no queue can be inferred this method will raise a `Resque::NoQueueError`
#
# If no args are given, this method will dequeue *all* jobs matching
# the provided class. See `Resque::Job.destroy` for more
# information.
#
# Returns the number of jobs destroyed.
#
# Example:
#
# # Removes all jobs of class `UpdateNetworkGraph`
# Resque.dequeue(GitHub::Jobs::UpdateNetworkGraph)
#
# # Removes all jobs of class `UpdateNetworkGraph` with matching args.
# Resque.dequeue(GitHub::Jobs::UpdateNetworkGraph, 'repo:135325')
#
# This method is considered part of the `stable` API.
def dequeue(klass, *args)
# Perform before_dequeue hooks. Don't perform dequeue if any hook returns false
before_hooks = Plugin.before_dequeue_hooks(klass).collect do |hook|
klass.send(hook, *args)
end
return if before_hooks.any? { |result| result == false }
Job.destroy(queue_from_class(klass), klass, *args)
Plugin.after_dequeue_hooks(klass).each do |hook|
klass.send(hook, *args)
end
end
# Given a class, try to extrapolate an appropriate queue based on a
# class instance variable or `queue` method.
def queue_from_class(klass)
klass.instance_variable_get(:@queue) ||
(klass.respond_to?(:queue) and klass.queue)
end
# This method will return a `Resque::Job` object or a non-true value
# depending on whether a job can be obtained. You should pass it the
# precise name of a queue: case matters.
#
# This method is considered part of the `stable` API.
def reserve(queue)
Job.reserve(queue)
end
# Validates if the given klass could be a valid Resque job
#
# If no queue can be inferred this method will raise a `Resque::NoQueueError`
#
# If given klass is nil this method will raise a `Resque::NoClassError`
def validate(klass, queue = nil)
queue ||= queue_from_class(klass)
if !queue
raise NoQueueError.new("Jobs must be placed onto a queue.")
end
if klass.to_s.empty?
raise NoClassError.new("Jobs must be given a class.")
end
end
#
# worker shortcuts
#
# A shortcut to Worker.all
def workers
Worker.all
end
# A shortcut to Worker.working
def working
Worker.working
end
# A shortcut to unregister_worker
# useful for command line tool
def remove_worker(worker_id)
worker = Resque::Worker.find(worker_id)
worker.unregister_worker
end
#
# stats
#
# Returns a hash, similar to redis-rb's #info, of interesting stats.
def info
return {
:pending => queues.inject(0) { |m,k| m + size(k) },
:processed => Stat[:processed],
:queues => queues.size,
:workers => workers.size.to_i,
:working => working.size,
:failed => Stat[:failed],
:servers => [redis_id],
:environment => ENV['RAILS_ENV'] || ENV['RACK_ENV'] || 'development'
}
end
# Returns an array of all known Resque keys in Redis. Redis' KEYS operation
# is O(N) for the keyspace, so be careful - this can be slow for big databases.
def keys
redis.keys("*").map do |key|
key.sub("#{redis.namespace}:", '')
end
end
end

4
samples/ruby/script.rake Executable file
View File

@@ -0,0 +1,4 @@
#!/usr/bin/env rake
task :default do
puts "Rake"
end

2
samples/ruby/script.rb Executable file
View File

@@ -0,0 +1,2 @@
#!/usr/bin/env ruby
puts "Ruby"

2
samples/ruby/script2.rb Normal file
View File

@@ -0,0 +1,2 @@
#! /usr/bin/env ruby -w -Ilib:test
echo "Ruby"

1775
samples/ruby/sinatra.rb Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,2 @@
#!/usr/bin/env python
puts "Not Python"