Skip to content

Commit

Permalink
Merge pull request #32 from oalders/fso
Browse files Browse the repository at this point in the history
Add fso subcommand
  • Loading branch information
oalders authored Jun 9, 2024
2 parents a08b4a5 + feb4b34 commit c954d7b
Show file tree
Hide file tree
Showing 7 changed files with 132 additions and 9 deletions.
1 change: 0 additions & 1 deletion .golangci.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
---
linters:
disable:
- err113
- nlreturn
- typecheck
- wsl
Expand Down
68 changes: 62 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,13 @@ $ is known cli version --major zsh
### Has gofumpt been modified in the last week?

```text
$ is cli age gofumpt lt 7 d
is cli age gofumpt lt 7 d
```

### Has a file been modified in the last hour?

```text
is fso age ./stats.txt lt 1 h
```

### echo the OS name
Expand Down Expand Up @@ -183,7 +189,9 @@ is os version-codename unlike ventura

🚨 Leaky abstraction alert!

Regex patterns are passed directly to Golang's `regexp.MatchString`. We can take advantage of this when crafting regexes. For instance, for a case insensitive search:
Regex patterns are passed directly to Golang's `regexp.MatchString`. We can
take advantage of this when crafting regexes. For instance, for a case
insensitive search:

```text
is cli output stdout date like "(?i)wed"
Expand Down Expand Up @@ -392,14 +400,14 @@ Optional argument to command. Can be used more than once.

Let's match on the results of `uname -m -n`.

```
```bash
is cli output stdout uname --arg="-m" --arg="-n" eq "olafs-mbp-2.lan x86_64"
```

If our args don't contain special characters or spaces, we may not need to
quote them. Let's match on the results of `cat README.md`.

```
```bash
is cli output stdout cat --arg README.md like "an inspector for your environment"
```

Expand Down Expand Up @@ -463,15 +471,15 @@ is cli output stdout "bash -c" -a "date|wc -l" eq 1
Passing negative integers as expected values is a bit tricky, since we don't
want them to be interpreted as flags.

```
```bash
$ is cli output stdout 'bash -c' -a 'date|wc -l' gt -1
```

> 💥 is: error: unknown flag -1, did you mean one of "-h", "-a"?
We can use `--` before the expected value to get around this. 😅

```
```bash
$ is cli output stdout 'bash -c' -a 'date|wc -l' gt -- -1
```

Expand Down Expand Up @@ -502,6 +510,53 @@ in some cases try to do an optimistic comparison. That is, it will try a string
comparison first and then a numeric comparison. Hopefully this will "do the
right thing" for you. If not, please open an issue.

### fso

`fso` is short for filesystem object (file, directory, link, etc). This command
is very similar to `cli age`. The difference between `cli age` and `fso age` is
that `fso` will not search your `$PATH`. You may provide either a relative or
an absolute path.

#### age

Compare against the last modified date of a file.

```bash
is cli age /tmp/programs.csv lt 18 hours
```

Compare against the last modified date of a directory.

```bash
is cli age ~./local/cache gt 1 d
```

Supported comparisons are:

* `lt`
* `gt`

Supported units are:

* `s`
* `second`
* `seconds`
* `m`
* `minute`
* `minutes`
* `h`
* `hour`
* `hours`
* `d`
* `day`
* `days`

Note that `d|day|days` is shorthand for 24 hours. DST offsets are not taken
into account here.

The `--debug` flag can give us some helpful information when troubleshooting
date math.

### os

Information specific to the current operating system
Expand Down Expand Up @@ -835,6 +890,7 @@ $ is known cli version --minor tmux
$ is known cli version --patch tmux
0
```

Please see the docs on `os version` for more information on `--major`,
`--minor` and `--patch`.

Expand Down
7 changes: 7 additions & 0 deletions api.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,13 @@ type CLICmd struct {
Output OutputCmp `cmd:"" help:"Check output of a command. e.g. \"is cli output stdout \"uname -a\" like \"Kernel Version 22.5\""`
}

// FSOCmd type is configuration for FSO checks.
//
//nolint:lll
type FSOCmd struct {
Age AgeCmp `cmd:"" help:"Check age (last modified time) of an fso (2h, 4d). e.g. \"is fso age /tmp/log.txt gt 1 d\""`
}

// OSCmd type is configuration for OS level checks.
//
//nolint:lll
Expand Down
7 changes: 5 additions & 2 deletions cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func execCommand(ctx *types.Context, stream, cmd string, args []string) (string,
// Run "is cli ...".
func (r *CLICmd) Run(ctx *types.Context) error {
if r.Age.Name != "" {
return runAge(ctx, r.Age.Name, r.Age.Op, r.Age.Val, r.Age.Unit)
return runCliAge(ctx, r.Age.Name, r.Age.Op, r.Age.Val, r.Age.Unit)
}
if r.Version.Name != "" {
output, err := parser.CLIOutput(ctx, r.Version.Name)
Expand Down Expand Up @@ -96,12 +96,15 @@ func compareAge(ctx *types.Context, modTime, targetTime time.Time, operator, pat
}
}

func runAge(ctx *types.Context, name, ageOperator, ageValue, ageUnit string) error {
func runCliAge(ctx *types.Context, name, ageOperator, ageValue, ageUnit string) error {
path, err := exec.LookPath(name)
if err != nil {
return errors.Join(errors.New("could not find command"), err)
}
return runAge(ctx, path, ageOperator, ageValue, ageUnit)
}

func runAge(ctx *types.Context, path, ageOperator, ageValue, ageUnit string) error {
info, err := os.Stat(path)
if err != nil {
return errors.Join(errors.New("could not stat command"), err)
Expand Down
15 changes: 15 additions & 0 deletions fso.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Package main contains the logic for the "fso" command
package main

import (
"errors"

"github.com/oalders/is/types"
)

func (r *FSOCmd) Run(ctx *types.Context) error {
if r.Age.Name != "" {
return runAge(ctx, r.Age.Name, r.Age.Op, r.Age.Val, r.Age.Unit)
}
return errors.New("unimplemented command")
}
42 changes: 42 additions & 0 deletions fso_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package main

import (
"testing"

"github.com/oalders/is/ops"
"github.com/oalders/is/types"
"github.com/stretchr/testify/assert"
)

func TestFSOLastModifiedTime(t *testing.T) {
t.Parallel()
const tmux = "testdata/bin/tmux"
{
ctx := types.Context{Debug: true}
cmd := FSOCmd{Age: AgeCmp{tmux, ops.Gt, "1", "s"}}
err := cmd.Run(&ctx)
assert.NoError(t, err)
assert.True(t, ctx.Success)
}
{
ctx := types.Context{Debug: true}
cmd := FSOCmd{Age: AgeCmp{tmux, ops.Lt, "100000", "days"}}
err := cmd.Run(&ctx)
assert.NoError(t, err)
assert.True(t, ctx.Success)
}
{
ctx := types.Context{Debug: true}
cmd := FSOCmd{Age: AgeCmp{tmux, ops.Lt, "1.1", "d"}}
err := cmd.Run(&ctx)
assert.Error(t, err)
assert.False(t, ctx.Success)
}
{
ctx := types.Context{Debug: true}
cmd := FSOCmd{Age: AgeCmp{"tmuxxx", ops.Lt, "1", "d"}}
err := cmd.Run(&ctx)
assert.Error(t, err)
assert.False(t, ctx.Success)
}
}
1 change: 1 addition & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ func main() {
Arch ArchCmd `cmd:"" help:"Check arch e.g. \"is arch like x64\""`
CLI CLICmd `cmd:"" help:"Check cli version. e.g. \"is cli version tmux gte 3\""`
Debug bool `help:"turn on debugging statements"`
FSO FSOCmd `cmd:"" help:"Check fso (file system object). e.g. \"is fso age gte 3 days\""` //nolint:lll
Known KnownCmd `cmd:""`
OS OSCmd `cmd:"" help:"Check OS attributes. e.g. \"is os name eq darwin\""`
There ThereCmd `cmd:"" help:"Check if command exists. e.g. \"is there git\""`
Expand Down

0 comments on commit c954d7b

Please sign in to comment.