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

feat: include local dirty changes by default. fixes #184 #520

Merged
merged 15 commits into from
Jan 11, 2022

Conversation

sabard
Copy link
Contributor

@sabard sabard commented Dec 29, 2021

A quick attempt at implementing the changes described in this comment.

  • if a template is vcs-tracked and dirty, the changes are committed automatically with a "wip" commit and propagated to the subproject
  • user is warned in this scenario
  • tests for copy and update on dirty templates

I made this the default behavior, but would be happy to add a flag for this behavior and maintain the current default.

Also, think this will have to rebase off of #519 to pass CI

copier/template.py Outdated Show resolved Hide resolved
copier/template.py Outdated Show resolved Hide resolved
tests/test_dirty_local.py Outdated Show resolved Hide resolved
@pawamoy
Copy link
Contributor

pawamoy commented Dec 29, 2021

So, just to be clear: this change creates the wip commits in a temporary copy/clone, right? Not in the original template repository?

If it does so in the original:
I'm really not in favor of automatic wip commits in the original repository. I believe this is error prone and too invasive. Each time I change something and test project generation again, it will create an additional wip commit (amending the previous one or resetting before committing again would be even more dangerous IMO). Once my changes are OK, I'll have to reset all these wip commits myself? That is as annoying as having to commit manually, maybe even more. (Sorry for not thinking about all this earlier, in the linked issue)

Let me know what you all think (and correct me if I'm wrong!)

@sabard
Copy link
Contributor Author

sabard commented Dec 30, 2021

I originally was creating the commit in the original template repository because that was easier, but I agree that it is too intrusive.

The current code modifies vcs::clone instead of template::local_abspath and copies a dirty repo into a temporary directory so that it can add, commit, and clone.

copier/vcs.py Outdated Show resolved Hide resolved
@pawamoy
Copy link
Contributor

pawamoy commented Dec 30, 2021

Docs failure is because mkdocs-autorefs 0.3.1 was installed, while mkdocstrings 0.17.0 was not. I should probably have tagged mkdocs-autorefs 0.4.0 to prevent that. Or better yet, upper bounds could be removed on Copier's dependencies 😛

@sabard
Copy link
Contributor Author

sabard commented Dec 30, 2021

Got it—should I just add mkdocs-autorefs = "^0.4.0" to pyproject.toml? I always use pip-tools and not too familiar with poetry.

@pawamoy
Copy link
Contributor

pawamoy commented Dec 30, 2021

I wasn't clear: mkdocstrings should be updated (up to 0.17.0), not mkdocs-autorefs. But it should probably be done in another PR (it's very easy, just manually update mkdocstrings accepted range in pyproject.toml and regen the lock file with poetry lock).

@sabard sabard force-pushed the sabard/dirty-local branch from 960455b to 3fe1f42 Compare December 30, 2021 21:37
@sabard
Copy link
Contributor Author

sabard commented Dec 30, 2021

I saw this was fixed in #518, so I just rebased instead.

@pawamoy
Copy link
Contributor

pawamoy commented Dec 31, 2021

Oh yes, good catch.

@codecov-commenter
Copy link

codecov-commenter commented Jan 1, 2022

Codecov Report

Merging #520 (d74ec86) into master (a283bc4) will decrease coverage by 0.13%.
The diff coverage is 100.00%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #520      +/-   ##
==========================================
- Coverage   96.45%   96.32%   -0.14%     
==========================================
  Files          40       41       +1     
  Lines        2623     2693      +70     
==========================================
+ Hits         2530     2594      +64     
- Misses         93       99       +6     
Flag Coverage Δ
unittests 96.32% <100.00%> (-0.14%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
copier/template.py 97.43% <ø> (ø)
copier/errors.py 97.36% <100.00%> (+0.07%) ⬆️
copier/vcs.py 97.40% <100.00%> (+0.52%) ⬆️
tests/test_dirty_local.py 100.00% <100.00%> (ø)
tests/conftest.py 84.61% <0.00%> (-7.70%) ⬇️
copier/tools.py 87.95% <0.00%> (-4.82%) ⬇️
copier/main.py 94.15% <0.00%> (-0.33%) ⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update a283bc4...d74ec86. Read the comment docs.

Copy link
Member

@yajo yajo left a comment

Choose a reason for hiding this comment

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

Hi @sabard! Welcome to Copier 😊

This PR is very nice already. There are some improvements to do below, but overall it's almost ready to merge.

Thank you very much for your contribution!

PS: Please make that CI happy 😉

README.md Outdated Show resolved Hide resolved
copier/main.py Outdated Show resolved Hide resolved
copier/main.py Outdated Show resolved Hide resolved
copier/vcs.py Outdated Show resolved Hide resolved
copier/vcs.py Outdated Show resolved Hide resolved
copier/vcs.py Outdated Show resolved Hide resolved
tests/test_dirty_local.py Show resolved Hide resolved
tests/test_dirty_local.py Outdated Show resolved Hide resolved
@sabard sabard force-pushed the sabard/dirty-local branch from 3fe1f42 to 15177a8 Compare January 2, 2022 19:43
@sabard
Copy link
Contributor Author

sabard commented Jan 3, 2022

Removed Python 3.7 incompatible dirs_exist_ok option in shutil.copytree and fixed a bug in test_dirty_local.py causing CI to error.

Should be ready for another CI run.

copier/vcs.py Outdated
if os.path.isdir(s):
copytree(s, d)
else:
copy2(s, d)
Copy link
Member

Choose a reason for hiding this comment

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

Looking closer to the algorithm, it's not much efficient. Luckily it's very easy to improve. It should:

  1. clone
  2. cd into url.
  3. git diff --binary HEAD to get a patch.
  4. cd into new clone
  5. git apply the patch
  6. wip commit.

This way you don't have to create yet aother clone just to add 1 extra commit. Besides, you avoid copying manually instead of using git clone (which is safer and more efficient too).

P,S. please avoid naming variables with a single letter. Makes the code harder to understand.

Copy link
Contributor Author

@sabard sabard Jan 3, 2022

Choose a reason for hiding this comment

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

This turned out to be not so simple for a few reasons:

  • git diff does not, by default, give a diff of the untracked files (of interested here doing a dirty copy)
  • HEAD might not exist (e.g., git init was just run)

That said, I was able to get something closer to what you are asking for working by using git diff --no-index and then excluding */.git/* on the apply. This will of course copy over other unwanted files to the temporary clone directory, but they shouldn't make it into the subdirectory since they will be in the clone's .gitignore. I think this is arguably just as inefficient in the worst-case (large .gitignored file getting needlessly copied).

I tried getting something like git --git-dir=<clone_dst>/.git --work-tree=<template_src> diff HEAD SO source to work to no avail. Seems that anytime git-diff is used without --no-index it ignores untracked files.

Need to make a couple fixes for CI still, but pushed latest changes to avoid losing progress.

Copy link
Member

Choose a reason for hiding this comment

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

AFAIK git stash works both with staged and untracked files. Have you tried with it?

tests/test_dirty_local.py Outdated Show resolved Hide resolved
@yajo
Copy link
Member

yajo commented Jan 3, 2022

Please also add a note in the changelog.

@sabard
Copy link
Contributor Author

sabard commented Jan 3, 2022

The most recent commit should probably pass CI. However:

I'm seeing error: git diff header lacks filename information when removing 1 leading pathname component from the test_worker_config_precedence test (attempting to copy the copier template itself). This is only triggered when the working tree is dirty, of course, but would appreciate any help figuring out how to fix this. Should be able to reproduce the error by checking out the latest commit here, making a change, and running the tests.

@sabard sabard force-pushed the sabard/dirty-local branch from ae3470f to 49e4fbd Compare January 4, 2022 00:23
@sabard
Copy link
Contributor Author

sabard commented Jan 4, 2022

After some thinking, I figured it would be a better solution to create a new .git dir in a temporary location, but point it to the files in the template dir. This lets us add and commit the dirty (and untracked!) changes while avoiding the extra copy. Please see the latest code and let me know if you have any questions.

@sabard sabard requested a review from yajo January 4, 2022 00:28
CHANGELOG.md Outdated Show resolved Hide resolved
tests/test_dirty_local.py Outdated Show resolved Hide resolved
copier/vcs.py Outdated Show resolved Hide resolved
@sabard sabard changed the title feat: include local dirty changes by default feat: include local dirty changes by default. fixes #184 Jan 5, 2022
copier/vcs.py Outdated Show resolved Hide resolved
tests/test_dirty_local.py Show resolved Hide resolved
@sabard sabard requested a review from yajo January 5, 2022 19:46
Copy link
Member

@yajo yajo left a comment

Choose a reason for hiding this comment

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

Looks much nicer now!

Just remove that leftover line and one question to merge!

Thanks again, great job!

copier/vcs.py Outdated Show resolved Hide resolved

with local.cwd(location):
git("checkout", ref or "HEAD")
git("submodule", "update", "--checkout", "--init", "--recursive", "--force")
Copy link
Member

Choose a reason for hiding this comment

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

I've got the feeling that this block should be done before importing the ditty changes. However, if the test goes green I guess I'm just wrong.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think it shouldn't matter if it runs before or after. But if there is no HEAD in the case of a recently intialized repo, then this fails and would need to be called after as well. I also realized that specifying ref means that dirty changes won't be considered and so added that to the dirty checking logic.

@sabard
Copy link
Contributor Author

sabard commented Jan 7, 2022

Any tips for figuring out what's wrong with CI on windows? I cloned and ran the tests on my windows box and they passed, so having trouble replicating to get more info on the error.

EDIT: tried a filecmp.clear_cache() in the latest code. don't have any way to test this on my end other than running CI again unfortunately.

tests/test_dirty_local.py Outdated Show resolved Hide resolved
Copy link
Member

@yajo yajo left a comment

Choose a reason for hiding this comment

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

Looks good! Just make it green to merge.

Thanks.

@sabard sabard requested a review from yajo January 10, 2022 17:43
@yajo yajo linked an issue Jan 11, 2022 that may be closed by this pull request
@yajo yajo merged commit 6cc94c6 into copier-org:master Jan 11, 2022
@sabard sabard deleted the sabard/dirty-local branch January 11, 2022 19:20
@yajo yajo added this to the v6.0.0 milestone Mar 7, 2022
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.

Don't checkout anything by default on local templates
4 participants