lib/engineyard-serverside/lockfile_parser.rb in engineyard-serverside-1.4.16 vs lib/engineyard-serverside/lockfile_parser.rb in engineyard-serverside-1.5.0
- old
+ new
@@ -1,130 +1,87 @@
require 'yaml'
module EY
module Serverside
class LockfileParser
+ DEFAULT = "1.0.10"
+
def self.default_version
- Parse10::DEFAULT
+ DEFAULT
end
attr_reader :bundler_version, :lockfile_version
def initialize(lockfile_contents)
- @lockfile_version, @bundler_version = Parse106.new(lockfile_contents).parse
+ @contents = lockfile_contents
+ parse
end
- class BaseParser
- def initialize(contents)
- @contents = contents
+ def any_database_adapter?
+ %w[mysql2 mysql do_mysql pg do_postgres].any? do |gem|
+ @contents.index(/^\s+#{gem}\s\([^\)]+\)$/)
end
- def parse
- raise "Unknown lockfile format #{@contents[0,50]}..."
- end
end
- class Parse09 < BaseParser
- DEFAULT = "0.9.26"
+ def parse
+ parse_from_metadata ||
+ parse_from_dependencies ||
+ raise("Malformed or pre bundler-1.0.0 Gemfile.lock: #{@contents[0,50]}...")
+ end
- def parse
- from_yaml = safe_yaml_load(@contents)
- unless from_yaml.is_a?(Hash)
- return super
- end
- bundler_version = from_yaml['specs'].map do |spec|
- # spec is a one-element hash: the key is the gem name, and
- # the value is {"version" => the-version}.
- if spec.keys.first == "bundler"
- spec.values.first["version"]
- end
- end.compact.first
- [:bundler09, bundler_version || DEFAULT]
+ def slice_section(header)
+ if start = @contents.index(/^#{header}/)
+ finish = @contents.index(/(^\S|\Z)/, start + header.length)
+ @contents.slice(start..finish)
+ else
+ ""
end
- def safe_yaml_load(loadable)
- YAML.load(loadable) #won't always raise... soemtimes parses the contents as 1 big string
- rescue ArgumentError, SyntaxError # not yaml
- nil
- end
end
- class Parse10 < Parse09
- DEFAULT = "1.0.10"
+ def parse_from_metadata
+ section = slice_section('METADATA')
- def parse
- unless @contents.index(/^DEPENDENCIES/)
- return super
- end
- dep_section = ""
- in_dependencies_section = false
- @contents.each_line do |line|
- if line =~ /^DEPENDENCIES/
- in_dependencies_section = true
- elsif line =~ /^\S/
- in_dependencies_section = false
- elsif in_dependencies_section
- dep_section << line
- end
- end
-
- unless dep_section.length > 0
- raise "Couldn't parse #{@contents}; exiting"
- exit(1)
- end
-
- result = scan_bundler(dep_section)
- bundler_version = result ? result.last : nil
- version_qualifier = result ? result.first : nil
- [:bundler10, fetch_version(bundler_version, version_qualifier)]
+ if section.empty?
+ return nil
end
- def fetch_version(bundler_version, version_qualifier)
- return bundler_version || DEFAULT unless version_qualifier
+ result = section.scan(/^\s*version:\s*(.*)$/).first
+ @lockfile_version = :bundler10
+ @bundler_version = result ? result.first : DEFAULT
+ end
- case version_qualifier
- when '='
- bundler_version
- when '>='
- Gem::Version.new(bundler_version) > Gem::Version.new(DEFAULT) ? bundler_version : DEFAULT
- when '~>'
- bundler_gem_version = Gem::Version.new(bundler_version)
- recommendation = bundler_gem_version.spermy_recommendation.gsub(/~>\s*(.+)$/, '\1.')
- recommends_default = DEFAULT.index(recommendation) == 0
- default_newer_than_requested = Gem::Version.new(DEFAULT) > bundler_gem_version
- (recommends_default && default_newer_than_requested) ? DEFAULT : bundler_version
- end
- end
+ def parse_from_dependencies
+ section = slice_section('DEPENDENCIES')
- def scan_bundler(dep_section)
- dep_section.scan(/^\s*bundler\s*\((>?=|~>)\s*([^,\)]+)/).first
+ if section.empty?
+ return nil
end
+
+ result = scan_bundler(section)
+ bundler_version = result ? result.last : nil
+ version_qualifier = result ? result.first : nil
+ @lockfile_version = :bundler10
+ @bundler_version = fetch_version(bundler_version, version_qualifier)
end
- class Parse106 < Parse10
- def parse
- unless @contents.index(/^METADATA/)
- return super
- end
- meta_section = ""
- in_meta_section = false
- @contents.each_line do |line|
- if line =~ /^METADATA/
- in_meta_section = true
- elsif line =~ /^\S/
- in_meta_section = false
- elsif in_meta_section
- meta_section << line
- end
- end
+ def fetch_version(bundler_version, version_qualifier)
+ return bundler_version || DEFAULT unless version_qualifier
- unless meta_section.length > 0
- raise "Couldn't parse #{@contents}; exiting"
- exit(1)
- end
-
- result = meta_section.scan(/^\s*version:\s*(.*)$/).first
- bundler_version = result ? result.first : DEFAULT
- [:bundler10, bundler_version]
+ case version_qualifier
+ when '='
+ bundler_version
+ when '>='
+ Gem::Version.new(bundler_version) > Gem::Version.new(DEFAULT) ? bundler_version : DEFAULT
+ when '~>'
+ bundler_gem_version = Gem::Version.new(bundler_version)
+ recommendation = bundler_gem_version.spermy_recommendation.gsub(/~>\s*(.+)$/, '\1.')
+ recommends_default = DEFAULT.index(recommendation) == 0
+ default_newer_than_requested = Gem::Version.new(DEFAULT) > bundler_gem_version
+ (recommends_default && default_newer_than_requested) ? DEFAULT : bundler_version
end
end
+ def scan_bundler(dep_section)
+ dep_section.scan(/^\s*bundler\s*\((>?=|~>)\s*([^,\)]+)/).first
+ end
end
end
end