Skip to content

Commit

Permalink
Add support for helper dependencies
Browse files Browse the repository at this point in the history
Helpers can now have a `name` and define `dependencies`. This is a comma delimited list of other helper names that the helper is dependent on. If a helper is dependent on another helper then the other helper will be loaded before it.
  • Loading branch information
trevordevore committed Jan 18, 2019
1 parent cb0e465 commit 3502f61
Showing 1 changed file with 88 additions and 0 deletions.
88 changes: 88 additions & 0 deletions framework/levure.livecodescript
Expand Up @@ -1194,6 +1194,7 @@ command levureLoadAppConfig pBuildProfile
put the result into tError

if tError is empty then
sortHelpersBasedOnDependencies
resolveHelperAssets pBuildProfile
put the result into tError
end if
Expand Down Expand Up @@ -1947,6 +1948,93 @@ private function shellFormat pArg, pSwitch
end shellFormat


/**
Summary: Reorders helpers so that dependencies are loaded before dependents.

Description:
If a helper is dependent on another helper then behaviors in the dependency
must be loaded first. This handler will reorder helpers so that the load
order is correct.

Returns: nothing
*/
private command sortHelpersBasedOnDependencies
local tHelperA, tHelpersA, tIndexesToProcess, tIndex, tNewIndex
local tLoadedHelpersA, tSkip

lookForCircularDependenciesInHelpers

put the keys of sAppA["helpers"] into tIndexesToProcess
sort lines of tIndexesToProcess numeric ascending

repeat until tIndexesToProcess is empty
put line 1 of tIndexesToProcess into tIndex
put sAppA["helpers"][tIndex] into tHelperA

put false into tSkip

repeat for each item tHelperName in tHelperA["dependencies"]
if tHelperName is not among the keys of tLoadedHelpersA then

# Move this helper to the end of the list
put tIndex into line (the number of lines of tIndexesToProcess + 1) of tIndexesToProcess

put true into tSkip
exit repeat
end if
end repeat

if not tSkip then
add 1 to tNewIndex
put tHelperA into tHelpersA[tNewIndex]
put empty into tLoadedHelpersA[ tHelperA["name"] ]
end if

delete line 1 of tIndexesToProcess
end repeat

put tHelpersA into sAppA["helpers"]
end sortHelpersBasedOnDependencies


/**
Summary: Performs a simple check for circular dependencies.

Description:
The check only looks for circular dependencies between A and B.
It doesn't look for circular connections between A, B, and C where
A depends on B and B depends on C but C depends on A.

Returns: nothing
*/
private command lookForCircularDependenciesInHelpers
local tHelperA, tDependenciesA
local tHelperName, tDependentName

# Create lookup area of each helper's dependencies
repeat for each element tHelperA in sAppA["helpers"]
if word 1 to -1 of tHelperA["name"] is not empty then
repeat for each item tHelperName in tHelperA["dependencies"]
put tHelperA["name"] & "," after tDependenciesA[tHelperName]
end repeat
end if
end repeat

# Now see if any of a helper depends on any of it's dependents.
repeat for each element tHelperA in sAppA["helpers"]
if word 1 to -1 of tHelperA["name"] is not empty then
repeat for each item tDependentName in tDependenciesA[ tHelperA["name"] ]
if tHelperA["name"] is among the items of tDependenciesA[tDependentName] then
throw kLevureErr & "circular dependency detected in" && \
quote & tHelperA["name"] & quote && "and" && \
quote & tDependentName & quote && "helpers"
end if
end repeat
end if
end repeat
end lookForCircularDependenciesInHelpers


private command resolveHelperAssets pBuildProfile
local tError, tConfigA, i
local tExternalPackagesInMemory
Expand Down

0 comments on commit 3502f61

Please sign in to comment.