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

build providers: better injection logic #2196

Merged
merged 17 commits into from
Aug 14, 2018

Conversation

sergiusens
Copy link
Collaborator

@sergiusens sergiusens commented Aug 7, 2018

  • Have you followed the guidelines for contributing?
  • Have you signed the CLA?
  • If this is a bugfix. Have you checked that there is a bug report open for the issue you are trying to fix on bug reports?
  • If this is a new feature. Have you discussed the design on the forum?
  • Have you successfully run ./runtests.sh static?
  • Have you successfully run ./runtests.sh unit?

@kyrofa
Copy link
Contributor

kyrofa commented Aug 8, 2018

Conflicts here.

@codecov-io
Copy link

codecov-io commented Aug 9, 2018

Codecov Report

Merging #2196 into master will decrease coverage by 0.05%.
The diff coverage is 91.85%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #2196      +/-   ##
==========================================
- Coverage   91.21%   91.15%   -0.06%     
==========================================
  Files         208      209       +1     
  Lines       13160    13302     +142     
  Branches     1957     1981      +24     
==========================================
+ Hits        12004    12126     +122     
- Misses        788      801      +13     
- Partials      368      375       +7
Impacted Files Coverage Δ
snapcraft/internal/lifecycle/_containers.py 82.92% <0%> (ø) ⬆️
snapcraft/internal/repo/snaps.py 91.01% <100%> (-0.27%) ⬇️
...l/build_providers/_multipass/_multipass_command.py 85.52% <33.33%> (-3.52%) ⬇️
snapcraft/storeapi/_snap_index_client.py 77.77% <66.66%> (-1.3%) ⬇️
.../internal/build_providers/_multipass/_multipass.py 83.67% <75%> (-6.33%) ⬇️
snapcraft/internal/build_providers/_snap.py 94.28% <94.28%> (ø)
...apcraft/internal/build_providers/_base_provider.py 98.33% <94.73%> (-1.67%) ⬇️
snapcraft/internal/pluginhandler/_plugin_loader.py 91.96% <0%> (-1.79%) ⬇️

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 b772997...0b9c8c8. Read the comment docs.

Keep a registry of what has been injected and allow for ephemeral
injection for disposable environments.

LP: #1779945
LP: #1782777
Signed-off-by: Sergio Schvezov <sergio.schvezov@canonical.com>
@sergiusens sergiusens changed the title Snap processor build providers: better injection logic Aug 9, 2018
Copy link
Contributor

@kyrofa kyrofa left a comment

Choose a reason for hiding this comment

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

Looking good! Took a first pass, made some comments inline.

@@ -53,6 +47,9 @@ def __init__(self, *, project, echoer) -> None:
self.snap_filename = "{}_{}.snap".format(
project.info.name, project.deb_arch
)
self.provider_project_dir = os.path.join(
BaseDirectory.xdg_data_home, "snapcraft", "projects", project.info.name
Copy link
Contributor

Choose a reason for hiding this comment

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

Perhaps os.path.join(xdg.BaseDirectory.save_data_path("snapcraft"), "projects", project.info.name) ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Sure, why not? Is there a difference?

if not snap_repo.installed and self._latest_revision is None:
op = _SnapOp.INSTALL
elif not snap_repo.installed and self._latest_revision is not None:
op = _SnapOp.REFRESH
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm a little confused on this one-- how can a refresh be what's needed if it's not installed?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

If you are running from the deb, it will not be installed, if the environment has already been created it may have a revision installed.
snap_repo is for the host, the operation for the build environment.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I will document with code comments

]


class SnapInjector:
Copy link
Contributor

Choose a reason for hiding this comment

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

Mind adding some sphinx docs here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

done

runner,
snap_dir_mounter,
snap_dir_unmounter,
file_pusher
Copy link
Contributor

Choose a reason for hiding this comment

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

Would like to see some types specified for these callbacks.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

yes, I forgot!

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

there is no comprehensive way to define a Callable that takes optional arguments nor one that takes kwargs https://docs.python.org/3.5/library/typing.html#callable

def _get_latest_revision(self, snap_name):
self._load_registry()
try:
return self._registry_data[snap_name][-1]["revision"]
Copy link
Contributor

Choose a reason for hiding this comment

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

Rather than having an explicit _load_registry() function as well as a private _registry_data attribute, this usage seems better suited to simple lazy evaluation of the property (or a get_registry() function, if you prefer) to encapsulate the loading and returning of the registry.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I sort of started to dislike properties when I do not need them (like replacing an already in use attribute). They are hard to mock and this clearly does something under the hood. Also,

Explicit is better than implicit" is in direct conflict with using a property. (It looks like a simple assignment, but it calls a function).

After that philosophical point, if you still want me to change, I will :-)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Oh, but I am down with get_registry, I had that originally and was passing around too many params for my taste, but I prefer that indeed

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I like the symmetry on this one and not sure I understand the change now that I am re-reading.

with open(self._registry_filepath) as registry_file:
self._registry_data = yaml.load(registry_file)

def _dump_registry(self):
Copy link
Contributor

Choose a reason for hiding this comment

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

Take it or leave it, but I feel like this should be called _save_registry.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

ok, was going with parity with yaml and json.load/dump :-)

except (IndexError, KeyError):
return None

def _add_latest_revision(self, snap_name: str, snap_revision: str) -> None:
Copy link
Contributor

Choose a reason for hiding this comment

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

This function name isn't a good indicator of what this does. It's not at all similar to the similarly-named add() function, and it doesn't do anything with the "latest revision": it takes the one you give it. Perhaps _record_revision() would be better?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

sure, this was mostly a parity thing, but I even got that wrong I think :-)

Copy link
Contributor

@kyrofa kyrofa left a comment

Choose a reason for hiding this comment

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

I have two nits, but this looks good to me.

return self.__install_cmd


_STORE_ASSERTION = [
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we move this up to the top of the file, please?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

sure

environment.
"""

self._snaps = [] # type: List["_SnapManager"]
Copy link
Contributor

Choose a reason for hiding this comment

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

Does this type need to be quoted? It's defined earlier in this file.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

only because I moved things around, probably not

@sergiusens sergiusens merged commit d9a477e into canonical:master Aug 14, 2018
@sergiusens sergiusens deleted the snap-processor branch August 14, 2018 23:57
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.

None yet

3 participants