Browse Source

Add recursive option

renovate/configure
Yota Toyama 8 years ago
parent
commit
7646bd2fb9
  1. 5
      arguments.go
  2. 9
      examples/options.feature
  3. 14
      extensions.go
  4. 13
      extensions_test.go
  5. 29
      main.go
  6. 32
      utils.go
  7. 22
      utils_test.go

5
arguments.go

@ -23,16 +23,18 @@ var defaultConcurrency = func() int {
const usage = `Link checker for Markdown and HTML const usage = `Link checker for Markdown and HTML
Usage: Usage:
liche [-c <num-requests>] [-t <timeout>] [-v] <filenames>... liche [-c <num-requests>] [-r] [-t <timeout>] [-v] <filenames>...
Options: Options:
-c, --concurrency <num-requests> Set max number of concurrent HTTP requests. [default: %v] -c, --concurrency <num-requests> Set max number of concurrent HTTP requests. [default: %v]
-r, --recursive Search Markdown and HTML files recursively
-t, --timeout <timeout> Set timeout for HTTP requests in seconds. Disabled by default. -t, --timeout <timeout> Set timeout for HTTP requests in seconds. Disabled by default.
-v, --verbose Be verbose.` -v, --verbose Be verbose.`
type arguments struct { type arguments struct {
filenames []string filenames []string
concurrency int concurrency int
recursive bool
timeout time.Duration timeout time.Duration
verbose bool verbose bool
} }
@ -63,6 +65,7 @@ func getArgs() (arguments, error) {
return arguments{ return arguments{
args["<filenames>"].([]string), args["<filenames>"].([]string),
int(c), int(c),
args["--recursive"].(bool),
time.Duration(t) * time.Second, time.Duration(t) * time.Second,
args["--verbose"].(bool), args["--verbose"].(bool),
}, nil }, nil

9
examples/options.feature

@ -41,3 +41,12 @@ Feature: Options
""" """
When I successfully run `liche --concurrency 10 foo.md` When I successfully run `liche --concurrency 10 foo.md`
Then the stdout should contain exactly "" Then the stdout should contain exactly ""
Scenario: Search files recursively
Given a directory named "foo"
And a file named "foo/bar.md" with:
"""
[Google](https://google.com)
"""
When I successfully run `liche --recursive -v foo`
Then the stderr should contain "OK"

14
extensions.go

@ -0,0 +1,14 @@
package main
import "path/filepath"
var extensions = map[string]bool{
".htm": true,
".html": true,
".md": true,
}
func isMarkupFile(f string) bool {
_, ok := extensions[filepath.Ext(f)]
return ok
}

13
extensions_test.go

@ -0,0 +1,13 @@
package main
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestIsMarkupFile(t *testing.T) {
for _, f := range []string{"foo.md", "foo.html", "foo.htm", "foo/bar.md"} {
assert.True(t, isMarkupFile(f))
}
}

29
main.go

@ -10,6 +10,15 @@ func main() {
os.Exit(1) os.Exit(1)
} }
if args.recursive {
args.filenames, err = listFilesRecursively(args.filenames)
if err != nil {
printToStderr(err.Error())
os.Exit(1)
}
}
rc := make(chan fileResult, len(args.filenames)) rc := make(chan fileResult, len(args.filenames))
s := newSemaphore(args.concurrency) s := newSemaphore(args.concurrency)
c := newFileChecker(args.timeout, s) c := newFileChecker(args.timeout, s)
@ -31,3 +40,23 @@ func main() {
os.Exit(1) os.Exit(1)
} }
} }
func listFilesRecursively(fs []string) ([]string, error) {
gs := []string{}
for _, f := range fs {
i, err := os.Stat(f)
if err != nil {
return nil, err
}
if i.IsDir() {
gs = append(gs, listFiles(f)...)
} else {
gs = append(gs, f)
}
}
return gs, nil
}

32
utils.go

@ -3,6 +3,8 @@ package main
import ( import (
"fmt" "fmt"
"os" "os"
"path/filepath"
"regexp"
"github.com/kr/text" "github.com/kr/text"
) )
@ -24,3 +26,33 @@ func printToStderr(xs ...interface{}) {
func indent(s string) string { func indent(s string) string {
return text.Indent(s, "\t") return text.Indent(s, "\t")
} }
func listFiles(d string) []string {
fc := make(chan string, 1024)
go func() {
filepath.Walk(d, func(p string, f os.FileInfo, err error) error {
b, err := regexp.MatchString("(^\\.)|(/\\.)", p)
if err != nil {
return err
}
if !f.IsDir() && !b && isMarkupFile(p) {
fc <- p
}
return nil
})
close(fc)
}()
fs := []string{}
for f := range fc {
fs = append(fs, f)
}
return fs
}

22
utils_test.go

@ -0,0 +1,22 @@
package main
import (
"os"
"testing"
"github.com/stretchr/testify/assert"
)
func TestListFiles(t *testing.T) {
fs := listFiles(".")
assert.NotEqual(t, 0, len(fs))
for _, f := range fs {
i, err := os.Stat(f)
assert.True(t, isMarkupFile(f))
assert.Equal(t, nil, err)
assert.False(t, i.IsDir())
}
}
Loading…
Cancel
Save