Skip to content

Commit

Permalink
preprocessor: require absolute paths for upload files
Browse files Browse the repository at this point in the history
When a file is uploaded, it is currently uploaded relative to the
current working directory of a multi-step script. For example, if a
script step changes directory, subsequent uploads (with relative paths)
are processed relative to that new working directory. This is incredibly
confusing and wrong, because it is entirely counter to the expectation
of the script writer who is most likely expecting txtar-like semantics.

Switch to those semantics, that the txtar-specified file is relative to
the starting working directory ($HOME) unless specified as absolute.

This requires a fix in
content/docs/tutorial/validating-simple-yaml-files/en.md which was
relying on the broken previous behaviour.

Preprocessor-No-Write-Cache: true
Signed-off-by: Paul Jolly <[email protected]>
Change-Id: I83d07aec141e52acc08b5ed54671d7a3cf97adbd
Dispatch-Trailer: {"type":"trybot","CL":1176743,"patchset":8,"ref":"refs/changes/43/1176743/8","targetBranch":"alpha"}
  • Loading branch information
myitcv authored and cueckoo committed Feb 12, 2024
1 parent e80816d commit 8f4d9b3
Show file tree
Hide file tree
Showing 5 changed files with 124 additions and 14 deletions.
8 changes: 4 additions & 4 deletions content/docs/tutorial/validating-simple-yaml-files/en.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ Place this information in it, including the deliberate mistake in the `species`
field:

{{{with upload "en" "yamlBroken"}}}
-- charlie.yml --
-- validating-yaml-with-cue/charlie.yml --
name:
first: Charlie
last: Cartwright
Expand All @@ -79,7 +79,7 @@ Create a file called `pets.cue` to hold your schema, and place this CUE in it:

{{{with upload "en" "pets.cue"}}}
#codetab(pets.cue) linenos="table"
-- pets.cue --
-- validating-yaml-with-cue/pets.cue --
species!: "cat" | "dog"
age?: number
{{{end}}}
Expand Down Expand Up @@ -151,7 +151,7 @@ Update `charlie.yml` to:
Your corrected data file should read as follows:

{{{with upload "en" "yamlFixed"}}}
-- charlie.yml --
-- validating-yaml-with-cue/charlie.yml --
name:
first: Charlie
last: Cartwright
Expand Down Expand Up @@ -189,7 +189,7 @@ Add a second data file containing the details of another pet.
Create a data file named `toby.yml` to hold Toby the dog's details:

{{{with upload "en" "yaml2"}}}
-- toby.yml --
-- validating-yaml-with-cue/toby.yml --
name:
first: Toby
last: Dog
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ Create a data file named `charlie.yml` to hold Charlie the cat's details.
Place this information in it, including the deliberate mistake in the `species`
field:

```yml { title="charlie.yml" }
```yml { title="validating-yaml-with-cue/charlie.yml" }
name:
first: Charlie
last: Cartwright
Expand All @@ -77,7 +77,7 @@ age: "15"
{{< step stepNumber="4" >}}
Create a file called `pets.cue` to hold your schema, and place this CUE in it:

```cue { title="pets.cue" linenos="table" }
```cue { title="validating-yaml-with-cue/pets.cue" }
species!: "cat" | "dog"
age?: number
```
Expand Down Expand Up @@ -158,7 +158,7 @@ Update `charlie.yml` to:

Your corrected data file should read as follows:

```yml { title="charlie.yml" }
```yml { title="validating-yaml-with-cue/charlie.yml" }
name:
first: Charlie
last: Cartwright
Expand Down Expand Up @@ -195,7 +195,7 @@ Add a second data file containing the details of another pet.

Create a data file named `toby.yml` to hold Toby the dog's details:

```yml { title="toby.yml" }
```yml { title="validating-yaml-with-cue/toby.yml" }
name:
first: Toby
last: Dog
Expand Down
28 changes: 23 additions & 5 deletions internal/cmd/preprocessor/cmd/rootfile.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ import (
"math/rand"
"os"
"os/exec"
"path"
"path/filepath"
"runtime"
"slices"
Expand Down Expand Up @@ -433,21 +432,40 @@ func (rf *rootFile) buildMultistepScript() (*multiStepScript, error) {
f := n.effectiveArchive.Files[0]

cmdEchoFence := rf.getFence()

// The upload target path provided via the txtar filename _might_ be
// absolute. We don't know. In case it is, we should treat it as
// such. Otherwise, as a convenience we treat it as relative to the
// starting working directory of the script, i.e. $HOME. The problem
// is that we can only determine if the target is absolute in the script
// itself (allowing for env var expansion, etc). So we use a unique
// variable name to store the target file path, which is made absolute
// as required.
targetFileVar := "target" + rf.getFence()
pf("if [[ \"%s\" != /* ]]; then %s=$HOME/%s; else %s=%s; fi\n", f.Name, targetFileVar, f.Name, targetFileVar, f.Name)

// First echo the commands that we will run to make debugging
// easier. Notice this block is surrounded in a no-interpolation
// cat using a pseudo-random string fence.
pf("cat <<'%s'\n", cmdEchoFence)
if strings.Contains(f.Name, "/") {
pf("$ mkdir -p '%s'\n", path.Dir(f.Name))
pf("$ mkdir -p $(dirname $%s)\n", targetFileVar)
}
pf("$ cat <<EOD > %s\n", f.Name)
pf("$ cat <<EOD > $%s\n", targetFileVar)
pf("%s\n", f.Data)
pf("EOD\n")
pf("%s\n", cmdEchoFence)

// Now write the actual commands to the file.
fence := rf.getFence()
if strings.Contains(f.Name, "/") {
pf("mkdir -p '%s'\n", path.Dir(f.Name))
pf("mkdir -p $(dirname $%s)\n", targetFileVar)
}
pf("cat <<'%s' > %s\n", fence, f.Name)
pf("cat <<'%s' > $%s\n", fence, targetFileVar)
pf("%s\n", f.Data)
pf("%s\n", fence)

// Check the exist code
pf("%s=$?\n", exitCodeVar)
pf("if [[ $%s -ne 0 ]]\n", exitCodeVar)
pf("then\n")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
# Ensure that we create uploaded files in the right place,
# regardless of working directory at the time of the upload.

unquote content/dir/en.md

exec preprocessor execute

cmp hugo/content/en/dir/index.md golden/hugo/content/en/dir/index.md

-- hugo/.keep --
-- content/site.cue --
package site
-- content/dir/page.cue --
package site

content: dir: page: {
leftDelim: "{{{"
rightDelim: "}}}"
}
-- content/dir/en.md --
>---
>title: JSON Superset
>---
>
>{{{with script "en" "1"}}}
>find $HOME -type f | sort
>{{{end}}}
>
>{{{with upload "en" "2"}}}
>-- one.txt --
>{{{end}}}
>{{{with upload "en" "3"}}}
>-- another/two.txt --
>{{{end}}}
>
>{{{with script "en" "4"}}}
>find $HOME -type f | sort
>cd another
>{{{end}}}
>
>{{{with upload "en" "5"}}}
>-- one.txt --
>{{{end}}}
>{{{with upload "en" "6"}}}
>-- another/two.txt --
>{{{end}}}
>
>{{{with script "en" "7"}}}
>find $HOME -type f | sort
>{{{end}}}
>
-- golden/hugo/content/en/dir/index.md --
---
title: JSON Superset
---

```text { title="TERMINAL" codeToCopy="ZmluZCAkSE9NRSAtdHlwZSBmIHwgc29ydAo=" }
$ find $HOME -type f | sort
/home/runner/.bash_logout
/home/runner/.bashrc
/home/runner/.profile
```

```txt { title="one.txt" }
```
```txt { title="another/two.txt" }
```

```text { title="TERMINAL" codeToCopy="ZmluZCAkSE9NRSAtdHlwZSBmIHwgc29ydApjZCBhbm90aGVyCg==" }
$ find $HOME -type f | sort
/home/runner/.bash_logout
/home/runner/.bashrc
/home/runner/.profile
/home/runner/another/two.txt
/home/runner/one.txt
$ cd another
```

```txt { title="one.txt" }
```
```txt { title="another/two.txt" }
```

```text { title="TERMINAL" codeToCopy="ZmluZCAkSE9NRSAtdHlwZSBmIHwgc29ydAo=" }
$ find $HOME -type f | sort
/home/runner/.bash_logout
/home/runner/.bashrc
/home/runner/.profile
/home/runner/another/two.txt
/home/runner/one.txt
```

Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ package site
"in-subdir": "Zwiy4x77+BFu61goz1QtYAalWU2pz5BnNGntPD/6asM="
}
multi_step: {
"377NPLQLLSANR3SP4BDR88KQU32BUBAPDARQ3K4LHMK8MF2VI6F0====": [{
"CCDBDCU5E1MLC2JR58VL9NCT6F49M45C3U8H598PETOOFTBJCR1G====": [{
doc: """
# script doc comment
#scripttag
Expand Down

0 comments on commit 8f4d9b3

Please sign in to comment.