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

Merge rspec repos #48

Draft
wants to merge 7,766 commits into
base: main
Choose a base branch
from
Draft

Merge rspec repos #48

wants to merge 7,766 commits into from

Conversation

p8
Copy link

@p8 p8 commented Oct 3, 2019

Proof of concept for merging the other repos into this repo while keeping all history (See: rspec/rspec-core#2509).
I had some success with the steps described here (https://thoughts.t37.net/merging-2-different-git-repositories-without-losing-your-history-de7a06bba804

mkdir rspec-mono
cd rspec-mono
git clone [email protected]:rspec/rspec.git
git clone [email protected]:rspec/rspec-core.git
git clone [email protected]:rspec/rspec-expectations.git
git clone [email protected]:rspec/rspec-mocks.git
cd rspec-core
mkdir rspec-core
git mv -k * rspec-core
git rm .gitignore
git rm .document
git commit -m 'Moving repo into its own subdirectory'
cd ..
cd rspec-expectations
mkdir rspec-expectations
git mv -k * rspec-expectations
git rm .gitignore
git rm .document
git rm .rspec
git rm .rubocop.yml
git rm .rubocop_rspec_base.yml
git rm .travis.yml
git rm .yardopts
git commit -m 'Moving repo into its own subdirectory'
cd ..
cd rspec-mocks
mkdir rspec-mocks
git mv -k * rspec-mocks
git rm .gitignore
git rm .document
git rm .rspec
git rm .rubocop.yml
git rm .rubocop_rspec_base.yml
git rm .travis.yml
git rm .yardopts
git commit -m 'Moving repo into its own subdirectory'
cd ..
cd rspec
git remote add rspec-core ../rspec-core
git remote add rspec-expectations ../rspec-expectations
git remote add rspec-mocks ../rspec-mocks
git fetch rspec-core
git fetch rspec-expectations
git fetch rspec-mocks
git co -b merge-rspec-repos
git merge --allow-unrelated-histories rspec-core/master
git merge --allow-unrelated-histories rspec-expectations/master
git merge --allow-unrelated-histories rspec-mocks/master
git commit -m 'Import sub repos'

xaviershay and others added 30 commits January 4, 2018 09:31
Defaulted most new things to off, though tried to keep performance and
linters.
$SAFE became a global variable in Ruby 2.6
* Added @Private tag for nested class (no longer inherits).
* Included full method definition in generated should/should_not docs.
* Used const_set for constant redefinition, since using = confuses YARD.
* Added short descriptions to methods that are @api private. Could
  probably just @Private the lot but didn't want to make that decision
  here.
Update yard to 0.9.12, motivated by CVE.
Upgrade rubocop, motivated by CVE.
* If it quacks like a Hash, treat it like a Hash

* DRY

* Not loaded by default in old Rubies

* Trying to get the build passing...

* No need to put this on Relish

* Not much value to pseudo-hashes allowed as expecteds
Upgrade rubocop, motivated by CVE.
We did not offer it when the BisectFormatter was written but it
nicely simplifies it now.

Also, get the expected failures in `initialize` instead of `start`.
Simplify BisectFormatter using `example_finished` notification.
It is not going to be needed for the ForkRunner, but it will have
its own lifecycle to manage, so `start { }` makes a convenient
interface for both.
Also, rename the bisect formatter to indicate it communicates over DRb.
Also, move it to `utilities` as the server will not always be loaded.
This is useful for when you want to initialize your formatter
with extra state. The simplest approach is for you to instantiate
the formatter yourself instead of depending on RSpec to do it and
trying to update the formatter with your desired state later.
…n_configuration

[#2494] Add yard return values to Rspec::Core::Configuration
Nicely handle errors encountered from processing `--require`.
Use a simple `Notifier` instead of the full-fledged `Reporter`
(which required the use of config). Avoiding config is necessary
for us to be able to use the new forking runner for bisect.
Avoid using `RSpec.configuration` from the bisect coordinator.
@p8
Copy link
Author

p8 commented Jan 28, 2020

@pirj Sorry for the late reply.
I was indeed under the presumption that everything was to be merged in a single gem.
I've changed the script to keep repo's as separate gems in separate folders.
So the folder structure is now similar to the mono-repo-prototype:

mono_repo/
mono_repo/rspec/
mono_repo/rspec/README.md
mono_repo/rspec/lib/
mono_repo/rspec/...
mono_repo/rspec-core
mono_repo/rspec-core/README.md
mono_repo/rspec-core/lib/
mono_repo/rspec-core/...
...

It can now also create branches for different versions.

#!/usr/bin/env ruby

working_dir = 'working'

Repo = Struct.new(:name, :url, :branch)
repos = [
  Repo.new('rspec',              '[email protected]:rspec/rspec.git'),
  Repo.new('rspec-core',         '[email protected]:rspec/rspec-core.git'),
  Repo.new('rspec-expectations', '[email protected]:rspec/rspec-expectations.git'),
  Repo.new('rspec-mocks',        '[email protected]:rspec/rspec-mocks.git'),
  Repo.new('rspec-support',      '[email protected]:rspec/rspec-support.git')
]

# merge everything into the rspec-monorepo-prototype repo for now
mono_repo = Repo.new('rspec-mono', '[email protected]:rspec/rspec-monorepo-prototype.git')

# Clone the mono repo
%x(
  mkdir #{working_dir}
  cd #{working_dir}
  git clone #{mono_repo.url} #{mono_repo.name}
)

# Merge sub repos into the mono repo while keeping the commit history.
# 1bf79d2bf is the initial commit of the mono-repo without the sub repos
# to prevent merge conflicts
%w[v3.8.0 v3.9.0].each do |branch|
  %x(
    cd #{working_dir}
    cd #{mono_repo.name}
    git co 1bf79d2bf
    git co -b #{branch}
  )
  repos.each do |repo|
    repo.branch = branch
    # Check out the sub repo and move all files to a sub directory
    # with the same name as the repo.
    # Merge the sub repo into the mono repo while keeping history.
    %x(
      cd #{working_dir}
      rm -rf #{repo.name}
      git clone #{repo.url} #{repo.name}
      cd #{repo.name}
      mkdir #{repo.name}
      git fetch --tags
      git co -b #{repo.branch} #{repo.branch}
      git mv -k * #{repo.name}
      git mv -k {.[!.]*,..?*} #{repo.name}
      git commit -m 'Moving #{repo.name} into its own subdirectory'
      cd ../#{mono_repo.name}
      git remote add #{repo.name} ../#{repo.name}
      git fetch #{repo.name}
      git merge --allow-unrelated-histories --ff #{repo.name}/#{repo.branch}
    )
    # rspec-expectations and rspec-mocks both moved License.txt to LICENSE.md.
    # Resolve this merge conflict by removing License.txt and adding the
    # LICENSE.md for both sub repos.
    %x(
      cd #{working_dir}
      cd #{mono_repo.name}
      git rm License.txt
      git add rspec-expectations/LICENSE.md
      git add rspec-mocks/LICENSE.md
      git commit -m 'Fix merge conflict'
    )
  end
end

@p8
Copy link
Author

p8 commented Jan 28, 2020

I'll see if I can make a PR for the mono-repo-prototype and get the build running.

@pirj
Copy link
Member

pirj commented Jan 28, 2020

Thanks for pushing this forward!

@p8
Copy link
Author

p8 commented Jan 30, 2020

I can now run the specs for all sub repo's in the rspec-monorepo-protoype:
rspec/rspec-monorepo-prototype#1
Some specs are failing though...

@p8
Copy link
Author

p8 commented Jan 30, 2020

Hmm, weird I'm not seeing Travis in the checks anymore.
Here is a link to a job that ran the specs: https://travis-ci.org/rspec/rspec-monorepo-prototype/jobs/643931521

@pirj
Copy link
Member

pirj commented Jan 30, 2020

Wow, nice, good job!
I actually see a link to a build job in the checks. https://travis-ci.org/rspec/rspec-monorepo-prototype/builds/643953326

@p8
Copy link
Author

p8 commented Jan 30, 2020

Yes, the problem was that my branch could not merge to master.
I now have some green jobs on my fork which used the script mentioned above:
https://travis-ci.org/p8/rspec-monorepo-prototype/builds/643957490

@pirj
Copy link
Member

pirj commented Mar 15, 2020

script/update_rubygems_and_install_bundler: line 8: is_ruby_23_plus: command not found

I guess the problem to the red builds might be this little thing.

@p8
Copy link
Author

p8 commented Mar 17, 2020

Yes, setting the dist to trusty fixes it on travis:
https://github.com/rspec/rspec-monorepo-prototype/pull/1/files

@pirj
Copy link
Member

pirj commented Mar 18, 2020

1.1) Failure/Error: let(:file_1) { File.open(File.join("tmp", "file_1"), "w").tap { |f| f.sync = true } }
          Errno::ENOENT:
            No such file or directory @ rb_sysopen - tmp/file_1

Maybe tmp is not present?

@pirj
Copy link
Member

pirj commented Apr 4, 2020

@p8 Have you had a chance to take a look at the tmp issue?

@p8
Copy link
Author

p8 commented Apr 4, 2020

@pirj I'll try to have a look this week.

@p8
Copy link
Author

p8 commented Apr 26, 2020

@pirj The script now merges the repo's, adds the travis config, and runs script/run_build in every subrepo. So Rubocop, Cucumber and other checks are run as well.
https://gist.github.com/p8/33563f7378376218a9ce078578b6c095

And the build is green: https://travis-ci.org/github/p8/rspec-monorepo-prototype/builds/679697190

@pirj
Copy link
Member

pirj commented Apr 26, 2020

Awesome!

@JonRowe
Copy link
Member

JonRowe commented May 3, 2020

So I've created a branch called setup on https://github.com/rspec/rspec-monorepo-prototype which contains this script and have run it to create master-20200503

Some thoughts I have so far are that, we are going to lose a large amount of our history in the form of PR references and overlaps, but I'm not sure how we can do much about that.

We're also going to need to work on all of our tags to get them into line, otherwise they will overwrite one another...

We'd also need to transfer all open issues from the other repos to the monorepo.

I've reviewed @p8's build and it works but would need tweaking / optimising afterwards, specifically I think we might actually want to break out the individual specs in a matrix, maybe this would also be a good opportunity to use Github actions, but my branches seem not to want to run for some reason

@pirj
Copy link
Member

pirj commented May 3, 2020

Nice!

work on all of our tags

I guess we can add a repo prefix to tags for all repos before merging them.

lose a large amount of our history in the form of PR references

That might be solvable, but I don't have a good idea how exactly. Before hub existed I used a trick to also fetch PR branches by tweaking the local repo's .git/config. Fetching looks like:

$ git fetch origin
From github.com:joyent/node
 * [new ref]         refs/pull/1000/head -> origin/pr/1000
 * [new ref]         refs/pull/1002/head -> origin/pr/1002

And even though those pull request won't exist in the resulting repo, the pull request heads will.
Maybe also prefix them as refs/pull/core-1000 refs/pull/expectations-1002 to avoid clashing?

It makes sense to add those two tweaks to the merge script.

@p8 Good job!

@JonRowe
Copy link
Member

JonRowe commented May 6, 2020

Its more that we have commits which reference the pull request number, which would not exist in the new repo, but the old repos will continue to exist, we'll just archive them

@benoittgt
Copy link
Member

benoittgt commented May 6, 2020

maybe this would also be a good opportunity to use Github action

I can start again my investigation on this. :)

For the tags, if we choose to prefix them. I am wondering how will manage the github release page

@JonRowe
Copy link
Member

JonRowe commented May 6, 2020

This is how rails handles it https://github.com/rails/rails/releases They just release all versions in lock step, maybe thats easier, we could adopt that from rspec 4

@benoittgt
Copy link
Member

This is how rails handles it https://github.com/rails/rails/releases They just release all versions in lock step, maybe thats easier, we could adopt that from rspec 4

I am in favor of this.

@pirj
Copy link
Member

pirj commented May 6, 2020

all versions in lock step, we could adopt that from rspec 4
All for doing it this way 👍

@p8 I can take it from here, add tag prefixes and keep PR references, if you don't want to continue.

@p8
Copy link
Author

p8 commented May 6, 2020

@pirj Sure, glad I could help :)

@JonRowe JonRowe changed the base branch from master to main August 2, 2020 01:51
@pirj pirj mentioned this pull request Sep 4, 2020
53 tasks
@pirj
Copy link
Member

pirj commented Sep 7, 2021

@eregon
Copy link

eregon commented Mar 21, 2022

It'd be great to get this over the line. TBH I feel it's a huge pain to work with so many git repos, issue trackers, separate projects for PRs, etc. This probably also drives potential contributors away, because to contribute to RSpec one needs a far more complicated setup than about any other gem.

@p8
Copy link
Author

p8 commented Mar 21, 2022

@eregon Making contributing easier was one of my motivations for working on this.
Currently the merging of the repo's is being worked on by @yujinakayama.
rspec/rspec-core#2509 (comment)

@JonRowe
Copy link
Member

JonRowe commented Mar 22, 2022

I'd love to merge the repos into one, but its something that will take time to do correctly and my intention was to coordinate this change with an RSpec 4 release, believe me its just as much of a maintainer headache as it is a contributor one, especially when it comes down to coordinating 4 releases of gems, but there is also a large time cost involved in merging the repos, verifying that everything is correct and then sorting out the history of github issues, that last part was my main reason for targeting a major version release, hopefully that would create a sort of minima of issues to transfer.

@eregon
Copy link

eregon commented Mar 30, 2022

then sorting out the history of github issues, that last part was my main reason for targeting a major version release, hopefully that would create a sort of minima of issues to transfer.

Wouldn't the issues be copied to the monorepo (maybe with an appropriate tag) and then that would be mostly automatic, except for the script/GitHub Action doing that migration? If so I don't think it would change things much whether it's done at the same time than a RSpec 4 release, and it might even be helpful to not have to do both tasks around the same time.

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.