T
Task2mo ago
Keb

Equivalence between sources and generates

Hello! Okay, this might be a strange use case since it's not really supported by any build system that I know of. I would want to map the sources to the generates. Take the following example:
PSD-to-PNG:
sources:
- psd/**/*.psd
generates:
- png/**/*.png
cmds:
- for: sources
cmd: convert {{.ITEM}} TARGET
PSD-to-PNG:
sources:
- psd/**/*.psd
generates:
- png/**/*.png
cmds:
- for: sources
cmd: convert {{.ITEM}} TARGET
If I have a file psd/sprite/enemy.psd (here an iteration of {{.ITEM}}), I would like to create png/sprite/enemy.png (here TARGET), knowing that at first my png folder is empty. I don't know if there's a simple way to get this TARGET, except with regexps that would defeat the purpose of readability (and not depend on generates at all...). I wonder if there's a simpler way to achieve that? Thanks!
8 Replies
andreynering
andreynering2mo ago
Hey @Keb, Take a look at loops. That's probably what you're looking for. https://taskfile.dev/usage/#looping-over-your-tasks-sources-or-generated-files
Keb
KebOP2mo ago
hey, for what I understand, there’s no way to loop to a sources and generates at the same time, right?
andreynering
andreynering2mo ago
No, bug if both files follow the same pattern, like in your example where just the extension changes, you can loop over sources and manipulate the string to get the right generated path
Keb
KebOP2mo ago
yeah, in a simple case like this it’s a simple regexp (something like {{regexpMatchAll png psd}}) but sometimes it’s more complicated (like png/**/*.png to src/img/**/*.c), and it would get quite messy so I was wondering if there was another way (like getting the generates, easily decomposing the path, etc)
andreynering
andreynering2mo ago
Task has some builtin path manipulation function that you can use inside templates: https://go-task.github.io/slim-sprig/paths.html
slim-sprig
Path and Filepath Functions
Useful template functions for Go templates.
Keb
KebOP2mo ago
thanks, I was able to progress quite a lot with this. however, it's quite heavy in terms of repetitive function calling, so I'm wondering if there's a way to simplify this. here's an example:
png-to-tileset:
sources:
- png/**/tileset*.png
generates:
- src/img/**/tileset*.c
cmds:
- for: sources
task: png2asset-tileset
vars: { SOURCE: "{{.ITEM}}", TARGET: 'src/img/{{ regexReplaceAll "png/" .ITEM "${1}" | dir }}/{{ regexReplaceAll "png" .ITEM "${1}c" | base }}' }

png2asset-tileset:
cmds:
- echo mkdir -p {{ dir .TARGET }}
- echo png2asset {{.SOURCE}} -map -tiles_only -noflip -no_palettes -keep_duplicate_tiles -o {{.TARGET}}

png-to-metasprite:
sources:
- png/sprites/metasprite*.png
generates:
- src/img/**/metasprite*.c
cmds:
- for: sources
task: png2asset-metasprite
vars: { SOURCE: "{{.ITEM}}", TARGET: 'src/img/{{ regexReplaceAll "png/" .ITEM "${1}" | dir }}/{{ regexReplaceAll "png" .ITEM "${1}c" | base }}' }

png2asset-metasprite:
cmds:
- echo mkdir -p {{ dir .TARGET }}
- echo png2asset {{.SOURCE}} -sw 16 -sh 16 -pw 8 -ph 8 -spr8x16 -no_palettes -o ${{.TARGET}}
png-to-tileset:
sources:
- png/**/tileset*.png
generates:
- src/img/**/tileset*.c
cmds:
- for: sources
task: png2asset-tileset
vars: { SOURCE: "{{.ITEM}}", TARGET: 'src/img/{{ regexReplaceAll "png/" .ITEM "${1}" | dir }}/{{ regexReplaceAll "png" .ITEM "${1}c" | base }}' }

png2asset-tileset:
cmds:
- echo mkdir -p {{ dir .TARGET }}
- echo png2asset {{.SOURCE}} -map -tiles_only -noflip -no_palettes -keep_duplicate_tiles -o {{.TARGET}}

png-to-metasprite:
sources:
- png/sprites/metasprite*.png
generates:
- src/img/**/metasprite*.c
cmds:
- for: sources
task: png2asset-metasprite
vars: { SOURCE: "{{.ITEM}}", TARGET: 'src/img/{{ regexReplaceAll "png/" .ITEM "${1}" | dir }}/{{ regexReplaceAll "png" .ITEM "${1}c" | base }}' }

png2asset-metasprite:
cmds:
- echo mkdir -p {{ dir .TARGET }}
- echo png2asset {{.SOURCE}} -sw 16 -sh 16 -pw 8 -ph 8 -spr8x16 -no_palettes -o ${{.TARGET}}
I need to make calls, with different sources and generates, to png2asset, with different parameters. These are just two examples, I have a few more. As you can see, my TARGET: 'src/img/{{ regexReplaceAll "png/" .ITEM "${1}" | dir }}/{{ regexReplaceAll "png" .ITEM "${1}c" | base }}' is the same in my two different tasks. I wonder if there's a way I can have this written only once, so that it is easier to maintain. Apart from this, it is quite easy and readable. (for easier understanding, here are one example of each task output:
mkdir -p src/img/map-level-1
png2asset png/map-level-1/tileset-level-1.png -map -tiles_only -noflip -no_palettes -keep_duplicate_tiles -o src/img/map-level-1/tileset-level-1.c
mkdir -p src/img/map-level-1
png2asset png/map-level-1/tileset-level-1.png -map -tiles_only -noflip -no_palettes -keep_duplicate_tiles -o src/img/map-level-1/tileset-level-1.c
mkdir -p src/img/sprites
png2asset png/sprites/metasprite-butterfly.png -sw 16 -sh 16 -pw 8 -ph 8 -spr8x16 -no_palettes -o /img/sprites/metasprite-butterfly.c
mkdir -p src/img/sprites
png2asset png/sprites/metasprite-butterfly.png -sw 16 -sh 16 -pw 8 -ph 8 -spr8x16 -no_palettes -o /img/sprites/metasprite-butterfly.c
)
andreynering
andreynering2mo ago
slim-sprig
String Functions
Useful template functions for Go templates.
slim-sprig
String Slice Functions
Useful template functions for Go templates.
slim-sprig
Path and Filepath Functions
Useful template functions for Go templates.
Keb
KebOP2mo ago
thanks, I will look into it! there’s no way to save my string operations somewhere and give them the .ITEM as a parameter or something like this to have some reusability? another question, I cannot use shopt globstar and these string functions. i would like to do something like (simplified):
source-to-obj:
sources:
- src/**/*.c
cmds:
- mkdir -p {{ dir src/**/*.c | replace "src" "build" }}
source-to-obj:
sources:
- src/**/*.c
cmds:
- mkdir -p {{ dir src/**/*.c | replace "src" "build" }}
but this doesn't work of course globstar is activated and it works for my C files (src/**/*.c) actually I don't need it, but still curious if there's a way to do this!

Did you find this page helpful?