initialcommit-com/git-sim

Add git-dummy as a dependency to git-sim

initialcommit-io opened this issue · 5 comments

I want to add git-dummy as a dependency for Git-Sim so that we can add a --generate flag to enable the creation of a dummy Git repo to run the simulation on with a single command, something like this:

$ git-sim --generate --branches=2 --commits=10 log

I set this up locally by updating the setup.py to add the git-dummy package into install_requires, and also added a new entry point for it so that it can be called as a subprocess:

entry_points={
        "console_scripts": [
            "git-sim=git_sim.__main__:app",
            "git-dummy=git_dummy.__main__:app",
        ],  
    },

I added some code into main to call git-dummy to create the new repo when the --generate flag is set:

if settings.generate:
        subprocess.call("git-dummy --no-subdir", shell=True)

This works, but I wonder if we can clean it up so we don't need a separate git-dummy endpoint and can just call methods within the git-dummy package. This would also avoid the need to call subprocess.

Also, I wonder if there is a nifty way to handle the git-dummy command line arguments, like --branches, --commit, --diverge-at without redefining them in Git-Sim.

@paketb0te Any thoughts on this?

Just to clarify: We do NOT want to use git-dummy as a subcommand for git-sim (which would look something like git-sim generate --branches 3 --diverge-at 2), but rather use it as a flag / option to other git-sim commands, like git-sim --generate --branches 3 --diverge-at 2 log, correct?

The first would be very easy, just import the typer app from git-dummy and add it to the git-sim typer app like this:

# __main__.py

# we should probably clean that up a little, objects starting with underscores are usually not meant to be exported - but this works as-is:

from git_dummy.__main__ import main as dummy_main
...
app.command(name="generate")(dummy_main)

And if there are at some point more sub-commands in git-dummy, then we could also switch to import not the single command but the whole typer app from git_dummy.

For the second option, we can still import the function from git-dummy and execute it when --generate is set:

# __main__.py

from git_dummy.__main__ import main as dummy_generate
...
@app.callback()
def main(
    ...
    generate: bool = typer.Option(
        settings.generate,  # would be set to False by default
        help="foo"
):
    ...
    if settings.generate:
        dummy_generate()

but I'm not sure if / how we can avoid re-declaring the options for git-dummy 🤔

@initialcommit-io I'm not sure I understand why we want --generate as an option to the other commands, could you expand a bit on that?

What is the main usecase?

I assume one would typically run only a single command with the --generate flag, because there is no need to re-create it each time for subsequent git-sim commands.

In that case I think it would be easier just to make it a separate command (like git-sim generate, as shown in my first example).

Do you have a different usecase in mind?

@paketb0te Thanks for the details! And good question. The reason I was thinking we would use an option like --generate as a global Git-Sim option was in the spirit of being able to do everything in a single command. So the use case is that the user could generate a dummy repo specifically to run 1 git-sim command against it, and run the git-sim command all in 1 step. So something like:

$ git-sim --generate --branches=2 merge branch1

This would allow the generation of the dummy repo ready to simulate a merge on, and simulate the merge as well with a single command. Another (smaller) reason is that theoretically, each git-sim subcommand should correlate to a Git subcommand. It might be confusing to some users if "generate" is a git-sim subcommand but not a Git subcommand. That's why I thought it might work better as a global option to Git-Sim instead of a subcommand.

However, having a separate git-sim generate ... subcommand would be a lot cleaner and more maintainable like you said. The user could do something like this if they wanted to do it all in one line:

$ git-sim generate --branches=2 && git-sim merge branch1

But if that's the case, then why wouldn't they just use git-dummy itself? Like this:

$ git-dummy --branches=2 && git-sim merge branch1

So in that case maybe it doesn't make sense to add git-dummy into Git-Sim... Aside from the fact that Git-Sim already has a good following of users, so more people would likely become aware of the feature if we add it into Git-Sim than if we just leave it as a separate git-dummy project.

Maybe the answer is to add git-dummy into git-sim as a dependency with an entry point so it gets installed along with git-sim, and add a section in the README for how to use it alongside Git-Sim and chain the commands together like in the example above if desired. That way we don't need to worry about maintaining the extra options in sync or adding a non-Git subcommand. And we also get the benefit of all the eyeballs on Git-Sim being aware of the generation feature.

Thoughts?

@initialcommit-io agree on all your points.

Random thought: If we keep it as a command in git-sim, we could call it init instead of generate to have it match an actual git command 😄

But I'm not sure if it's a good idea, seeing that it would not simulate git init, but actually create a git repo.

On that note, we should probably make sure that we don't accidentally overwrite an existing git repo (I assume that the git module throws an error in that case, but we should be extra careful there to not accidentally destroy someone's repo 😅)

@paketb0te Ha yes I guess it kind of is like git init... But yes you're right that we should probably just stick to simulating instead of doing.

And yes I was thinking about that for git-dummy - I will put in some explicit logic into git-dummy to stop execution and log an error if the user is already inside an existing Git repo, so it doesn't try to create a new one in that folder, or in a subdirectory.

Added git-dummy as a dependency as a part of v0.2.5