diff --git a/hex/lib/dependabot/hex/file_updater/mixfile_sanitizer.rb b/hex/lib/dependabot/hex/file_updater/mixfile_sanitizer.rb index c3912b389e0..75b46f66c04 100644 --- a/hex/lib/dependabot/hex/file_updater/mixfile_sanitizer.rb +++ b/hex/lib/dependabot/hex/file_updater/mixfile_sanitizer.rb @@ -11,16 +11,40 @@ def initialize(mixfile_content:) @mixfile_content = mixfile_content end + FILE_READ = /File.read\(.*?\)/.freeze + FILE_READ_BANG = /File.read!\(.*?\)/.freeze + PIPE = Regexp.escape("|>").freeze + VERSION_FILE = /"VERSION"/i.freeze + + NESTED_VERSION_FILE_READ = /String\.trim\(#{FILE_READ}\)/.freeze + NESTED_VERSION_FILE_READ_BANG = /String\.trim\(#{FILE_READ_BANG}\)/.freeze + PIPED_VERSION_FILE_READ = + /#{VERSION_FILE}[[:space:]]+#{PIPE}[[:space:]]+#{FILE_READ}/.freeze + PIPED_VERSION_FILE_READ_BANG = + /#{VERSION_FILE}[[:space:]]+#{PIPE}[[:space:]]+#{FILE_READ_BANG}/.freeze + def sanitized_content mixfile_content. - gsub(/File\.read!\(.*?\)/, '"0.0.1"'). - gsub(/File\.read\(.*?\)/, '{:ok, "0.0.1"}'). - gsub(/^\s*config_path:.*(?:,|$)/, "") + yield_self(&method(:prevent_version_file_loading)). + yield_self(&method(:prevent_config_path_loading)) end private attr_reader :mixfile_content + + def prevent_version_file_loading(configuration) + configuration. + gsub(NESTED_VERSION_FILE_READ_BANG, 'String.trim("0.0.1")'). + gsub(NESTED_VERSION_FILE_READ, 'String.trim({:ok, "0.0.1"})'). + gsub(PIPED_VERSION_FILE_READ, '{:ok, "0.0.1"}'). + gsub(PIPED_VERSION_FILE_READ_BANG, '"0.0.1"') + end + + def prevent_config_path_loading(configuration) + configuration. + gsub(/^\s*config_path:.*(?:,|$)/, "") + end end end end diff --git a/hex/spec/dependabot/hex/update_checker/file_preparer_spec.rb b/hex/spec/dependabot/hex/update_checker/file_preparer_spec.rb index 5f3d7112520..5d4d8982d47 100644 --- a/hex/spec/dependabot/hex/update_checker/file_preparer_spec.rb +++ b/hex/spec/dependabot/hex/update_checker/file_preparer_spec.rb @@ -107,6 +107,24 @@ to include('@version String.trim({:ok, "0.0.1"})') end end + + context "when file loading is done with pipes" do + let(:mixfile_fixture_name) { "loads_file_with_pipes" } + + it "removes the call to load the file" do + expect(prepared_mixfile.content). + to include('@version {:ok, "0.0.1"} |> String.trim()') + end + end + + context "when file loading is done with pipes and a !" do + let(:mixfile_fixture_name) { "loads_file_with_pipes_and_bang" } + + it "removes the call to load the file" do + expect(prepared_mixfile.content). + to include('@version "0.0.1" |> String.trim()') + end + end end context "with unlock_requirement set to false" do diff --git a/hex/spec/fixtures/mixfiles/loads_file_with_pipes b/hex/spec/fixtures/mixfiles/loads_file_with_pipes new file mode 100644 index 00000000000..2997b94ecff --- /dev/null +++ b/hex/spec/fixtures/mixfiles/loads_file_with_pipes @@ -0,0 +1,26 @@ +defmodule DependabotTest.Mixfile do + use Mix.Project + + @version "VERSION" |> File.read() |> String.trim() + + def project do + [ + app: :dependabot_test, + version: @version, + elixir: "~> 1.5", + start_permanent: Mix.env == :prod, + deps: deps() + ] + end + + def application do + [extra_applications: [:logger]] + end + + defp deps do + [ + {:plug, "1.3.0"}, + {:phoenix, "== 1.2.1"} + ] + end +end diff --git a/hex/spec/fixtures/mixfiles/loads_file_with_pipes_and_bang b/hex/spec/fixtures/mixfiles/loads_file_with_pipes_and_bang new file mode 100644 index 00000000000..d51972751de --- /dev/null +++ b/hex/spec/fixtures/mixfiles/loads_file_with_pipes_and_bang @@ -0,0 +1,26 @@ +defmodule DependabotTest.Mixfile do + use Mix.Project + + @version "VERSION" |> File.read!() |> String.trim() + + def project do + [ + app: :dependabot_test, + version: @version, + elixir: "~> 1.5", + start_permanent: Mix.env == :prod, + deps: deps() + ] + end + + def application do + [extra_applications: [:logger]] + end + + defp deps do + [ + {:plug, "1.3.0"}, + {:phoenix, "== 1.2.1"} + ] + end +end