Skip to content

Commit

Permalink
docs/howto: use path.{Base,Dir,Ext} to examine paths
Browse files Browse the repository at this point in the history
This adds a Commented CUE guide that demonstrates how to use path.Base,
path.Dir, and path.Ext to access components of a file's name and path.

A single guide was preferred, rather than 3 separate documents, to more
accessibly display the relationship and potential overlap between the
values the functions emit when given specific inputs.

Only one example is laid out in full to demonstrate the function calls,
at the top of the guide. Several examples are added via comprehensions
in order to provide the reader with information about potential corner
case output. The OS flavour parameter is deliberately *not* incorporated
into a top-level loop so that the reader has direct visibility into the
form that Windows path-specific function calls take; without having to
mentally unroll the putative loop to infer the "path.Windows" value.

Preview-Path: /docs/howto/use-the-builtin-functions-path-base-path-dir-path-ext-to-examine-path-filename-components/
Signed-off-by: Jonathan Matthews <[email protected]>
Change-Id: I0c80c4fea19b018c902bcc3ffecefb7509083ca1
  • Loading branch information
jpluscplusm committed Jan 11, 2024
1 parent c136777 commit c6cb68b
Show file tree
Hide file tree
Showing 4 changed files with 378 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
---
title: Using the builtin functions "path.Base", "path.Dir", and "path.Ext" to examine path and filename components
tags:
- commented cue
authors:
- jpluscplusm
toc_hide: true
---

This [Commented CUE]({{< relref "docs/howto#commented-cue-guides" >}})
demonstrates how to use the builtin functions `path.Base`, `path.Dir`, and
`path.Ext` to access components of a file's name and its path.

{{{with code "en" "cc"}}}
# eval is used so the output's leaf values are horizontally aligned, allowing
# the user to more easily compare "Path" and "Dir" values visually
exec cue eval -e output
cmp stdout out
-- file.cue --
package example

import "path"

output: unix: fileAbsolutePath: {
Path: "/foo/bar/baz.js"

// path.Dir, path.Base and path.Ext need
// to be told their input path's OS type,
// via their 2nd parameter

// path.Dir emits every component of the
// path's directory
Dir: path.Dir(Path, path.Unix)

// path.Base emits the path's final
// component, regardless of if it
// represents a file or a directory
Base: path.Base(Path, path.Unix)

// path.Ext emits the path's filename
// extension, but *only* if the path
// represents a file
Ext: path.Ext(Path, path.Unix)
}

examples: unix: {
fileAbsolutePath: "/foo/bar/baz.js"
fileRelativePath: "bar/baz.js.backup"
fileNoExtension: "/foo/bar/baz"
dirAbsolutePath: "/foo/bar/baz/"
dirWithExtension: "/foo/bar/baz.dir/"
dirWithTraversal: "/foo/bar/../quux/a.js"
fileDirtyPath: "/foo///bar////baz.js"
}
examples: windows: {
fileAbsolutePath: #"C:\foo\bar\baz.js"#
fileRelativePath: #"bar\baz.js.backup"#
fileNoExtension: #"C:\foo\bar\baz"#
dirAbsolutePath: #"C:\foo\bar\baz\"#
dirWithExtension: #"C:\foo\bar\baz.dir\"#
dirWithTraversal: #"C:\foo\bar\..\quux\a.js"#
fileDirtyPath: #"C:\foo\\bar\\\baz.js"#
}

output: unix: {for _id, _path in examples.unix {(_id): {
Path: _path
Dir: path.Dir(_path, path.Unix)
Base: path.Base(_path, path.Unix)
Ext: path.Ext(_path, path.Unix)
}}}
output: windows: {for _id, _path in examples.windows {(_id): {
Path: _path
Dir: path.Dir(_path, path.Windows)
Base: path.Base(_path, path.Windows)
Ext: path.Ext(_path, path.Windows)
}}}
-- out --
unix: {
fileAbsolutePath: {
Path: "/foo/bar/baz.js"
Dir: "/foo/bar"
Base: "baz.js"
Ext: ".js"
}
fileRelativePath: {
Path: "bar/baz.js.backup"
Dir: "bar"
Base: "baz.js.backup"
Ext: ".backup"
}
fileNoExtension: {
Path: "/foo/bar/baz"
Dir: "/foo/bar"
Base: "baz"
Ext: ""
}
dirAbsolutePath: {
Path: "/foo/bar/baz/"
Dir: "/foo/bar/baz"
Base: "baz"
Ext: ""
}
dirWithExtension: {
Path: "/foo/bar/baz.dir/"
Dir: "/foo/bar/baz.dir"
Base: "baz.dir"
Ext: ""
}
dirWithTraversal: {
Path: "/foo/bar/../quux/a.js"
Dir: "/foo/quux"
Base: "a.js"
Ext: ".js"
}
fileDirtyPath: {
Path: "/foo///bar////baz.js"
Dir: "/foo/bar"
Base: "baz.js"
Ext: ".js"
}
}
windows: {
fileAbsolutePath: {
Path: "C:\\foo\\bar\\baz.js"
Dir: "C:\\foo\\bar"
Base: "baz.js"
Ext: ".js"
}
fileRelativePath: {
Path: "bar\\baz.js.backup"
Dir: "bar"
Base: "baz.js.backup"
Ext: ".backup"
}
fileNoExtension: {
Path: "C:\\foo\\bar\\baz"
Dir: "C:\\foo\\bar"
Base: "baz"
Ext: ""
}
dirAbsolutePath: {
Path: "C:\\foo\\bar\\baz\\"
Dir: "C:\\foo\\bar\\baz"
Base: "baz"
Ext: ""
}
dirWithExtension: {
Path: "C:\\foo\\bar\\baz.dir\\"
Dir: "C:\\foo\\bar\\baz.dir"
Base: "baz.dir"
Ext: ""
}
dirWithTraversal: {
Path: "C:\\foo\\bar\\..\\quux\\a.js"
Dir: "C:\\foo\\quux"
Base: "a.js"
Ext: ".js"
}
fileDirtyPath: {
Path: "C:\\foo\\\\bar\\\\\\baz.js"
Dir: "C:\\foo\\bar"
Base: "baz.js"
Ext: ".js"
}
}
{{{end}}}

## Related content

- The [`path`](https://pkg.go.dev/cuelang.org/go/pkg/path) builtin package
documentation details the rules that each of the functions
[`path.Base`](https://pkg.go.dev/cuelang.org/[email protected]/pkg/path#Base),
[`path.Dir`](https://pkg.go.dev/cuelang.org/[email protected]/pkg/path#Dir), and
[`path.Ext`](https://pkg.go.dev/cuelang.org/[email protected]/pkg/path#Ext) follow
as they process their input
- Using CUE's ["raw" strings]({{< relref "docs/tour/types/stringraw" >}}) is
convenient when writing literal Windows paths. They avoid having to escape
every backslash (`\\`) - as is demonstrated above in the `examples.windows`
struct inside `file.cue`
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package site
{
content: {
docs: {
howto: {
"use-the-builtin-functions-path-base-path-dir-path-ext-to-examine-path-filename-components": {
page: {
cache: {
code: {
cc: "Rf1XI25CxOVp9/NGjQz3elOoablgz2OTWIPxWkgH96w="
}
}
}
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package site

content: docs: howto: "use-the-builtin-functions-path-base-path-dir-path-ext-to-examine-path-filename-components": {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
---
title: Using the builtin functions "path.Base", "path.Dir", and "path.Ext" to examine path and filename components
tags:
- commented cue
authors:
- jpluscplusm
toc_hide: true
---

This [Commented CUE]({{< relref "docs/howto#commented-cue-guides" >}})
demonstrates how to use the builtin functions `path.Base`, `path.Dir`, and
`path.Ext` to access components of a file's name and its path.

{{< code-tabs >}}
{{< code-tab name="file.cue" language="cue" area="top-left" >}}
package example

import "path"

output: unix: fileAbsolutePath: {
Path: "/foo/bar/baz.js"

// path.Dir, path.Base and path.Ext need
// to be told their input path's OS type,
// via their 2nd parameter

// path.Dir emits every component of the
// path's directory
Dir: path.Dir(Path, path.Unix)

// path.Base emits the path's final
// component, regardless of if it
// represents a file or a directory
Base: path.Base(Path, path.Unix)

// path.Ext emits the path's filename
// extension, but *only* if the path
// represents a file
Ext: path.Ext(Path, path.Unix)
}

examples: unix: {
fileAbsolutePath: "/foo/bar/baz.js"
fileRelativePath: "bar/baz.js.backup"
fileNoExtension: "/foo/bar/baz"
dirAbsolutePath: "/foo/bar/baz/"
dirWithExtension: "/foo/bar/baz.dir/"
dirWithTraversal: "/foo/bar/../quux/a.js"
fileDirtyPath: "/foo///bar////baz.js"
}
examples: windows: {
fileAbsolutePath: #"C:\foo\bar\baz.js"#
fileRelativePath: #"bar\baz.js.backup"#
fileNoExtension: #"C:\foo\bar\baz"#
dirAbsolutePath: #"C:\foo\bar\baz\"#
dirWithExtension: #"C:\foo\bar\baz.dir\"#
dirWithTraversal: #"C:\foo\bar\..\quux\a.js"#
fileDirtyPath: #"C:\foo\\bar\\\baz.js"#
}

output: unix: {for _id, _path in examples.unix {(_id): {
Path: _path
Dir: path.Dir(_path, path.Unix)
Base: path.Base(_path, path.Unix)
Ext: path.Ext(_path, path.Unix)
}}}
output: windows: {for _id, _path in examples.windows {(_id): {
Path: _path
Dir: path.Dir(_path, path.Windows)
Base: path.Base(_path, path.Windows)
Ext: path.Ext(_path, path.Windows)
}}}
{{< /code-tab >}}
{{< code-tab name="TERMINAL" language="" type="terminal" area="top-right" >}}
$ cue eval -e output
unix: {
fileAbsolutePath: {
Path: "/foo/bar/baz.js"
Dir: "/foo/bar"
Base: "baz.js"
Ext: ".js"
}
fileRelativePath: {
Path: "bar/baz.js.backup"
Dir: "bar"
Base: "baz.js.backup"
Ext: ".backup"
}
fileNoExtension: {
Path: "/foo/bar/baz"
Dir: "/foo/bar"
Base: "baz"
Ext: ""
}
dirAbsolutePath: {
Path: "/foo/bar/baz/"
Dir: "/foo/bar/baz"
Base: "baz"
Ext: ""
}
dirWithExtension: {
Path: "/foo/bar/baz.dir/"
Dir: "/foo/bar/baz.dir"
Base: "baz.dir"
Ext: ""
}
dirWithTraversal: {
Path: "/foo/bar/../quux/a.js"
Dir: "/foo/quux"
Base: "a.js"
Ext: ".js"
}
fileDirtyPath: {
Path: "/foo///bar////baz.js"
Dir: "/foo/bar"
Base: "baz.js"
Ext: ".js"
}
}
windows: {
fileAbsolutePath: {
Path: "C:\\foo\\bar\\baz.js"
Dir: "C:\\foo\\bar"
Base: "baz.js"
Ext: ".js"
}
fileRelativePath: {
Path: "bar\\baz.js.backup"
Dir: "bar"
Base: "baz.js.backup"
Ext: ".backup"
}
fileNoExtension: {
Path: "C:\\foo\\bar\\baz"
Dir: "C:\\foo\\bar"
Base: "baz"
Ext: ""
}
dirAbsolutePath: {
Path: "C:\\foo\\bar\\baz\\"
Dir: "C:\\foo\\bar\\baz"
Base: "baz"
Ext: ""
}
dirWithExtension: {
Path: "C:\\foo\\bar\\baz.dir\\"
Dir: "C:\\foo\\bar\\baz.dir"
Base: "baz.dir"
Ext: ""
}
dirWithTraversal: {
Path: "C:\\foo\\bar\\..\\quux\\a.js"
Dir: "C:\\foo\\quux"
Base: "a.js"
Ext: ".js"
}
fileDirtyPath: {
Path: "C:\\foo\\\\bar\\\\\\baz.js"
Dir: "C:\\foo\\bar"
Base: "baz.js"
Ext: ".js"
}
}
{{< /code-tab >}}
{{< /code-tabs >}}

## Related content

- The [`path`](https://pkg.go.dev/cuelang.org/go/pkg/path) builtin package
documentation details the rules that each of the functions
[`path.Base`](https://pkg.go.dev/cuelang.org/[email protected]/pkg/path#Base),
[`path.Dir`](https://pkg.go.dev/cuelang.org/[email protected]/pkg/path#Dir), and
[`path.Ext`](https://pkg.go.dev/cuelang.org/[email protected]/pkg/path#Ext) follow
as they process their input
- Using CUE's ["raw" strings]({{< relref "docs/tour/types/stringraw" >}}) is
convenient when writing literal Windows paths. They avoid having to escape
every backslash (`\\`) - as is demonstrated above in the `examples.windows`
struct inside `file.cue`

0 comments on commit c6cb68b

Please sign in to comment.