diff --git a/.hoerc b/.hoerc index 54c813cf5f..21b93e7b13 100644 --- a/.hoerc +++ b/.hoerc @@ -2,45 +2,46 @@ --- # this regex is what `rake check_manifest` should consider excluded from the gem exclude: !ruby/regexp '/ -(^\.\/ - ((\.git - |.vagrant - |.yardoc - |concourse - |gems - |ports - |suppressions - |rakelib - |test - |tmp - )\/) - |\.(autotest - |cross_rubies - |editorconfig - |gemtest - |github - |gitignore - |hoerc - |travis\.yml - ) - |Gemfile.* - |Manifest.txt - |Rakefile - |appveyor\.yml - |CHANGELOG.md - |CODE_OF_CONDUCT.md - |CONTRIBUTING.md - |ROADMAP.md - |SECURITY.md - |STANDARD_RESPONSES.md - |Vagrantfile - |Y_U_NO_GEMSPEC.md - |C_CODING_STYLE.* - |h1-.* - |[0-9][0-9][0-9][0-9]-.* - |scripts - |sorbet - |patches +(^\.\/(\.git| + \.github| + \.vagrant| + \.yardoc| + concourse| + gems| + patches| + ports| + pkg| + suppressions| + rakelib| + scripts| + sorbet| + test| + tmp + )\/ + | (\.autotest| + \.cross_rubies| + \.editorconfig| + \.gemtest| + \.gitignore| + \.hoerc| + \.travis\.yml| + appveyor\.yml| + CHANGELOG\.md| + CODE_OF_CONDUCT\.md| + CONTRIBUTING\.md| + C_CODING_STYLE\.rdoc| + Gemfile.*| + Manifest\.txt| + ROADMAP\.md| + Rakefile| + SECURITY\.md| + STANDARD_RESPONSES\.md| + Vagrantfile| + Y_U_NO_GEMSPEC\.md| + [0-9]+-.*| + [a-z\.]+\.(log|out) + )$ ) -|\.gitkeep +| +(.*\/nokogiri\.(so|bundle))$ /x' diff --git a/Manifest.txt b/Manifest.txt index d2a6b213ff..6114810f4b 100644 --- a/Manifest.txt +++ b/Manifest.txt @@ -188,6 +188,8 @@ lib/nokogiri/html/sax/push_parser.rb lib/nokogiri/jruby/dependencies.rb lib/nokogiri/syntax_error.rb lib/nokogiri/version.rb +lib/nokogiri/version/constant.rb +lib/nokogiri/version/info.rb lib/nokogiri/xml.rb lib/nokogiri/xml/attr.rb lib/nokogiri/xml/attribute_decl.rb diff --git a/Rakefile b/Rakefile index ce4dfc0c5d..2ff3f3cab0 100644 --- a/Rakefile +++ b/Rakefile @@ -7,8 +7,11 @@ Hoe.plugin :git Hoe.plugin :markdown require_relative "rakelib/util" +require_relative "lib/nokogiri/version/constant" HOE = Hoe.spec "nokogiri" do |hoe| + hoe.version = Nokogiri::VERSION + hoe.author = [ "Mike Dalessio", "Aaron Patterson", diff --git a/concourse/tasks/gem-test/gem-build.sh b/concourse/tasks/gem-test/gem-build.sh index 0a86c3b388..12d243ee2d 100755 --- a/concourse/tasks/gem-test/gem-build.sh +++ b/concourse/tasks/gem-test/gem-build.sh @@ -25,13 +25,7 @@ bundle install --local || bundle install bundle exec rake set-version-to-timestamp if [ -n "${BUILD_NATIVE_GEM:-}" ] ; then - # TODO remove after https://github.com/rake-compiler/rake-compiler/pull/171 is shipped - find /usr/local/rvm/gems -name extensiontask.rb | while read f ; do - echo "rewriting $f" - sudo sed -i 's/callback.call(spec) if callback/@cross_compiling.call(spec) if @cross_compiling/' $f - done - - bundle exec rake gem:x86_64-linux:guest + bundle exec rake gem:x86_64-linux:builder FORCE_CROSS_COMPILING=true else # TODO we're only compiling so that we retrieve libxml2/libxslt # tarballs, we can do better a couple of different ways diff --git a/lib/nokogiri/version.rb b/lib/nokogiri/version.rb index 6500e34f29..1637b2ce51 100644 --- a/lib/nokogiri/version.rb +++ b/lib/nokogiri/version.rb @@ -1,155 +1,3 @@ # frozen_string_literal: true -module Nokogiri - # The version of Nokogiri you are using - VERSION = "1.11.0.rc3" - - class VersionInfo # :nodoc: - def jruby? - ::JRUBY_VERSION if RUBY_PLATFORM == "java" - end - - def engine - defined?(RUBY_ENGINE) ? RUBY_ENGINE : "mri" - end - - def loaded_libxml_version - Gem::Version.new(LIBXML_LOADED_VERSION. - scan(/^(\d+)(\d\d)(\d\d)(?!\d)/).first. - collect(&:to_i). - join(".")) - end - - def compiled_libxml_version - Gem::Version.new LIBXML_COMPILED_VERSION - end - - def loaded_libxslt_version - Gem::Version.new(LIBXSLT_LOADED_VERSION. - scan(/^(\d+)(\d\d)(\d\d)(?!\d)/).first. - collect(&:to_i). - join(".")) - end - - def compiled_libxslt_version - Gem::Version.new LIBXSLT_COMPILED_VERSION - end - - def libxml2? - defined?(LIBXML_COMPILED_VERSION) - end - - def libxml2_has_iconv? - defined?(LIBXML_ICONV_ENABLED) && LIBXML_ICONV_ENABLED - end - - def libxml2_using_system? - !libxml2_using_packaged? - end - - def libxml2_using_packaged? - NOKOGIRI_USE_PACKAGED_LIBRARIES - end - - def warnings - warnings = [] - - if libxml2? - if compiled_libxml_version != loaded_libxml_version - warnings << "Nokogiri was built against libxml version #{compiled_libxml_version}, but has dynamically loaded #{loaded_libxml_version}" - end - - if compiled_libxslt_version != loaded_libxslt_version - warnings << "Nokogiri was built against libxslt version #{compiled_libxslt_version}, but has dynamically loaded #{loaded_libxslt_version}" - end - end - - warnings - end - - def to_hash - {}.tap do |vi| - vi["warnings"] = [] - vi["nokogiri"] = Nokogiri::VERSION - vi["ruby"] = {}.tap do |ruby| - ruby["version"] = ::RUBY_VERSION - ruby["platform"] = ::RUBY_PLATFORM - ruby["gem_platform"] = ::Gem::Platform.local.to_s - ruby["description"] = ::RUBY_DESCRIPTION - ruby["engine"] = engine - ruby["jruby"] = jruby? if jruby? - end - - if libxml2? - vi["libxml"] = {}.tap do |libxml| - if libxml2_using_packaged? - libxml["source"] = "packaged" - libxml["patches"] = NOKOGIRI_LIBXML2_PATCHES - else - libxml["source"] = "system" - end - libxml["compiled"] = compiled_libxml_version.to_s - libxml["loaded"] = loaded_libxml_version.to_s - libxml["iconv_enabled"] = libxml2_has_iconv? - end - - vi["libxslt"] = {}.tap do |libxslt| - if libxml2_using_packaged? - libxslt["source"] = "packaged" - libxslt["patches"] = NOKOGIRI_LIBXSLT_PATCHES - else - libxslt["source"] = "system" - end - libxslt["compiled"] = compiled_libxslt_version.to_s - libxslt["loaded"] = loaded_libxslt_version.to_s - end - - vi["warnings"] = warnings - elsif jruby? - vi["xerces"] = Nokogiri::XERCES_VERSION - vi["nekohtml"] = Nokogiri::NEKO_VERSION - end - end - end - - def to_markdown - begin - require "psych" - rescue LoadError - end - require "yaml" - "# Nokogiri (#{Nokogiri::VERSION})\n" + - YAML.dump(to_hash).each_line.map { |line| " #{line}" }.join - end - - # FIXME: maybe switch to singleton? - @@instance = new - @@instance.warnings.each do |warning| - warn "WARNING: #{warning}" - end - def self.instance; @@instance; end - end - - def self.uses_libxml?(requirement = nil) # :nodoc: - return false unless VersionInfo.instance.libxml2? - return true unless requirement - return Gem::Requirement.new(requirement).satisfied_by?(VersionInfo.instance.loaded_libxml_version) - end - - def self.jruby? # :nodoc: - VersionInfo.instance.jruby? - end - - # Ensure constants used in this file are loaded - see #1896 - if Nokogiri.jruby? - require "nokogiri/jruby/dependencies" - end - begin - RUBY_VERSION =~ /(\d+\.\d+)/ - require "nokogiri/#{$1}/nokogiri" - rescue LoadError - require "nokogiri/nokogiri" - end - - # More complete version information about libxml - VERSION_INFO = VersionInfo.instance.to_hash -end +require_relative "version/constant" +require_relative "version/info" diff --git a/lib/nokogiri/version/constant.rb b/lib/nokogiri/version/constant.rb new file mode 100644 index 0000000000..d47b18723d --- /dev/null +++ b/lib/nokogiri/version/constant.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true +module Nokogiri + # The version of Nokogiri you are using + VERSION = "1.11.0.rc3" +end diff --git a/lib/nokogiri/version/info.rb b/lib/nokogiri/version/info.rb new file mode 100644 index 0000000000..90bae8bad9 --- /dev/null +++ b/lib/nokogiri/version/info.rb @@ -0,0 +1,152 @@ +# frozen_string_literal: true +module Nokogiri + class VersionInfo # :nodoc: + def jruby? + ::JRUBY_VERSION if RUBY_PLATFORM == "java" + end + + def engine + defined?(RUBY_ENGINE) ? RUBY_ENGINE : "mri" + end + + def loaded_libxml_version + Gem::Version.new(LIBXML_LOADED_VERSION. + scan(/^(\d+)(\d\d)(\d\d)(?!\d)/).first. + collect(&:to_i). + join(".")) + end + + def compiled_libxml_version + Gem::Version.new LIBXML_COMPILED_VERSION + end + + def loaded_libxslt_version + Gem::Version.new(LIBXSLT_LOADED_VERSION. + scan(/^(\d+)(\d\d)(\d\d)(?!\d)/).first. + collect(&:to_i). + join(".")) + end + + def compiled_libxslt_version + Gem::Version.new LIBXSLT_COMPILED_VERSION + end + + def libxml2? + defined?(LIBXML_COMPILED_VERSION) + end + + def libxml2_has_iconv? + defined?(LIBXML_ICONV_ENABLED) && LIBXML_ICONV_ENABLED + end + + def libxml2_using_system? + !libxml2_using_packaged? + end + + def libxml2_using_packaged? + NOKOGIRI_USE_PACKAGED_LIBRARIES + end + + def warnings + warnings = [] + + if libxml2? + if compiled_libxml_version != loaded_libxml_version + warnings << "Nokogiri was built against libxml version #{compiled_libxml_version}, but has dynamically loaded #{loaded_libxml_version}" + end + + if compiled_libxslt_version != loaded_libxslt_version + warnings << "Nokogiri was built against libxslt version #{compiled_libxslt_version}, but has dynamically loaded #{loaded_libxslt_version}" + end + end + + warnings + end + + def to_hash + {}.tap do |vi| + vi["warnings"] = [] + vi["nokogiri"] = Nokogiri::VERSION + vi["ruby"] = {}.tap do |ruby| + ruby["version"] = ::RUBY_VERSION + ruby["platform"] = ::RUBY_PLATFORM + ruby["gem_platform"] = ::Gem::Platform.local.to_s + ruby["description"] = ::RUBY_DESCRIPTION + ruby["engine"] = engine + ruby["jruby"] = jruby? if jruby? + end + + if libxml2? + vi["libxml"] = {}.tap do |libxml| + if libxml2_using_packaged? + libxml["source"] = "packaged" + libxml["patches"] = NOKOGIRI_LIBXML2_PATCHES + else + libxml["source"] = "system" + end + libxml["compiled"] = compiled_libxml_version.to_s + libxml["loaded"] = loaded_libxml_version.to_s + libxml["iconv_enabled"] = libxml2_has_iconv? + end + + vi["libxslt"] = {}.tap do |libxslt| + if libxml2_using_packaged? + libxslt["source"] = "packaged" + libxslt["patches"] = NOKOGIRI_LIBXSLT_PATCHES + else + libxslt["source"] = "system" + end + libxslt["compiled"] = compiled_libxslt_version.to_s + libxslt["loaded"] = loaded_libxslt_version.to_s + end + + vi["warnings"] = warnings + elsif jruby? + vi["xerces"] = Nokogiri::XERCES_VERSION + vi["nekohtml"] = Nokogiri::NEKO_VERSION + end + end + end + + def to_markdown + begin + require "psych" + rescue LoadError + end + require "yaml" + "# Nokogiri (#{Nokogiri::VERSION})\n" + + YAML.dump(to_hash).each_line.map { |line| " #{line}" }.join + end + + # FIXME: maybe switch to singleton? + @@instance = new + @@instance.warnings.each do |warning| + warn "WARNING: #{warning}" + end + def self.instance; @@instance; end + end + + def self.uses_libxml?(requirement = nil) # :nodoc: + return false unless VersionInfo.instance.libxml2? + return true unless requirement + return Gem::Requirement.new(requirement).satisfied_by?(VersionInfo.instance.loaded_libxml_version) + end + + def self.jruby? # :nodoc: + VersionInfo.instance.jruby? + end + + # Ensure constants used in this file are loaded - see #1896 + if Nokogiri.jruby? + require "nokogiri/jruby/dependencies" + end + begin + RUBY_VERSION =~ /(\d+\.\d+)/ + require "nokogiri/#{$1}/nokogiri" + rescue LoadError + require "nokogiri/nokogiri" + end + + # More complete version information about libxml + VERSION_INFO = VersionInfo.instance.to_hash +end diff --git a/rakelib/cross-ruby.rake b/rakelib/cross-ruby.rake index a40c482783..9b91898f67 100644 --- a/rakelib/cross-ruby.rake +++ b/rakelib/cross-ruby.rake @@ -237,40 +237,49 @@ CROSS_RUBIES.each do |cross_ruby| end namespace "gem" do + def gem_builder(plat) + # use Task#invoke because the pkg/*gem task is defined at runtime + Rake::Task["native:#{plat}"].invoke + Rake::Task["pkg/#{HOE.spec.full_name}-#{Gem::Platform.new(plat).to_s}.gem"].invoke + end + CROSS_RUBIES.find_all { |cr| cr.windows? || cr.linux? }.map(&:platform).uniq.each do |plat| - desc "build native gem for #{plat} platform (host)" + desc "build native gem for #{plat} platform" task plat do - # TODO remove `find` after https://github.com/rake-compiler/rake-compiler/pull/171 is shipped RakeCompilerDock.sh <<~EOT, platform: plat gem install bundler --no-document && bundle && - find /usr/local/rvm/gems -name extensiontask.rb | while read f ; do sudo sed -i 's/callback.call(spec) if callback/@cross_compiling.call(spec) if @cross_compiling/' $f ; done && - rake gem:#{plat}:guest MAKE='nice make -j`nproc`' + rake gem:#{plat}:builder MAKE='nice make -j`nproc`' FORCE_CROSS_COMPILING=true EOT end namespace plat do - desc "build native gem for #{plat} platform (guest)" - task "guest" do - # use Task#invoke because the pkg/*gem task is defined at runtime - Rake::Task["native:#{plat}"].invoke - Rake::Task["pkg/#{HOE.spec.full_name}-#{Gem::Platform.new(plat).to_s}.gem"].invoke + desc "build native gem for #{plat} platform (guest container)" + task "builder" do + gem_builder(plat) end + task "guest" => "builder" # TODO: remove me after this code is on master, temporary backwards compat for CI end end - desc "build a jruby gem" - task "jruby" do - RakeCompilerDock.sh "gem install bundler --no-document && bundle && rake java gem", rubyvm: "jruby" - end - CROSS_RUBIES.find_all { |cr| cr.darwin? }.map(&:platform).uniq.each do |plat| desc "build native gem for #{plat} platform" task plat do - sh "find ~/.gem -name extensiontask.rb | while read f ; do sed -i '' 's/callback.call(spec) if callback/@cross_compiling.call(spec) if @cross_compiling/' \$f ; done" - Rake::Task["native:#{plat}"].invoke - Rake::Task["pkg/#{HOE.spec.full_name}-#{Gem::Platform.new(plat).to_s}.gem"].invoke + sh "rake gem:#{plat}:builder MAKE='nice make -j`nproc`' FORCE_CROSS_COMPILING=true" end + + namespace plat do + desc "build native gem for #{plat} platform (child process)" + task "builder" do + gem_builder(plat) + end + task "guest" => "builder" # TODO: remove me after this code is on master, temporary backwards compat for CI + end + end + + desc "build a jruby gem" + task "jruby" do + RakeCompilerDock.sh "gem install bundler --no-document && bundle && rake java gem", rubyvm: "jruby" end desc "build native gems for windows" @@ -328,6 +337,7 @@ else Rake::ExtensionTask.new("nokogiri", HOE.spec) do |ext| ext.lib_dir = File.join(*['lib', 'nokogiri', ENV['FAT_DIR']].compact) ext.config_options << ENV['EXTOPTS'] + ext.no_native = (ENV["FORCE_CROSS_COMPILING"] == "true") ext.cross_compile = true ext.cross_platform = CROSS_RUBIES.map(&:platform).uniq ext.cross_config_options << "--enable-cross-build" diff --git a/rakelib/set-version-to-timestamp.rake b/rakelib/set-version-to-timestamp.rake index 4a574fa458..11de1784fe 100644 --- a/rakelib/set-version-to-timestamp.rake +++ b/rakelib/set-version-to-timestamp.rake @@ -1,11 +1,17 @@ +# frozen_string_literal: true +desc "Temporarily set Nokogiri::VERSION to a unique timestamp" task "set-version-to-timestamp" do + # this task is used by concourse/tasks/gem-test/gem-build.sh + # to test building, packaging, and installing a Nokogiri gem version = Time.now.strftime("%Y.%m%d.%H%M") - version_file_path = File.join(File.dirname(__FILE__), "..", "lib/nokogiri/version.rb") + version_file_path = File.join(File.dirname(__FILE__), "..", "lib/nokogiri/version/constant.rb") version_file_contents = File.read(version_file_path) - version_file_contents.gsub!(/^\s*VERSION\s*=.*/, "VERSION = \"#{version}\"") + unless version_file_contents.gsub!(/^\s*VERSION\s*=.*/, "VERSION = \"#{version}\"") + raise("Could not hack the VERSION constant") + end - File.open(version_file_path, "w") { |f| f.write version_file_contents } + File.open(version_file_path, "w") { |f| f.write(version_file_contents) } puts "NOTE: wrote version as \"#{version}\"" end