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

many: detect local source changes #2167

Merged
79 changes: 47 additions & 32 deletions snapcraft/internal/lifecycle/_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,41 +184,56 @@ def run(self, step: steps.Step, part_names=None):
# already been built --elopio - 20170713
pluginhandler.check_for_collisions(self.config.all_parts)
for part in parts:
dirty_report = self._cache.get_dirty_report(
part, current_step)
if dirty_report:
self._handle_dirty(
part, current_step, dirty_report, cli_config)
elif self._cache.has_step_run(part, current_step):
# By default, if a step has already run, don't run it
# again. However, automatically clean and re-run the
# step if all the following conditions apply:
#
# 1. The step is the exact step that was requested
# (not an earlier one)
# 2. The part was explicitly specified
if (part_names and current_step == step and
part.name in part_names):
getattr(self, '_re{}'.format(
current_step.name))(part)
else:
outdated_report = self._cache.get_outdated_report(
part, current_step)
if outdated_report:
self._handle_outdated(
part, current_step, outdated_report,
cli_config)
else:
notify_part_progress(
part,
'Skipping {}'.format(current_step.name),
'(already ran)')
else:
getattr(self, '_run_{}'.format(
current_step.name))(part)
self._handle_step(
part_names, part, step, current_step, cli_config)

self._create_meta(step, processed_part_names)

def _handle_step(self, requested_part_names: Sequence[str],
part: pluginhandler.PluginHandler,
requested_step: steps.Step,
current_step: steps.Step, cli_config) -> None:
# If this step hasn't yet run, all we need to do is run it
if not self._cache.has_step_run(part, current_step):
getattr(self, '_run_{}'.format(current_step.name))(part)
return
Copy link
Collaborator

Choose a reason for hiding this comment

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

instead of multiple returns here, it seems this could be handled very well with elif and a final else.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We're fetching reports before checking them, which is heavy to do upfront if we don't actually need to, so it doesn't fit particularly well within an if/elif unless we want to nest within elses.


# Alright, this step has already run. In that case, a few different
# things need to happen:

# 1. By default, if a step has already run, don't run it again.
# However, automatically clean and re-run the step if all the
# following conditions apply:
#
# 1.1. The step is the exact step that was requested (not an
# earlier one).
# 1.2. The part was explicitly specified.
if (requested_part_names and current_step == requested_step and
part.name in requested_part_names):
getattr(self, '_re{}'.format(current_step.name))(part)
return

# 2. If a step has already run, it might be dirty, in which case we
# need to clean and run it again.
dirty_report = self._cache.get_dirty_report(part, current_step)
if dirty_report:
self._handle_dirty(part, current_step, dirty_report, cli_config)
return

# 3. If a step has already run, it might be outdated, in which case we
# need to update it (without cleaning if possible).
outdated_report = self._cache.get_outdated_report(
part, current_step)
if outdated_report:
self._handle_outdated(
part, current_step, outdated_report, cli_config)
return

# 4. The step has already run, and is up-to-date, no need to run it
# again.
notify_part_progress(
part, 'Skipping {}'.format(current_step.name), '(already ran)')

def _run_pull(self, part):
self._run_step(step=steps.PULL, part=part, progress='Pulling')

Expand Down