Skip to content

Commit

Permalink
Add support for processing multiple input lines
Browse files Browse the repository at this point in the history
- add support for reading input URLs from a file
- add support for reading input URLs from stdin
- retain interactive prompt if no input given
- remove leading explanation text from results
- emit URL parsing failure text to stderr, continue
  processing URLs
  - allow for batch operation
  - allow for splitting success results and error output
    across different files
- refactor output and decoding logic
- refresh README coverage
  - add new support for processing standard input
  - add new flags
  - update examples

refs GH-78
  • Loading branch information
atc0005 committed Aug 25, 2023
1 parent 1f22980 commit 206d19f
Show file tree
Hide file tree
Showing 5 changed files with 211 additions and 63 deletions.
88 changes: 60 additions & 28 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,14 @@ Go-based tooling to manipulate (e.g., normalize/decode) Microsoft Office 365
- [`usl`](#usl)
- [Flags](#flags)
- [Positional Argument](#positional-argument)
- [Standard input (e.g., "piping")](#standard-input-eg-piping)
- [Just Hit Enter](#just-hit-enter)
- [Examples](#examples)
- [Using positional argument](#using-positional-argument)
- [Using flag](#using-flag)
- [Using url positional argument](#using-url-positional-argument)
- [Using url flag](#using-url-flag)
- [Using input prompt](#using-input-prompt)
- [Using standard input (e.g., "piping")](#using-standard-input-eg-piping)
- [Using filename flag](#using-filename-flag)
- [Verbose output](#verbose-output)
- [License](#license)
- [References](#references)
Expand All @@ -58,8 +61,13 @@ This repo is intended to provide various tools used to monitor processes.

Small CLI tool for decoding a given Safe Links URL.

- Specify Safe Links URL via CLI argument or flag

- Specify single Safe Links URL
- via positional argument
- via flag
- via interactive prompt
- Specify multiple Safe Links URLs
- via standard input ("piping")
- via file (using flag)
- Optional verbose listing of query parameter values within a given Safe Links
URL.

Expand Down Expand Up @@ -167,15 +175,16 @@ binaries.

##### Flags

| Flag | Required | Default | Repeat | Possible | Description |
| -------------- | -------- | ------- | ------ | -------------- | ----------------------------------------------------------------------------- |
| `h`, `help` | No | `false` | No | `h`, `help` | Show Help text along with the list of supported flags. |
| `version` | No | `false` | No | `version` | Whether to display application version and then immediately exit application. |
| `v`, `verbose` | No | `false` | No | `v`, `verbose` | Display additional information about a given Safe Links URL. |
| `u`, `url` | *maybe* | | No | `u`, `url` | Safe Links URL to decode |
| Flag | Required | Default | Repeat | Possible | Description |
| ---------------- | -------- | ------- | ------ | -------------------- | ----------------------------------------------------------------------------- |
| `h`, `help` | No | `false` | No | `h`, `help` | Show Help text along with the list of supported flags. |
| `version` | No | `false` | No | `version` | Whether to display application version and then immediately exit application. |
| `v`, `verbose` | No | `false` | No | `v`, `verbose` | Display additional information about a given Safe Links URL. |
| `u`, `url` | *maybe* | | No | `u`, `url` | Safe Links URL to decode |
| `f`, `inputfile` | *maybe* | | No | *valid path to file* | Path to file containing Safe Links URL to decode |

NOTE: If the `url` flag is not specified a prompt is provided to enter a Safe
Links URL.
NOTE: If an input `url` is not specified (e.g., via flag, positional argument
or standard input) a prompt is provided to enter a Safe Links URL.

##### Positional Argument

Expand All @@ -184,34 +193,37 @@ or `url` flag. It is recommended that you quote the URL pattern to help
prevent some of the characters from being interpreted as shell commands (e.g.,
`&` as an attempt to background a command).

##### Standard input (e.g., "piping")

One or more URL patterns can be provided by piping them to the `usl` tool.

An attempt is made to decode all input URLs (no early exit). Successful
decoding results are emitted to `stdout` with decoding failures emitted to
`stderr`. This allows for splitting success results and error output across
different files (e.g., for later review).

##### Just Hit Enter

The `usl` tool can also be called without any flags or positional argument. In
this scenario it will prompt you to insert/paste the URL pattern (quoted or
otherwise).
The `usl` tool can also be called without any input (e.g., flags, positional
argument, standard input). In this scenario it will prompt you to insert/paste
the URL pattern (quoted or otherwise).

## Examples

Though probably not required for all terminals, we quote the Safe Links URL to
prevent unintended interpretation of characters in the URL.

### Using positional argument
### Using url positional argument

```console
$ ./usl 'SafeLinksURLHere'

Original URL:

$ usl 'SafeLinksURLHere'
https://go.dev/dl/
```

### Using flag
### Using url flag

```console
$ ./usl --url 'SafeLinksURLHere'

Original URL:

$ usl --url 'SafeLinksURLHere'
https://go.dev/dl/
```

Expand All @@ -221,18 +233,38 @@ In this example we just press enter so that we will be prompted for the input
URL pattern.

```console
$ ./usl
$ usl
Enter URL: SafeLinksURLHere
https://go.dev/dl/
```

Original URL:
### Using standard input (e.g., "piping")

```console
$ cat file.with.links | usl
https://go.dev/dl/
http://example.com
http://example.net
```

```console
$ echo 'SafeLinksURLHere' | usl
https://go.dev/dl/
```

### Using filename flag

```console
$ usl --filename file.with.links
https://go.dev/dl/
http://example.com
http://example.net
```

### Verbose output

```console
$ ./usl --verbose --url 'SafeLinksURLHere'
$ usl --verbose --url 'SafeLinksURLHere'

Expanded values from the given link:

Expand Down
9 changes: 6 additions & 3 deletions cmd/usl/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,10 @@ const (

// Config represents configuration details for this application.
type Config struct {
URL string
Verbose bool
Version bool
URL string
Filename string
Verbose bool
Version bool
}

// NewConfig processes flag values and returns an application configuration.
Expand Down Expand Up @@ -56,6 +57,8 @@ func usage() {
func setupFlags(c *Config) {
flag.StringVar(&c.URL, "url", "", "Safe Links URL to decode")
flag.StringVar(&c.URL, "u", "", "Safe Links URL to decode"+" (shorthand)")
flag.StringVar(&c.Filename, "inputfile", "", "Path to file containing Safe Links URLs to decode")
flag.StringVar(&c.Filename, "f", "", "Path to file containing Safe Links URL to decode"+" (shorthand)")
flag.BoolVar(&c.Verbose, "verbose", false, "Display additional information about a given Safe Links URL")
flag.BoolVar(&c.Verbose, "v", false, "Display additional information about a given Safe Links URL"+" (shorthand)")
flag.BoolVar(&c.Version, "version", false, "Display version information and immediately exit")
Expand Down
46 changes: 27 additions & 19 deletions cmd/usl/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ package main

import (
"fmt"
"net/url"
"os"
)

Expand All @@ -24,29 +23,38 @@ func main() {
os.Exit(0)
}

inputURL, err := processInputAsURL(cfg.URL)
if err != nil {
fmt.Printf("Failed to parse input as URL: %v\n", err)
os.Exit(1)
}
var inputURLs []string

safelink, err := url.Parse(inputURL)
if err != nil {
fmt.Printf("Failed to parse URL: %v\n", err)
os.Exit(1)
}
switch {
case cfg.Filename != "":
f, err := os.Open(cfg.Filename)
if err != nil {
fmt.Printf("Failed to open %q: %v\n", cfg.Filename, err)
os.Exit(1)
}

if err := assertValidURLParameter(safelink); err != nil {
fmt.Printf("Invalid Safelinks URL: %v\n", err)
os.Exit(1)
}
input, err := readURLsFromFile(f)
if err != nil {
fmt.Printf("Failed to read URLs from %q: %v\n", cfg.Filename, err)
os.Exit(1)
}

switch {
case cfg.Verbose:
verboseOutput(safelink, os.Stdout)
inputURLs = input

default:
simpleOutput(safelink, os.Stdout)
input, err := processInputAsURL(cfg.URL)
if err != nil {
fmt.Printf("Failed to parse input as URL: %v\n", err)
os.Exit(1)
}

inputURLs = input
}

hasErr := processInputURLs(inputURLs, os.Stdout, os.Stderr, cfg.Verbose)

// Ensure unsuccessful error code if one encountered.
if hasErr {
os.Exit(1)
}
}
14 changes: 13 additions & 1 deletion cmd/usl/output.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,25 @@ import (
"sort"
)

// emitOutput emits a given URL to the specified output sink. If specified,
// verbose output is used.
func emitOutput(u *url.URL, w io.Writer, verbose bool) {
switch {
case verbose:
verboseOutput(u, w)

default:
simpleOutput(u, w)
}
}

// simpleOutput handles generating reduced or "simple" output when verbose
// mode is not invoked.
func simpleOutput(u *url.URL, w io.Writer) {
urlValues := u.Query()
maskedURL := urlValues.Get("url")

fmt.Fprintf(w, "\nOriginal URL:\n\n%v\n", maskedURL)
fmt.Fprintln(w, maskedURL)
}

// verboseOutput handles generating extended or "verbose" output when
Expand Down
Loading

0 comments on commit 206d19f

Please sign in to comment.