Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add bisect_gemfile_parser script #7

Open
wants to merge 10 commits into
base: master
Choose a base branch
from

Conversation

NickLaMuro
Copy link
Owner

@NickLaMuro NickLaMuro commented Jun 29, 2018

This is a helper for running a bisect when having to deal with "point in time" issues when bisecting and dealing with git-gems

Because our Gemfile use the most recent version of the gem when running a bundle and/or bundle update, when attempting to do a git bistect, dependecies that might be causing the issue are not being checked out in a fashion that represents what the state of things were in the MIQ environment at the point of the checkout.

This helper attempts to checkout a proper revision of all of the manageiq git gem dependencies by checking the current revision of the gems in the currently parse Gemfile, and throws a override file in the bundler.d/ directory which will set the proper overrides.

Usage

The workflow for using this script is as follows;

  1. Start git bisect
  2. Run the script
    • you can actually chuck this in bin/ since it is git-ignored)
  3. Run bin/bundle update
  4. Do what you need to validate the git sha, and move on the the next commit
  5. Repeat steps 2-4 until you are finished
  6. Run rm bundle.d/bisect.rb to clean up this script (DON'T FORGET!)

The last step is important as it will most likely mess with your your master branch.

Example Output

Here is an example bundle.d/bisect.rb output for a given run:

require "shellwords"
require "time"

class Bundler::Source::Git::GitProxy
  private

  def find_local_revision
    allowed_in_path do
      if ref.include?("@")
        branch, timestamp = ref.split("@")
        git("log --format='%H' --before=#{timestamp.gsub(/[\{\}]/,"")} --merges -n1 #{branch}").strip
      else
        git("rev-parse --verify #{Shellwords.shellescape(ref)}", true).strip
      end
    end
  end
end

bisect_iso_time = `git show -q --format="%ai"`.chomp
# Time in "hours ago".
#   example:  "100.hours.ago"
bisect_time = "#{(Time.now.to_i - Time.parse(bisect_iso_time).to_i) / 60 / 60}.hours.ago"

override_gem 'manageiq-gems-pending', :git => 'https://github.com/ManageIQ/manageiq-gems-pending', :ref => "fine@{#{bisect_time}}"
override_gem 'manageiq-content', :git => 'https://github.com/ManageIQ/manageiq-content', :ref => "fine@{#{bisect_time}}"
override_gem 'manageiq-providers-amazon', :git => 'https://github.com/ManageIQ/manageiq-providers-amazon', :ref => "fine@{#{bisect_time}}"
override_gem 'manageiq-providers-azure', :git => 'https://github.com/ManageIQ/manageiq-providers-azure', :ref => "fine@{#{bisect_time}}"
override_gem 'manageiq-providers-vmware', :git => 'https://github.com/ManageIQ/manageiq-providers-vmware', :ref => "fine@{#{bisect_time}}"
override_gem 'manageiq-ui-classic', :git => 'https://github.com/ManageIQ/manageiq-ui-classic', :ref => "fine@{#{bisect_time}}"
override_gem 'manageiq-providers-lenovo', :git => 'https://github.com/ManageIQ/manageiq-providers-lenovo', :ref => "fine@{#{bisect_time}}"

TODO

  • Consider searching for "merge commits" only in the versus any old commit (those are the only ones that matter)
  • Possibly add workflow commands for handling bistect commands, that will run both steps 2 & 3 from the above workflow
  • Possibly add a bisect_gemfile_parser cleanup subcommand to handle the rm bundler.d/bisect.rb portion of things.

@NickLaMuro
Copy link
Owner Author

Not sure if I will commit this now, or do the TODO's as part of this PR, but wanted to get this off of my machine as I am now finding a use for it again.

Repo names can get changed and moved around, so this is a mechanism for
handling that based on the current name being provided in the `gem`
portion of the bundler DSL.
Because otherwise it will bug the S#!% out of me...
Copy link
Contributor

@kbrock kbrock left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

still not 100% show to use but it looks cool

GemfilePluginParser.parse.each do |manageiq_plugin|
override_gem_content = "override_gem '#{manageiq_plugin}', "
override_gem_content << ":git => 'https://github.com/ManageIQ/#{KNOWN_REPO_CHANGES[manageiq_plugin] || manageiq_plugin}', "
override_gem_content << ":ref => \"master@{\#{bisect_time}}\""
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you use branch up above, can you use that same thing here?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What I am thinking for this is I would probably use --branch flag to allow you to change the branch. I think the branch you are referring to is the from parsing the master@ part, so that would be coming from this line.

I am sure there are ways to "git" it from git itself, but chances are you would be bisecting this from a specific branch anyway, so a flag is probably okay to use and just default it to master otherwise.

@NickLaMuro
Copy link
Owner Author

still not 100% show to use but it looks cool

@kbrock Grammatical errors aside, what can I improve to make this easier to use? Tried to include some documentation in the script itself (which is just what I ended up using for the PR description), but wouldn't mind hearing suggestions on what I can do to make this more clear.

Previously, we were using `git` to generate the friendly timestamp for
us to use in a commit.  Specifically, it would generate something like
the examples below:

    2.minutes.ago
    5.hours.ago
    3.weeks.ago
    1.month.ago

But the farther back in time we go, the less precision we have, so we
end up with the same repo commits after a while.

This change updates the code to figure out the "time ago" in hours, so
that we are always using relatively usable precision, without being too
precise.

Note:  Curious if it makes sense just to use seconds, and avoid the
conversion to hours.  Might make the commits more stable, but unsure.
Since the only relevant commits we care about in the case of this parser
is the merge commits, make sure we are using those determining the
commit to use in the `bundler.d/bisect.rb`.

This is because the only difference that will be observed by the
manageiq repo normally will be the merge commits, so referencing other
commits will only put the bisecting into a weird state.
Instead of using the --branches=flag, which is meant to accept a
pattern, use the optional argument of `<revision-range>` for git-log to
filter by the branch.
Previously, we were always using 'master' for the branch when building
the `override_gem` line.

This doesn't make sense when bisecting in a release branch, so use the
branch for the plugin if it has one provided (it should, since that is
our convention for release branches).
This method is a slight alternative to #override_gem, as it is meant to
also remove the git_source from `@source` so there isn't duplicate git
fetch calls happening:  once for the original gem that was removed, and
once for the new dependency that was use as the override.

I hope to introduce this into the main repo, but since that won't exist
in previous versions, this should be fine for now.

Examples
--------

(`<<<` signifies a duplicate)

**Before**

    $ bin/bundle update
    Fetching https://github.com/ManageIQ/handsoap.git
    Fetching https://github.com/ManageIQ/rubywbem.git
    Fetching https://github.com/ManageIQ/foreman_api_client.git
    Fetching https://github.com/ManageIQ/ruport.git
    Fetching https://github.com/ManageIQ/jquery-rjs.git
    Fetching https://github.com/ManageIQ/manageiq-gems-pending
    Fetching https://github.com/ManageIQ/manageiq-content
    Fetching https://github.com/ManageIQ/manageiq-providers-amazon
    Fetching https://github.com/ManageIQ/manageiq-providers-azure
    Fetching https://github.com/ManageIQ/manageiq-providers-vmware
    Fetching https://github.com/ManageIQ/manageiq-ui-classic
    Fetching https://github.com/ManageIQ/manageiq-providers-lenovo
    Fetching https://github.com/ManageIQ/manageiq-providers-lenovo  <<<
    Fetching https://github.com/ManageIQ/manageiq-ui-classic        <<<
    Fetching https://github.com/ManageIQ/manageiq-providers-vmware  <<<
    Fetching https://github.com/ManageIQ/manageiq-providers-azure   <<<
    Fetching https://github.com/ManageIQ/manageiq-providers-amazon  <<<
    Fetching https://github.com/ManageIQ/manageiq-content           <<<

**After**

    $ bin/bundle update
    Fetching https://github.com/ManageIQ/handsoap.git
    Fetching https://github.com/ManageIQ/rubywbem.git
    Fetching https://github.com/ManageIQ/foreman_api_client.git
    Fetching https://github.com/ManageIQ/ruport.git
    Fetching https://github.com/ManageIQ/jquery-rjs.git
    Fetching https://github.com/ManageIQ/manageiq-gems-pending
    Fetching https://github.com/ManageIQ/manageiq-content
    Fetching https://github.com/ManageIQ/manageiq-providers-amazon
    Fetching https://github.com/ManageIQ/manageiq-providers-azure
    Fetching https://github.com/ManageIQ/manageiq-providers-vmware
    Fetching https://github.com/ManageIQ/manageiq-ui-classic
    Fetching https://github.com/ManageIQ/manageiq-providers-lenovo
@NickLaMuro NickLaMuro force-pushed the bisect_gemfile_parser branch from 833a88a to ffe7920 Compare October 3, 2018 00:55
Currently only has a `Troubleshooting` section, but probably should also
have some usage instructions with it as well... so TODO...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants