Since we want to allow for independently executing datasources when
needed, we break down the logic to do so.
Each datasource will now hold a list of dependencies. For now, these
dependencies are all datasources themselves, but this may change in the
future.
Then, actual execution of the datasource is self-contained within a
method of the structure, so that we can individually execute them.
Finally, we replace the current sequential execution by a method of the
PackerConfig with an approach akin to local variable evaluation, where
we execute all the datasources one-by-one, and if they cannot be
executed, move along.
We retry this loop for as many times as we don't reach either a state
where all the datasources have been executed; or when we reach a
terminal state where datasources cannot be evaluated because of
dependencies remaining, and no changes have occurred after a try.