diff --git a/README.md b/README.md index 0efd9f0..d9f3ec7 100644 --- a/README.md +++ b/README.md @@ -417,6 +417,8 @@ ARG=hello world You can also rely on parameterized goals [parameters interpolation](https://github.com/xonixx/makesure/issues/153). +Also, it's possible for a `@glob` goal [to be parameterized](https://github.com/xonixx/makesure/issues/155). + Please find a more real-world example [here](https://github.com/xonixx/fhtagn/blob/e7161f92731c13b5afbc09c7d738c1ff4882906f/Makesurefile#L70). For more technical consideration regarding this feature see [parameterized_goals.md](docs/parameterized_goals.md). diff --git a/docs/glob_plus_pg.md b/docs/glob_plus_pg.md new file mode 100644 index 0000000..9168594 --- /dev/null +++ b/docs/glob_plus_pg.md @@ -0,0 +1,24 @@ + +```shell +@goal gpg @glob 'glob_test/*.txt' @params P + echo "$ITEM $P" + +@goal g1 +@depends_on gpg @args 'hello' +``` + +-> + +```shell +@goal gpg @params P +@depends_on 'gpg@glob_test/1.txt' @args P +@depends_on 'gpg@glob_test/2.txt' @args P + +@goal 'gpg@glob_test/1.txt' @params P + echo "$ITEM $P" +@goal 'gpg@glob_test/2.txt' @params P + echo "$ITEM $P" + +@goal g1 +@depends_on gpg @args 'hello' +``` diff --git a/makesure.awk b/makesure.awk index 954b693..e4fec09 100755 --- a/makesure.awk +++ b/makesure.awk @@ -20,7 +20,7 @@ BEGIN { delete Dependencies # name,depI -> dep goal delete DependenciesLineNo # name,depI -> line no. delete DependenciesCnt # name -> dep cnt - delete DependencyArgsNR # name,depI -> NR only when it's @depends_on with @args + delete DependencyArgsL # name,depI -> initial $0, but only when it's @depends_on with @args delete Doc # name -> doc str delete ReachedIf # name -> condition line GlobCnt = 0 # count of files for glob @@ -41,7 +41,7 @@ BEGIN { function makesure( i) { while (getline > 0) { - Lines[NR] = $0 + Lines[NR] = Line0 = $0 if ($1 ~ /^@/ && "@reached_if" != $1 && !reparseCli()) continue if ("@options" == $1) handleOptions() else if ("@define" == $1) handleDefine() @@ -242,27 +242,42 @@ function parsePriv() { NF-- return 1 } -function handleGoalGlob( goalName,globAllGoal,globSingle,priv,i,pattern,nfMax) { +function handleGoalGlob( goalName,globAllGoal,globSingle,priv,i,pattern,nfMax,gi,j,l,globPgParams) { started("goal_glob") priv = parsePriv() if ("@glob" == (goalName = $2)) { goalName = ""; pattern = $(nfMax = 3) } else pattern = $(nfMax = 4) - if (NF > nfMax) - addError("nothing allowed after glob pattern") + if (NF > nfMax && "@params" != $(nfMax + 1)) + addError("nothing or @params allowed after glob pattern") else if (pattern == "") addError("absent glob pattern") else { + if ("@params" == $(nfMax + 1)) + for (i = nfMax + 2; i <= NF; i++) + arrPush(globPgParams, validateParamName($i)) calcGlob(goalName, pattern) globAllGoal = goalName ? goalName : pattern globSingle = GlobCnt == 1 && globAllGoal == globGoal(0) - for (i = 0; i < GlobCnt; i++) - registerGoal(globSingle ? priv : 1, globGoal(i)) + for (i = 0; i < GlobCnt; i++) { + registerGoal(globSingle ? priv : 1, gi = globGoal(i)) + for (j = 0; j in globPgParams; j++) + GoalParams[gi, GoalParamsCnt[gi]++] = globPgParams[j] + } if (!globSingle) { # glob on single file registerGoal(priv, globAllGoal) - for (i = 0; i < GlobCnt; i++) + for (j = 0; j in globPgParams; j++) + GoalParams[globAllGoal, GoalParamsCnt[globAllGoal]++] = globPgParams[j] + for (i = 0; i < GlobCnt; i++) { registerDependency(globAllGoal, globGoal(i)) + if (arrLen(globPgParams)) { + l = "@depends_on x @params" + for (j = 0; j in globPgParams; j++) + l = l " " globPgParams[j] + DependencyArgsL[globAllGoal, i] = l + } + } } } } @@ -300,13 +315,12 @@ function handleDependsOn( i) { registerDependsOn(globGoal(i)) } -function registerDependsOn(goalName, i,dep,x,y) { +function registerDependsOn(goalName, i,dep) { for (i = 2; i <= NF; i++) { - dep = $i - if ("@args" == dep) { + if ("@args" == (dep = $i)) { if (i != 3) addError("@args only allowed at position 3") - DependencyArgsNR[goalName, DependenciesCnt[goalName] - 1] = NR + DependencyArgsL[goalName, DependenciesCnt[goalName] - 1] = Line0 break } else registerDependency(goalName, dep) @@ -646,12 +660,12 @@ function instantiate(goal,args,newArgs, i,j,depArg,depArgType,dep,goalNameInst dep = Dependencies[gi = goal SUBSEP i] argsCnt = 0 - if (gi in DependencyArgsNR) { + if (gi in DependencyArgsL) { delete reparsed # The idea behind deferring this reparsing to instantiation is to be able to reference both @define vars and PG # params in PG arg string interpolation. # Already should not fails syntax (checked earlier) - we don't check result code. - parseCli_2(Lines[DependencyArgsNR[gi]], args, Vars, reparsed) + parseCli_2(DependencyArgsL[gi], args, Vars, reparsed) argsCnt = reparsed[-7] - 3 # -7 holds len. Subtracting 3, because args start after `@depends_on pg @args` } diff --git a/tests/12_errors.tush b/tests/12_errors.tush index 30071cd..4dbe975 100644 --- a/tests/12_errors.tush +++ b/tests/12_errors.tush @@ -42,11 +42,11 @@ $ ./$MAKESURE -f tests/12_errors.sh @ tests/12_errors.sh:48: @goal @private @ nothing allowed after goal name: @ tests/12_errors.sh:51: @goal g15 should not have anything after goal name -@ nothing allowed after glob pattern: +@ nothing or @params allowed after glob pattern: @ tests/12_errors.sh:54: @goal g17 @glob '*.txt' should not have anything after glob pattern -@ nothing allowed after glob pattern: +@ nothing or @params allowed after glob pattern: @ tests/12_errors.sh:57: @goal @glob '*.txt' should not have anything after glob pattern -@ nothing allowed after glob pattern: +@ nothing or @params allowed after glob pattern: @ tests/12_errors.sh:58: @goal @glob '*.txt' should_not_have_anything_after_glob_pattern @ absent glob pattern: @ tests/12_errors.sh:61: @goal @glob # absent glob pattern diff --git a/tests/29_glob_plus_pg.tush b/tests/29_glob_plus_pg.tush new file mode 100644 index 0000000..09a9a37 --- /dev/null +++ b/tests/29_glob_plus_pg.tush @@ -0,0 +1,150 @@ + +$ ./$MAKESURE -f tests/29_glob_plus_pg_1.sh -l +| Available goals: +| g1 +| g2 +| g3 +| gpg@hello +| gpg@hi +| g3pg@salut +| gpg@salut + +$ ./$MAKESURE -f tests/29_glob_plus_pg_1.sh -la +| Available goals: +| g1 +| g2 +| g3 +| gpg@hello +| gpg@glob_test/1.txt@hello +| gpg@glob_test/2.txt@hello +| gpg@hi +| gpg@glob_test/1.txt@hi +| gpg@glob_test/2.txt@hi +| g3pg@salut +| gpg@salut +| gpg@glob_test/1.txt@salut +| gpg@glob_test/2.txt@salut + +$ ./$MAKESURE -f tests/29_glob_plus_pg_1.sh g1 +| goal 'gpg@glob_test/1.txt@hello' ... +| glob_test/1.txt hello +| goal 'gpg@glob_test/2.txt@hello' ... +| glob_test/2.txt hello +| goal 'gpg@hello' [empty]. +| goal 'g1' [empty]. + +$ ./$MAKESURE -f tests/29_glob_plus_pg_1.sh g2 +| goal 'gpg@glob_test/1.txt@hello' ... +| glob_test/1.txt hello +| goal 'gpg@glob_test/2.txt@hello' ... +| glob_test/2.txt hello +| goal 'gpg@hello' [empty]. +| goal 'gpg@glob_test/1.txt@hi' ... +| glob_test/1.txt hi +| goal 'gpg@glob_test/2.txt@hi' ... +| glob_test/2.txt hi +| goal 'gpg@hi' [empty]. +| goal 'g2' [empty]. + +$ ./$MAKESURE -f tests/29_glob_plus_pg_1.sh g3 +| goal 'gpg@glob_test/1.txt@salut' ... +| glob_test/1.txt salut +| goal 'gpg@glob_test/2.txt@salut' ... +| glob_test/2.txt salut +| goal 'gpg@salut' [empty]. +| goal 'g3pg@salut' [empty]. +| goal 'g3' [empty]. + +$ ./$MAKESURE -f tests/29_glob_plus_pg_2.sh -l +| Available goals: +| g1 +| g2 +| g3 +| 'glob_test/*.txt@hello' +| 'glob_test/*.txt@hi' +| g3pg@salut +| 'glob_test/*.txt@salut' + +$ ./$MAKESURE -f tests/29_glob_plus_pg_2.sh -la +| Available goals: +| g1 +| g2 +| g3 +| 'glob_test/*.txt@hello' +| glob_test/1.txt@hello +| glob_test/2.txt@hello +| 'glob_test/*.txt@hi' +| glob_test/1.txt@hi +| glob_test/2.txt@hi +| g3pg@salut +| 'glob_test/*.txt@salut' +| glob_test/1.txt@salut +| glob_test/2.txt@salut + +$ ./$MAKESURE -f tests/29_glob_plus_pg_2.sh g1 +| goal 'glob_test/1.txt@hello' ... +| glob_test/1.txt hello +| goal 'glob_test/2.txt@hello' ... +| glob_test/2.txt hello +| goal 'glob_test/*.txt@hello' [empty]. +| goal 'g1' [empty]. + +$ ./$MAKESURE -f tests/29_glob_plus_pg_2.sh g2 +| goal 'glob_test/1.txt@hello' ... +| glob_test/1.txt hello +| goal 'glob_test/2.txt@hello' ... +| glob_test/2.txt hello +| goal 'glob_test/*.txt@hello' [empty]. +| goal 'glob_test/1.txt@hi' ... +| glob_test/1.txt hi +| goal 'glob_test/2.txt@hi' ... +| glob_test/2.txt hi +| goal 'glob_test/*.txt@hi' [empty]. +| goal 'g2' [empty]. + +$ ./$MAKESURE -f tests/29_glob_plus_pg_2.sh g3 +| goal 'glob_test/1.txt@salut' ... +| glob_test/1.txt salut +| goal 'glob_test/2.txt@salut' ... +| glob_test/2.txt salut +| goal 'glob_test/*.txt@salut' [empty]. +| goal 'g3pg@salut' [empty]. +| goal 'g3' [empty]. + +$ ./$MAKESURE -f tests/29_glob_plus_pg_3.sh -l +| Available goals: +| g1 +| g2 +| g3 +| glob_test/1.txt@hello +| glob_test/1.txt@hi +| g3pg@salut +| glob_test/1.txt@salut + +$ ./$MAKESURE -f tests/29_glob_plus_pg_3.sh -la +| Available goals: +| g1 +| g2 +| g3 +| glob_test/1.txt@hello +| glob_test/1.txt@hi +| g3pg@salut +| glob_test/1.txt@salut + +$ ./$MAKESURE -f tests/29_glob_plus_pg_3.sh g1 +| goal 'glob_test/1.txt@hello' ... +| glob_test/1.txt hello +| goal 'g1' [empty]. + +$ ./$MAKESURE -f tests/29_glob_plus_pg_3.sh g2 +| goal 'glob_test/1.txt@hello' ... +| glob_test/1.txt hello +| goal 'glob_test/1.txt@hi' ... +| glob_test/1.txt hi +| goal 'g2' [empty]. + +$ ./$MAKESURE -f tests/29_glob_plus_pg_3.sh g3 +| goal 'glob_test/1.txt@salut' ... +| glob_test/1.txt salut +| goal 'g3pg@salut' [empty]. +| goal 'g3' [empty]. diff --git a/tests/29_glob_plus_pg_1.sh b/tests/29_glob_plus_pg_1.sh new file mode 100644 index 0000000..2b2abdf --- /dev/null +++ b/tests/29_glob_plus_pg_1.sh @@ -0,0 +1,16 @@ + +@goal gpg @glob 'glob_test/*.txt' @params P + echo "$ITEM $P" + +@goal g1 +@depends_on gpg @args 'hello' + +@goal g2 +@depends_on gpg @args 'hello' +@depends_on gpg @args 'hi' + +@goal g3 +@depends_on g3pg @args 'salut' + +@goal g3pg @params X +@depends_on gpg @args X diff --git a/tests/29_glob_plus_pg_2.sh b/tests/29_glob_plus_pg_2.sh new file mode 100644 index 0000000..9cc97fb --- /dev/null +++ b/tests/29_glob_plus_pg_2.sh @@ -0,0 +1,16 @@ + +@goal @glob 'glob_test/*.txt' @params P + echo "$ITEM $P" + +@goal g1 +@depends_on 'glob_test/*.txt' @args 'hello' + +@goal g2 +@depends_on 'glob_test/*.txt' @args 'hello' +@depends_on 'glob_test/*.txt' @args 'hi' + +@goal g3 +@depends_on g3pg @args 'salut' + +@goal g3pg @params X +@depends_on 'glob_test/*.txt' @args X diff --git a/tests/29_glob_plus_pg_3.sh b/tests/29_glob_plus_pg_3.sh new file mode 100644 index 0000000..67e1487 --- /dev/null +++ b/tests/29_glob_plus_pg_3.sh @@ -0,0 +1,16 @@ + +@goal @glob 'glob_test/1.txt' @params P + echo "$ITEM $P" + +@goal g1 +@depends_on 'glob_test/1.txt' @args 'hello' + +@goal g2 +@depends_on 'glob_test/1.txt' @args 'hello' +@depends_on 'glob_test/1.txt' @args 'hi' + +@goal g3 +@depends_on g3pg @args 'salut' + +@goal g3pg @params X +@depends_on 'glob_test/1.txt' @args X diff --git a/tests/glob_test/1.txt b/tests/glob_test/1.txt new file mode 100644 index 0000000..9d07aa0 --- /dev/null +++ b/tests/glob_test/1.txt @@ -0,0 +1 @@ +111 \ No newline at end of file diff --git a/tests/glob_test/2.txt b/tests/glob_test/2.txt new file mode 100644 index 0000000..6dd90d2 --- /dev/null +++ b/tests/glob_test/2.txt @@ -0,0 +1 @@ +222 \ No newline at end of file