-
Notifications
You must be signed in to change notification settings - Fork 70
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
Migrator hash #197
Migrator hash #197
Conversation
Codecov Report
@@ Coverage Diff @@
## master #197 +/- ##
=========================================
+ Coverage 13.35% 14.6% +1.25%
=========================================
Files 7 7
Lines 397 397
=========================================
+ Hits 53 58 +5
+ Misses 344 339 -5
Continue to review full report at Codecov.
|
conda_forge_tick/auto_tick.xsh
Outdated
# If we've gotten this far then the node is good | ||
attrs['bad'] = False | ||
print('Removing feedstock dir') | ||
rm -rf @(feedstock_dir) | ||
return True | ||
return migrate_return |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Won't migrate_return
always be True if we get here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, yes I forgot to do the upate in main.
@justcalamari @scopatz ready for review! This PR will make sure that we don't re-run migrations that we have already run. |
@@ -15,7 +15,9 @@ from .git_utils import (get_repo, push_repo) | |||
# TODO: move this back to the bot file as soon as the source issue is sorted | |||
# https://travis-ci.org/regro/00-find-feedstocks/jobs/388387895#L1870 | |||
from .migrators import * | |||
$MIGRATORS = [Version(), Compiler()] | |||
$MIGRATORS = [Version(), | |||
# Compiler() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Compiler migration is not complete though
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
right, isn't that why it is commented out?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct, I need to manually migrate the graph or we'll issue PRs to all outstanding compiler migrations. This issue was one of the driving factors for making these changes.
conda_forge_tick/auto_tick.xsh
Outdated
migrator.pr_head(), migrator.remote_branch()) | ||
except github3.GitHubError as e: | ||
if e.msg != 'Validation Failed': | ||
raise e |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should just be a reraise, ie raise
not raise e
conda_forge_tick/auto_tick.xsh
Outdated
if e.msg != 'Validation Failed': | ||
raise e | ||
else: | ||
pass |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
else: pass
is a no-op, that you can remove.
re-raise properly pass migrator_hash to PRed set
conda_forge_tick/migrators.xsh
Outdated
return f'{n}_{attrs["new_version"]}' | ||
|
||
def _extract_version_from_hash(self, h): | ||
return h.split('_')[-1] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happens when the version has an underscore in it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure if conda allows that but I will put in some safe guards.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
conda does allow '_'
conda_forge_tick/auto_tick.xsh
Outdated
'smithy_version': smithy_version, | ||
if 'PRed' not in gx.nodes[node]: | ||
gx.nodes[node]['PRed'] = set() | ||
gx.nodes[node]['PRed'].add(migrator_hash) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe do gx.nodes[node].setdefault('PRed', set()).add(migrator_hash)
here to reduce lines.
or (VersionOrder(str(attrs['new_version'])) <= | ||
VersionOrder(str(attrs['version']))) | ||
# if PRed version is greater than newest version | ||
or any(VersionOrder(self._extract_version_from_hash(h)) >= |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think sometimes h
will be False
. Then _extract_version_from_hash
will error.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
right, so now we default to '0.0.0'
tests/test_migrators.py
Outdated
pmy['meta_yaml'] = parse_meta_yaml(inp) | ||
pmy['raw_meta_yaml'] = inp | ||
pmy.update(kwargs) | ||
|
||
m = migrator() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we use a single instance of each migrator for all tests? This will make the tests more robust.
tests/test_migrators.py
Outdated
(Version, multi_source, updated_multi_source, {'new_version': '2.4.1'}, | ||
'Please check that the dependencies have not changed.'), | ||
(Version, sample_r, updated_sample_r, {'new_version': '1.3_2'}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why was 1.3_2
changed to 1.3-2
?
@justcalamari @scopatz @isuruf Thank you for the review! Would it be possible to get another round? |
conda_forge_tick/migrators.xsh
Outdated
@@ -89,6 +93,9 @@ class Migrator: | |||
"""Branch to use on local and remote""" | |||
return 'bot-pr' | |||
|
|||
def migrator_hash(self, attrs): | |||
return f'{self.__class__.__name__}_{self._class_version}' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm trying to remember why we didn't go with a tuple for this. A tuple might make life easier.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or maybe a dict?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can always change it :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, that is why, I can't put dicts into sets. I can put tuples though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But maybe I can live with lists since dicts seem nicer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A namedtuple might be what you want, actually
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will namedtuple
allow me to add keys as needed or do I need to put out a new one for each set of keys?
conda_forge_tick/migrators.xsh
Outdated
# don't run on bad nodes | ||
return (bool(attrs.get('archived', False) | ||
or self.migrator_hash(attrs) in attrs.get('PRed', [])) | ||
or attrs.get('bad', False)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The problem with this is that the graph thinks that good nodes that used to be bad are still bad. We would need to set bad to False somewhere earlier in the code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm ok, should we reset bad here? https://github.com/regro/cf-scripts/blob/master/conda_forge_tick/make_graph.py#L15
That way every node is good at least to start with.
Or would this introduce too much of a burden?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that should be fine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We may need to think about this more, since failing on every bad feedstock every time the bot runs could be a problem.
conda_forge_tick/migrators.xsh
Outdated
@@ -89,6 +95,10 @@ class Migrator: | |||
"""Branch to use on local and remote""" | |||
return 'bot-pr' | |||
|
|||
def migrator_hash(self, attrs): | |||
return {'class': self.__class__.__name__, | |||
'class_version': self._class_version} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Making this a dict complicates searching with whoosh. I can probably write a new whoosh field type for list of dict, but we need to decide what key names to use. Or maybe we don't care about searching PRed and it can be left out of the schema.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, how are we going to handle multi-source packages, don't they have a list of dicts?
I wouldn't worry about searching this info yet. This will most likely need to go through a refactor when libcflib has a feedstocks graph.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Multi-source packages have a list of dicts for what field?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return pull request json object for later use (eg close PRs if they are old, send pings to maintainers when the status checks are finished)
conda_forge_tick/auto_tick.xsh
Outdated
# TODO: capture pinning here too! | ||
gx.nodes[node].update({'PRed': attrs['new_version'], | ||
'smithy_version': smithy_version, | ||
migrator_hash = run(attrs=attrs, migrator=migrator, gh=gh, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Run also returns PR json now.
conda_forge_tick/auto_tick.xsh
Outdated
gx.nodes[node].setdefault('PRed', []).append(migrator_hash) | ||
# Stash the pr json data so we can access it later | ||
gx.nodes[node].setdefault('PRed_json', {}).update( | ||
{tuple(migrator_hash.keys()): pr_json}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems like a weird key. Did you mean migrator_hash.values()
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, ugh
add migration script for moving the graph to the new PRed format
compiler_migrations.append(node) | ||
|
||
last_compiler_pr = 'cxxopts' | ||
last_compiler_index = compiler_migrations.index(last_compiler_pr) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is compiler_migrations
in the same order every time?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think so (based off of the last time we hit the exact same recipes). I think it is alphabetical.
conda_forge_tick/auto_tick.xsh
Outdated
hash_type=attrs.get('hash_type', 'sha256')) | ||
|
||
converted_hash = convert_dict_to_nt(migrator_hash) | ||
gx.nodes[node].setdefault('PRed', set()).update(converted_hash) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add not update
conda_forge_tick/migrators.xsh
Outdated
# if PRed version is greater than newest version | ||
or any(VersionOrder(self._extract_version_from_hash(h)) >= | ||
VersionOrder(attrs['new_version'] | ||
) for h in attrs.get('PRed', []))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Needs set
return n | ||
|
||
def _extract_version_from_hash(self, h): | ||
return h.get('version', '0.0.0') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
needs getattr
@justcalamari @scopatz @isuruf one last round? Once this is merged, I'll:
I think after that we should be back to normal. |
@mariusvniekerk (would you be interested in giving review?) |
return bool(attrs.get('archived', False)) | ||
# don't run on things we've already done | ||
# don't run on bad nodes | ||
return bool(bool(attrs.get('archived', False) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the bool casting needed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was going to play it safe
conda_forge_tick/auto_tick.xsh
Outdated
rerender=rerender, protocol='https', | ||
hash_type=attrs.get('hash_type', 'sha256')) | ||
|
||
converted_hash = convert_dict_to_nt(migrator_hash) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not have migrator_hash
be a namedtuple to begin with?
conda_forge_tick/migrators.xsh
Outdated
|
||
|
||
class Migrator: | ||
"""Base class for Migrators""" | ||
rerender = False | ||
|
||
_class_version = 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would prefer if this was called migrator_version
, and it seems like this should be part of the public API
conda_forge_tick/migrators.xsh
Outdated
@@ -89,6 +96,10 @@ class Migrator: | |||
"""Branch to use on local and remote""" | |||
return 'bot-pr' | |||
|
|||
def migrator_hash(self, attrs): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
docstring on this method. Also, it doesn't seem to return a hash (int)
conda_forge_tick/migrators.xsh
Outdated
@@ -89,6 +96,10 @@ class Migrator: | |||
"""Branch to use on local and remote""" | |||
return 'bot-pr' | |||
|
|||
def migrator_hash(self, attrs): | |||
return {'class_name': self.__class__.__name__, | |||
'class_version': self._class_version} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you can drop the class_
from these keys.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or replace them with migrator_
, which has more semantic meaning.
conda_forge_tick/migrators.xsh
Outdated
@@ -240,6 +257,15 @@ class Version(Migrator): | |||
def remote_branch(self): | |||
return self.attrs['new_version'] | |||
|
|||
def migrator_hash(self, attrs): | |||
n = super().migrator_hash(attrs) | |||
n.update({'version': attrs["new_version"]}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, I see that this adds version
@@ -0,0 +1,29 @@ | |||
import networkx as nx |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should probably have a #!/usr/bin/env python
as a script
conda_forge_tick/auto_tick.xsh
Outdated
rerender=rerender, protocol='https', | ||
hash_type=attrs.get('hash_type', 'sha256')) | ||
|
||
converted_hash = migrator_uid |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this line can be removed and every instance of converted_hash
changed to migrator_uid
conda_forge_tick/migrators.xsh
Outdated
@@ -44,7 +51,7 @@ class Migrator: | |||
bool: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The return type is different now
conda_forge_tick/auto_tick.xsh
Outdated
|
||
Returns | ||
------- | ||
migrate_return: dict |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
type should be namedtuple
don't write to exceptions file, just put it into the graph style changes
Interesting, trying to pickle the namedtuple is causing problems: christopher@christopher-ubuntu ~/dev/cf-graph master $ python ../cf-scripts/migrate_to_hash.py
Traceback (most recent call last):
File "../cf-scripts/migrate_to_hash.py", line 30, in <module>
nx.write_gpickle(g, '../cf-graph/graph.pkl')
File "<decorator-gen-402>", line 2, in write_gpickle
File "/home/christopher/mc/lib/python3.6/site-packages/networkx/utils/decorators.py", line 227, in _open_file
result = func_to_be_decorated(*new_args, **kwargs)
File "/home/christopher/mc/lib/python3.6/site-packages/networkx/readwrite/gpickle.py", line 70, in write_gpickle
pickle.dump(G, path, protocol)
_pickle.PicklingError: Can't pickle <class 'conda_forge_tick.utils.converted'>: attribute lookup converted on conda_forge_tick.utils failed |
I think this is ready to go! I've tested this on the graph and it seems to produce the expected output. Thank you everyone for the reviews! (sorry that this PR was a bit like pulling chicken teeth) |
Closes #189
closes #138