Compare commits
No commits in common. "f012eeebbffd75f7d0ea49089110936b65a42714" and "c6361ea4886d6502ba16377ea6494acb74a68c4d" have entirely different histories.
f012eeebbf
...
c6361ea488
10
README.md
10
README.md
@ -19,11 +19,11 @@ The command-line utility can be installed using `go install`:
|
|||||||
go install code.betamike.com/mediocregopher/deadlinks/cmd/deadlinks
|
go install code.betamike.com/mediocregopher/deadlinks/cmd/deadlinks
|
||||||
```
|
```
|
||||||
|
|
||||||
The `-url` parameter is required. Given a URL it will check it for
|
The `-urls` parameter is required. Given one or more URLs it will check each one
|
||||||
any dead links. Can be specified more than once:
|
for any dead links:
|
||||||
|
|
||||||
```
|
```
|
||||||
deadlinks -url='https://mediocregopher.com' -url='gemini://mediocregopher.com'
|
deadlinks -urls 'https://mediocregopher.com,gemini://mediocregopher.com'
|
||||||
```
|
```
|
||||||
|
|
||||||
Any links which are dead will be output to stdout as YAML objects, each
|
Any links which are dead will be output to stdout as YAML objects, each
|
||||||
@ -36,8 +36,8 @@ so on):
|
|||||||
|
|
||||||
```
|
```
|
||||||
deadlinks \
|
deadlinks \
|
||||||
-url='https://mediocregopher.com' -url='gemini://mediocregopher.com' \
|
-urls 'https://mediocregopher.com,gemini://mediocregopher.com' \
|
||||||
-pattern='://mediocregopher.com'
|
-patterns '://mediocregopher.com'
|
||||||
```
|
```
|
||||||
|
|
||||||
There are further options available which affect the utility's behavior, see
|
There are further options available which affect the utility's behavior, see
|
||||||
|
13
client.go
13
client.go
@ -36,11 +36,6 @@ type ClientOpts struct {
|
|||||||
Do(*http.Request) (*http.Response, error)
|
Do(*http.Request) (*http.Response, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// HTTPUserAgent overwrites the user agent used by the HTTPClient.
|
|
||||||
//
|
|
||||||
// Defaults to whatever http.Client uses by default.
|
|
||||||
HTTPUserAgent string
|
|
||||||
|
|
||||||
// MaxRedirects indicates the maximum number of redirects which will be
|
// MaxRedirects indicates the maximum number of redirects which will be
|
||||||
// allowed when resolving a resource. A negative value indicates no
|
// allowed when resolving a resource. A negative value indicates no
|
||||||
// redirects are allowed.
|
// redirects are allowed.
|
||||||
@ -59,9 +54,7 @@ func (o *ClientOpts) withDefaults() *ClientOpts {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if o.HTTPClient == nil {
|
if o.HTTPClient == nil {
|
||||||
o.HTTPClient = &http.Client{
|
o.HTTPClient = new(http.Client)
|
||||||
Transport: http.DefaultTransport.(*http.Transport).Clone(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if o.MaxRedirects == 0 {
|
if o.MaxRedirects == 0 {
|
||||||
@ -195,10 +188,6 @@ func (c *client) getHTTP(
|
|||||||
return "", nil, fmt.Errorf("building request: %w", err)
|
return "", nil, fmt.Errorf("building request: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.opts.HTTPUserAgent != "" {
|
|
||||||
req.Header.Set("User-Agent", c.opts.HTTPUserAgent)
|
|
||||||
}
|
|
||||||
|
|
||||||
res, err := c.opts.HTTPClient.Do(req)
|
res, err := c.opts.HTTPClient.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", nil, fmt.Errorf("performing request: %w", err)
|
return "", nil, fmt.Errorf("performing request: %w", err)
|
||||||
|
@ -1,29 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"flag"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Created so that multiple inputs can be accecpted
|
|
||||||
type arrayFlags struct {
|
|
||||||
strs *[]string
|
|
||||||
}
|
|
||||||
|
|
||||||
func flagStrings(name, usage string) arrayFlags {
|
|
||||||
f := arrayFlags{new([]string)}
|
|
||||||
flag.Var(&f, name, usage)
|
|
||||||
return f
|
|
||||||
}
|
|
||||||
|
|
||||||
func (i arrayFlags) String() string {
|
|
||||||
if i.strs == nil {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
return strings.Join(*i.strs, ", ")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (i arrayFlags) Set(value string) error {
|
|
||||||
*i.strs = append(*i.strs, strings.TrimSpace(value))
|
|
||||||
return nil
|
|
||||||
}
|
|
@ -8,6 +8,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"code.betamike.com/mediocregopher/deadlinks"
|
"code.betamike.com/mediocregopher/deadlinks"
|
||||||
@ -32,16 +33,20 @@ func main() {
|
|||||||
var (
|
var (
|
||||||
storePath = flag.String("store-path", "", "Path to sqlite storage file. If not given then a temporary in-memory storage is used")
|
storePath = flag.String("store-path", "", "Path to sqlite storage file. If not given then a temporary in-memory storage is used")
|
||||||
maxAge = flag.Duration("max-age", 0, "Maximum duration since last check of a resource, before it must be checked again. Must be used with -store-path")
|
maxAge = flag.Duration("max-age", 0, "Maximum duration since last check of a resource, before it must be checked again. Must be used with -store-path")
|
||||||
urls = flagStrings("url", "URL which is always checked. Must be given at least once")
|
urls = flag.String("urls", "", `Comma-separated list of URLs which are always checked. At least one is required`)
|
||||||
patterns = flagStrings("pattern", "URLs matching this regex will have their links checked as well. Can be specified multiple times")
|
patternsStr = flag.String("patterns", "", "Comma-separated list of regexps. All URLs which match one of these will have their links checked as well")
|
||||||
concurrency = flag.Int("concurrency", runtime.NumCPU()/2, "Number simultaneous requests to make at a time")
|
concurrency = flag.Int("concurrency", runtime.NumCPU()/2, "Number simultaneous requests to make at a time")
|
||||||
httpUserAgent = flag.String("http-user-agent", "", "User-agent to use for http requests")
|
|
||||||
)
|
)
|
||||||
|
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
if len(*urls.strs) == 0 {
|
if *urls == "" {
|
||||||
log.Fatal("at least one -url is required")
|
log.Fatal("-urls is required")
|
||||||
|
}
|
||||||
|
|
||||||
|
var patterns []string
|
||||||
|
if *patternsStr != "" {
|
||||||
|
patterns = strings.Split(*patternsStr, ",")
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt)
|
ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt)
|
||||||
@ -55,13 +60,11 @@ func main() {
|
|||||||
dl, err := deadlinks.New(
|
dl, err := deadlinks.New(
|
||||||
ctx,
|
ctx,
|
||||||
store,
|
store,
|
||||||
*urls.strs,
|
strings.Split(*urls, ","),
|
||||||
*patterns.strs,
|
patterns,
|
||||||
&deadlinks.Opts{
|
&deadlinks.Opts{
|
||||||
NewClient: func() deadlinks.Client {
|
NewClient: func() deadlinks.Client {
|
||||||
return loggingClient{deadlinks.NewClient(&deadlinks.ClientOpts{
|
return loggingClient{deadlinks.NewClient(nil)}
|
||||||
HTTPUserAgent: *httpUserAgent,
|
|
||||||
})}
|
|
||||||
},
|
},
|
||||||
Concurrency: *concurrency,
|
Concurrency: *concurrency,
|
||||||
OnError: func(err error) {
|
OnError: func(err error) {
|
||||||
|
Loading…
Reference in New Issue
Block a user