Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
10
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Open sidebar
dms3
go-dms3
Commits
2cb4e59e
Commit
2cb4e59e
authored
Nov 15, 2014
by
Brian Tiger Chow
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #336 from jbenet/feat/test2
fix update check when running ipfs init
parents
7f31b041
e940643f
Changes
13
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
653 additions
and
22 deletions
+653
-22
Godeps/Godeps.json
Godeps/Godeps.json
+9
-1
Godeps/_workspace/src/github.com/facebookgo/stack/.travis.yml
...ps/_workspace/src/github.com/facebookgo/stack/.travis.yml
+24
-0
Godeps/_workspace/src/github.com/facebookgo/stack/readme.md
Godeps/_workspace/src/github.com/facebookgo/stack/readme.md
+4
-0
Godeps/_workspace/src/github.com/facebookgo/stack/stack.go
Godeps/_workspace/src/github.com/facebookgo/stack/stack.go
+197
-0
Godeps/_workspace/src/github.com/facebookgo/stack/stack_test.go
.../_workspace/src/github.com/facebookgo/stack/stack_test.go
+102
-0
Godeps/_workspace/src/github.com/facebookgo/stackerr/.travis.yml
..._workspace/src/github.com/facebookgo/stackerr/.travis.yml
+24
-0
Godeps/_workspace/src/github.com/facebookgo/stackerr/readme.md
...s/_workspace/src/github.com/facebookgo/stackerr/readme.md
+4
-0
Godeps/_workspace/src/github.com/facebookgo/stackerr/stackerr.go
..._workspace/src/github.com/facebookgo/stackerr/stackerr.go
+97
-0
Godeps/_workspace/src/github.com/facebookgo/stackerr/stackerr_test.go
...space/src/github.com/facebookgo/stackerr/stackerr_test.go
+82
-0
cmd/ipfs2/ipfs.go
cmd/ipfs2/ipfs.go
+13
-4
cmd/ipfs2/main.go
cmd/ipfs2/main.go
+65
-15
config/config.go
config/config.go
+2
-2
util/debugerror/debugerror.go
util/debugerror/debugerror.go
+30
-0
No files found.
Godeps/Godeps.json
View file @
2cb4e59e
{
"ImportPath"
:
"github.com/jbenet/go-ipfs"
,
"GoVersion"
:
"go1.3"
,
"GoVersion"
:
"go1.3
.3
"
,
"Packages"
:
[
"./..."
],
...
...
@@ -60,6 +60,14 @@
"ImportPath"
:
"github.com/coreos/go-semver/semver"
,
"Rev"
:
"6fe83ccda8fb9b7549c9ab4ba47f47858bc950aa"
},
{
"ImportPath"
:
"github.com/facebookgo/stack"
,
"Rev"
:
"4da6d991fc3c389efa512151354d643eb5fae4e2"
},
{
"ImportPath"
:
"github.com/facebookgo/stackerr"
,
"Rev"
:
"060fbf9364c89acd41bf710e9e92915a90e7a5b5"
},
{
"ImportPath"
:
"github.com/gonuts/flag"
,
"Rev"
:
"741a6cbd37a30dedc93f817e7de6aaf0ca38a493"
...
...
Godeps/_workspace/src/github.com/facebookgo/stack/.travis.yml
0 → 100644
View file @
2cb4e59e
language
:
go
go
:
-
1.2
-
1.3
matrix
:
fast_finish
:
true
before_install
:
-
go get -v code.google.com/p/go.tools/cmd/vet
-
go get -v github.com/golang/lint/golint
-
go get -v code.google.com/p/go.tools/cmd/cover
install
:
-
go install -race -v std
-
go get -race -t -v ./...
-
go install -race -v ./...
script
:
-
go vet ./...
-
$HOME/gopath/bin/golint .
-
go test -cpu=2 -race -v ./...
-
go test -cpu=2 -covermode=atomic ./...
Godeps/_workspace/src/github.com/facebookgo/stack/readme.md
0 → 100644
View file @
2cb4e59e
stack [![Build Status](https://secure.travis-ci.org/facebookgo/stack.png)](http://travis-ci.org/facebookgo/stack)
=====
Documentation: https://godoc.org/github.com/facebookgo/stack
Godeps/_workspace/src/github.com/facebookgo/stack/stack.go
0 → 100644
View file @
2cb4e59e
// Package stack provides utilities to capture and pass around stack traces.
//
// This is useful for building errors that know where they originated from, to
// track where a certain log event occured and so on.
package
stack
import
(
"bytes"
"fmt"
"os"
"path/filepath"
"runtime"
"strings"
)
const
maxStackSize
=
32
// Frame identifies a file, line & function name in the stack.
type
Frame
struct
{
File
string
Line
int
Name
string
}
// String provides the standard file:line representation.
func
(
f
Frame
)
String
()
string
{
return
fmt
.
Sprintf
(
"%s:%d %s"
,
f
.
File
,
f
.
Line
,
f
.
Name
)
}
// Stack represents an ordered set of Frames.
type
Stack
[]
Frame
// String provides the standard multi-line stack trace.
func
(
s
Stack
)
String
()
string
{
var
b
bytes
.
Buffer
writeStack
(
&
b
,
s
)
return
b
.
String
()
}
// Multi represents a number of Stacks. This is useful to allow tracking a
// value as it travels thru code.
type
Multi
struct
{
stacks
[]
Stack
}
// Stacks returns the tracked Stacks.
func
(
m
*
Multi
)
Stacks
()
[]
Stack
{
return
m
.
stacks
}
// Add the given Stack to this Multi.
func
(
m
*
Multi
)
Add
(
s
Stack
)
{
m
.
stacks
=
append
(
m
.
stacks
,
s
)
}
// AddCallers adds the Callers Stack to this Multi. The argument skip is
// the number of stack frames to ascend, with 0 identifying the caller of
// Callers.
func
(
m
*
Multi
)
AddCallers
(
skip
int
)
{
m
.
Add
(
Callers
(
skip
+
1
))
}
// String provides a human readable multi-line stack trace.
func
(
m
*
Multi
)
String
()
string
{
var
b
bytes
.
Buffer
for
i
,
s
:=
range
m
.
stacks
{
if
i
!=
0
{
fmt
.
Fprintf
(
&
b
,
"
\n
(Stack %d)
\n
"
,
i
+
1
)
}
writeStack
(
&
b
,
s
)
}
return
b
.
String
()
}
// Caller returns a single Frame for the caller. The argument skip is the
// number of stack frames to ascend, with 0 identifying the caller of Callers.
func
Caller
(
skip
int
)
Frame
{
pc
,
file
,
line
,
_
:=
runtime
.
Caller
(
skip
+
1
)
fun
:=
runtime
.
FuncForPC
(
pc
)
return
Frame
{
File
:
StripGOPATH
(
file
),
Line
:
line
,
Name
:
StripPackage
(
fun
.
Name
()),
}
}
// Callers returns a Stack of Frames for the callers. The argument skip is the
// number of stack frames to ascend, with 0 identifying the caller of Callers.
func
Callers
(
skip
int
)
Stack
{
pcs
:=
make
([]
uintptr
,
maxStackSize
)
num
:=
runtime
.
Callers
(
skip
+
2
,
pcs
)
stack
:=
make
(
Stack
,
num
)
for
i
,
pc
:=
range
pcs
[
:
num
]
{
fun
:=
runtime
.
FuncForPC
(
pc
)
file
,
line
:=
fun
.
FileLine
(
pc
)
stack
[
i
]
.
File
=
StripGOPATH
(
file
)
stack
[
i
]
.
Line
=
line
stack
[
i
]
.
Name
=
StripPackage
(
fun
.
Name
())
}
return
stack
}
// CallersMulti returns a Multi which includes one Stack for the
// current callers. The argument skip is the number of stack frames to ascend,
// with 0 identifying the caller of CallersMulti.
func
CallersMulti
(
skip
int
)
*
Multi
{
m
:=
new
(
Multi
)
m
.
AddCallers
(
skip
+
1
)
return
m
}
func
writeStack
(
b
*
bytes
.
Buffer
,
s
Stack
)
{
var
width
int
for
_
,
f
:=
range
s
{
if
l
:=
len
(
f
.
File
)
+
numDigits
(
f
.
Line
)
+
1
;
l
>
width
{
width
=
l
}
}
last
:=
len
(
s
)
-
1
for
i
,
f
:=
range
s
{
b
.
WriteString
(
f
.
File
)
b
.
WriteRune
(
rune
(
':'
))
n
,
_
:=
fmt
.
Fprintf
(
b
,
"%d"
,
f
.
Line
)
for
i
:=
width
-
len
(
f
.
File
)
-
n
;
i
!=
0
;
i
--
{
b
.
WriteRune
(
rune
(
' '
))
}
b
.
WriteString
(
f
.
Name
)
if
i
!=
last
{
b
.
WriteRune
(
rune
(
'\n'
))
}
}
}
func
numDigits
(
i
int
)
int
{
var
n
int
for
{
n
++
i
=
i
/
10
if
i
==
0
{
return
n
}
}
}
// This can be set by a build script. It will be the colon separated equivalent
// of the environment variable.
var
gopath
string
// This is the processed version based on either the above variable set by the
// build or from the GOPATH environment variable.
var
gopaths
[]
string
func
init
()
{
// prefer the variable set at build time, otherwise fallback to the
// environment variable.
if
gopath
==
""
{
gopath
=
os
.
Getenv
(
"GOPATH"
)
}
for
_
,
p
:=
range
strings
.
Split
(
gopath
,
":"
)
{
if
p
!=
""
{
gopaths
=
append
(
gopaths
,
filepath
.
Join
(
p
,
"src"
)
+
"/"
)
}
}
// Also strip GOROOT for maximum cleanliness
gopaths
=
append
(
gopaths
,
filepath
.
Join
(
runtime
.
GOROOT
(),
"src"
,
"pkg"
)
+
"/"
)
}
// StripGOPATH strips the GOPATH prefix from the file path f.
// In development, this will be done using the GOPATH environment variable.
// For production builds, where the GOPATH environment will not be set, the
// GOPATH can be included in the binary by passing ldflags, for example:
//
// GO_LDFLAGS="$GO_LDFLAGS -X github.com/facebookgo/stack.gopath $GOPATH"
// go install "-ldflags=$GO_LDFLAGS" my/pkg
func
StripGOPATH
(
f
string
)
string
{
for
_
,
p
:=
range
gopaths
{
if
strings
.
HasPrefix
(
f
,
p
)
{
return
f
[
len
(
p
)
:
]
}
}
return
f
}
// StripPackage strips the package name from the given Func.Name.
func
StripPackage
(
n
string
)
string
{
slashI
:=
strings
.
LastIndex
(
n
,
"/"
)
if
slashI
==
-
1
{
slashI
=
0
// for built-in packages
}
dotI
:=
strings
.
Index
(
n
[
slashI
:
],
"."
)
if
dotI
==
-
1
{
return
n
}
return
n
[
slashI
+
dotI
+
1
:
]
}
Godeps/_workspace/src/github.com/facebookgo/stack/stack_test.go
0 → 100644
View file @
2cb4e59e
package
stack_test
import
(
"regexp"
"strings"
"testing"
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/facebookgo/stack"
)
func
indirect1
()
stack
.
Stack
{
return
stack
.
Callers
(
0
)
}
func
indirect2
()
stack
.
Stack
{
return
indirect1
()
}
func
indirect3
()
stack
.
Stack
{
return
indirect2
()
}
func
TestCallers
(
t
*
testing
.
T
)
{
s
:=
indirect3
()
matches
:=
[]
string
{
"^github.com/facebookgo/stack/stack_test.go:12 +indirect1$"
,
"^github.com/facebookgo/stack/stack_test.go:16 +indirect2$"
,
"^github.com/facebookgo/stack/stack_test.go:20 +indirect3$"
,
"^github.com/facebookgo/stack/stack_test.go:24 +TestCallers$"
,
}
match
(
t
,
s
.
String
(),
matches
)
}
func
TestCallersMulti
(
t
*
testing
.
T
)
{
m
:=
stack
.
CallersMulti
(
0
)
const
expected
=
"github.com/facebookgo/stack/stack_test.go:35 TestCallersMulti"
first
:=
m
.
Stacks
()[
0
][
0
]
.
String
()
if
first
!=
expected
{
t
.
Fatalf
(
`expected "%s" got "%s"`
,
expected
,
first
)
}
}
func
TestCallersMultiWithTwo
(
t
*
testing
.
T
)
{
m
:=
stack
.
CallersMulti
(
0
)
m
.
AddCallers
(
0
)
matches
:=
[]
string
{
"^github.com/facebookgo/stack/stack_test.go:44 +TestCallersMultiWithTwo$"
,
""
,
""
,
`^\(Stack 2\)$`
,
"^github.com/facebookgo/stack/stack_test.go:46 +TestCallersMultiWithTwo$"
,
}
match
(
t
,
m
.
String
(),
matches
)
}
type
typ
struct
{}
func
(
m
typ
)
indirect1
()
stack
.
Stack
{
return
stack
.
Callers
(
0
)
}
func
(
m
typ
)
indirect2
()
stack
.
Stack
{
return
m
.
indirect1
()
}
func
(
m
typ
)
indirect3
()
stack
.
Stack
{
return
m
.
indirect2
()
}
func
TestCallersWithStruct
(
t
*
testing
.
T
)
{
var
m
typ
s
:=
m
.
indirect3
()
matches
:=
[]
string
{
"^github.com/facebookgo/stack/stack_test.go:59 +typ.indirect1$"
,
"^github.com/facebookgo/stack/stack_test.go:63 +typ.indirect2$"
,
"^github.com/facebookgo/stack/stack_test.go:67 +typ.indirect3$"
,
"^github.com/facebookgo/stack/stack_test.go:72 +TestCallersWithStruct$"
,
}
match
(
t
,
s
.
String
(),
matches
)
}
func
TestCaller
(
t
*
testing
.
T
)
{
f
:=
stack
.
Caller
(
0
)
const
expected
=
"github.com/facebookgo/stack/stack_test.go:83 TestCaller"
if
f
.
String
()
!=
expected
{
t
.
Fatalf
(
`expected "%s" got "%s"`
,
expected
,
f
)
}
}
func
match
(
t
testing
.
TB
,
s
string
,
matches
[]
string
)
{
lines
:=
strings
.
Split
(
s
,
"
\n
"
)
for
i
,
m
:=
range
matches
{
if
!
regexp
.
MustCompile
(
m
)
.
MatchString
(
lines
[
i
])
{
t
.
Fatalf
(
"did not find expected match
\"
%s
\"
on line %d in:
\n
%s"
,
m
,
i
,
s
,
)
}
}
}
Godeps/_workspace/src/github.com/facebookgo/stackerr/.travis.yml
0 → 100644
View file @
2cb4e59e
language
:
go
go
:
-
1.2
-
1.3
matrix
:
fast_finish
:
true
before_install
:
-
go get -v code.google.com/p/go.tools/cmd/vet
-
go get -v github.com/golang/lint/golint
-
go get -v code.google.com/p/go.tools/cmd/cover
install
:
-
go install -race -v std
-
go get -race -t -v ./...
-
go install -race -v ./...
script
:
-
go vet ./...
-
$HOME/gopath/bin/golint .
-
go test -cpu=2 -race -v ./...
-
go test -cpu=2 -covermode=atomic ./...
Godeps/_workspace/src/github.com/facebookgo/stackerr/readme.md
0 → 100644
View file @
2cb4e59e
stackerr [![Build Status](https://secure.travis-ci.org/facebookgo/stackerr.png)](http://travis-ci.org/facebookgo/stackerr)
========
Documentation: https://godoc.org/github.com/facebookgo/stackerr
Godeps/_workspace/src/github.com/facebookgo/stackerr/stackerr.go
0 → 100644
View file @
2cb4e59e
// Package stackerr provides a way to augment errors with one or more stack
// traces to allow for easier debugging.
package
stackerr
import
(
"errors"
"fmt"
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/facebookgo/stack"
)
// Error provides the wrapper that adds multiple Stacks to an error. Each Stack
// represents a location in code thru which this error was wrapped.
type
Error
struct
{
multiStack
*
stack
.
Multi
underlying
error
}
// Error provides a multi line error string that includes the stack trace.
func
(
e
*
Error
)
Error
()
string
{
return
fmt
.
Sprintf
(
"%s
\n
%s"
,
e
.
underlying
,
e
.
multiStack
)
}
// MultiStack identifies the locations this error was wrapped at.
func
(
e
*
Error
)
MultiStack
()
*
stack
.
Multi
{
return
e
.
multiStack
}
// Underlying returns the error that is being wrapped.
func
(
e
*
Error
)
Underlying
()
error
{
return
e
.
underlying
}
type
hasMultiStack
interface
{
MultiStack
()
*
stack
.
Multi
}
// WrapSkip the error and add the current Stack. The argument skip is the
// number of stack frames to ascend, with 0 identifying the caller of Wrap. If
// the error to be wrapped has a MultiStack, the current stack will be added to
// it. If the error to be wrapped is nil, a nil error is returned.
func
WrapSkip
(
err
error
,
skip
int
)
error
{
// nil errors are returned back as nil.
if
err
==
nil
{
return
nil
}
// we're adding another Stack to an already wrapped error.
if
se
,
ok
:=
err
.
(
hasMultiStack
);
ok
{
se
.
MultiStack
()
.
AddCallers
(
skip
+
1
)
return
err
}
// we're create a freshly wrapped error.
return
&
Error
{
multiStack
:
stack
.
CallersMulti
(
skip
+
1
),
underlying
:
err
,
}
}
// Wrap provides a convenience function that calls WrapSkip with skip=0. That
// is, the Stack starts with the caller of Wrap.
func
Wrap
(
err
error
)
error
{
return
WrapSkip
(
err
,
1
)
}
// New returns a new error that includes the Stack.
func
New
(
s
string
)
error
{
return
WrapSkip
(
errors
.
New
(
s
),
1
)
}
// Newf formats and returns a new error that includes the Stack.
func
Newf
(
format
string
,
args
...
interface
{})
error
{
return
WrapSkip
(
fmt
.
Errorf
(
format
,
args
...
),
1
)
}
type
hasUnderlying
interface
{
Underlying
()
error
}
// Underlying returns all the underlying errors by iteratively checking if the
// error has an Underlying error. If e is nil, the returned slice will be nil.
func
Underlying
(
e
error
)
[]
error
{
var
errs
[]
error
for
{
if
e
==
nil
{
return
errs
}
errs
=
append
(
errs
,
e
)
if
eh
,
ok
:=
e
.
(
hasUnderlying
);
ok
{
e
=
eh
.
Underlying
()
}
else
{
e
=
nil
}
}
}
Godeps/_workspace/src/github.com/facebookgo/stackerr/stackerr_test.go
0 → 100644
View file @
2cb4e59e
package
stackerr_test
import
(
"errors"
"fmt"
"regexp"
"strings"
"testing"
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/facebookgo/stackerr"
)
func
TestNew
(
t
*
testing
.
T
)
{
const
errStr
=
"foo bar baz"
e
:=
stackerr
.
New
(
errStr
)
matches
:=
[]
string
{
errStr
,
"^github.com/facebookgo/stackerr/stackerr_test.go:15 +TestNew$"
,
}
match
(
t
,
e
.
Error
(),
matches
)
}
func
TestNewf
(
t
*
testing
.
T
)
{
const
fmtStr
=
"%s 42"
const
errStr
=
"foo bar baz"
e
:=
stackerr
.
Newf
(
fmtStr
,
errStr
)
matches
:=
[]
string
{
fmt
.
Sprintf
(
fmtStr
,
errStr
),
"^github.com/facebookgo/stackerr/stackerr_test.go:26 +TestNewf$"
,
}
match
(
t
,
e
.
Error
(),
matches
)
}
func
TestWrap
(
t
*
testing
.
T
)
{
const
errStr
=
"foo bar baz"
e
:=
stackerr
.
Wrap
(
errors
.
New
(
errStr
))
matches
:=
[]
string
{
errStr
,
"^github.com/facebookgo/stackerr/stackerr_test.go:36 +TestWrap$"
,
}
match
(
t
,
e
.
Error
(),
matches
)
}
func
TestNilWrap
(
t
*
testing
.
T
)
{
if
stackerr
.
WrapSkip
(
nil
,
1
)
!=
nil
{
t
.
Fatal
(
"did not get nil error"
)
}
}
func
TestDoubleWrap
(
t
*
testing
.
T
)
{
e
:=
stackerr
.
New
(
""
)
if
stackerr
.
WrapSkip
(
e
,
1
)
!=
e
{
t
.
Fatal
(
"double wrap failure"
)
}
}
func
TestLog
(
t
*
testing
.
T
)
{
t
.
Log
(
stackerr
.
New
(
"hello"
))
}
func
TestUnderlying
(
t
*
testing
.
T
)
{
e1
:=
errors
.
New
(
""
)
e2
:=
stackerr
.
Wrap
(
e1
)
errs
:=
stackerr
.
Underlying
(
e2
)
if
len
(
errs
)
!=
2
||
errs
[
0
]
!=
e2
||
errs
[
1
]
!=
e1
{
t
.
Fatal
(
"failed Underlying"
)
}
}
func
match
(
t
testing
.
TB
,
s
string
,
matches
[]
string
)
{
lines
:=
strings
.
Split
(
s
,
"
\n
"
)
for
i
,
m
:=
range
matches
{
if
!
regexp
.
MustCompile
(
m
)
.
MatchString
(
lines
[
i
])
{
t
.
Fatalf
(
"did not find expected match
\"
%s
\"
on line %d in:
\n
%s"
,
m
,
i
,
s
,
)
}
}
}
cmd/ipfs2/ipfs.go
View file @
2cb4e59e
...
...
@@ -55,6 +55,15 @@ type cmdDetails struct {
cannotRunOnClient
bool
cannotRunOnDaemon
bool
doesNotUseRepo
bool
// initializesConfig describes commands that initialize the config.
// pre-command hooks that require configs must not be run before this
// command
initializesConfig
bool
// preemptsAutoUpdate describes commands that must be executed without the
// pre-command update hook
preemptsAutoUpdate
bool
}
func
(
d
*
cmdDetails
)
String
()
string
{
...
...
@@ -71,14 +80,14 @@ func (d *cmdDetails) usesRepo() bool { return !d.doesNotUseRepo }
// properties so that other code can make decisions about whether to invoke a
// command or return an error to the user.
var
cmdDetailsMap
=
map
[
*
cmds
.
Command
]
cmdDetails
{
initCmd
:
cmdDetails
{
cannotRunOnDaemon
:
true
,
doesNotUseRepo
:
true
},
initCmd
:
cmdDetails
{
initializesConfig
:
true
,
cannotRunOnDaemon
:
true
,
doesNotUseRepo
:
true
},
daemonCmd
:
cmdDetails
{
cannotRunOnDaemon
:
true
},
commandsClientCmd
:
cmdDetails
{
doesNotUseRepo
:
true
},
commands
.
CommandsDaemonCmd
:
cmdDetails
{
doesNotUseRepo
:
true
},
commands
.
DiagCmd
:
cmdDetails
{
cannotRunOnClient
:
true
},
commands
.
VersionCmd
:
cmdDetails
{
doesNotUseRepo
:
true
},
commands
.
UpdateCmd
:
cmdDetails
{
cannotRunOnDaemon
:
true
},
commands
.
UpdateCheckCmd
:
cmdDetails
{},
commands
.
UpdateLogCmd
:
cmdDetails
{},
commands
.
UpdateCmd
:
cmdDetails
{
preemptsAutoUpdate
:
true
,
cannotRunOnDaemon
:
true
},
commands
.
UpdateCheckCmd
:
cmdDetails
{
preemptsAutoUpdate
:
true
},
commands
.
UpdateLogCmd
:
cmdDetails
{
preemptsAutoUpdate
:
true
},
commands
.
LogCmd
:
cmdDetails
{
cannotRunOnClient
:
true
},
}
cmd/ipfs2/main.go
View file @
2cb4e59e
...
...
@@ -20,6 +20,7 @@ import (
daemon
"github.com/jbenet/go-ipfs/daemon2"
updates
"github.com/jbenet/go-ipfs/updates"
u
"github.com/jbenet/go-ipfs/util"
"github.com/jbenet/go-ipfs/util/debugerror"
)
// log is the command logger
...
...
@@ -169,6 +170,7 @@ func (i *cmdInvocation) Parse(args []string) error {
if
err
!=
nil
{
return
err
}
log
.
Debugf
(
"config path is %s"
,
configPath
)
// this sets up the function that will initialize the config lazily.
ctx
:=
i
.
req
.
Context
()
...
...
@@ -200,21 +202,61 @@ func (i *cmdInvocation) requestedHelp() (short bool, long bool, err error) {
return
longHelp
,
shortHelp
,
nil
}
func
callPreCommandHooks
(
details
cmdDetails
,
req
cmds
.
Request
,
root
*
cmds
.
Command
)
error
{
log
.
Debug
(
"Calling pre-command hooks..."
)
// some hooks only run when the command is executed locally
daemon
,
err
:=
commandShouldRunOnDaemon
(
details
,
req
,
root
)
if
err
!=
nil
{
return
err
}
// check for updates when 1) commands is going to be run locally, 2) the
// command does not initialize the config, and 3) the command does not
// pre-empt updates
if
!
daemon
&&
!
details
.
initializesConfig
&&
!
details
.
preemptsAutoUpdate
{
log
.
Debug
(
"Calling hook: Check for updates"
)
cfg
,
err
:=
req
.
Context
()
.
GetConfig
()
if
err
!=
nil
{
return
err
}
// Check for updates and potentially install one.
if
err
:=
updates
.
CliCheckForUpdates
(
cfg
,
req
.
Context
()
.
ConfigRoot
);
err
!=
nil
{
return
err
}
}
return
nil
}
func
callCommand
(
req
cmds
.
Request
,
root
*
cmds
.
Command
)
(
cmds
.
Response
,
error
)
{
var
res
cmds
.
Response
useDaemon
,
err
:=
commandShouldRunOnDaemon
(
req
,
root
)
details
,
err
:=
commandDetails
(
req
.
Path
(),
root
)
if
err
!=
nil
{
return
nil
,
err
}
useDaemon
,
err
:=
commandShouldRunOnDaemon
(
*
details
,
req
,
root
)
if
err
!=
nil
{
return
nil
,
err
}
cfg
,
err
:
=
req
.
Context
()
.
GetConfig
(
)
err
=
callPreCommandHooks
(
*
details
,
req
,
root
)
if
err
!=
nil
{
return
nil
,
err
}
if
useDaemon
{
cfg
,
err
:=
req
.
Context
()
.
GetConfig
()
if
err
!=
nil
{
return
nil
,
err
}
addr
,
err
:=
ma
.
NewMultiaddr
(
cfg
.
Addresses
.
API
)
if
err
!=
nil
{
return
nil
,
err
...
...
@@ -236,11 +278,6 @@ func callCommand(req cmds.Request, root *cmds.Command) (cmds.Response, error) {
}
else
{
log
.
Info
(
"Executing command locally"
)
// Check for updates and potentially install one.
if
err
:=
updates
.
CliCheckForUpdates
(
cfg
,
req
.
Context
()
.
ConfigRoot
);
err
!=
nil
{
return
nil
,
err
}
// this sets up the function that will initialize the node
// this is so that we can construct the node lazily.
ctx
:=
req
.
Context
()
...
...
@@ -266,13 +303,11 @@ func callCommand(req cmds.Request, root *cmds.Command) (cmds.Response, error) {
return
res
,
nil
}
func
commandShouldRunOnDaemon
(
req
cmds
.
Request
,
root
*
cmds
.
Command
)
(
bool
,
error
)
{
path
:=
req
.
Path
()
// root command.
if
len
(
path
)
<
1
{
return
false
,
nil
}
// commandDetails returns a command's details for the command given by |path|
// within the |root| command tree.
//
// Returns an error if the command is not found in the Command tree.
func
commandDetails
(
path
[]
string
,
root
*
cmds
.
Command
)
(
*
cmdDetails
,
error
)
{
var
details
cmdDetails
// find the last command in path that has a cmdDetailsMap entry
cmd
:=
root
...
...
@@ -280,7 +315,7 @@ func commandShouldRunOnDaemon(req cmds.Request, root *cmds.Command) (bool, error
var
found
bool
cmd
,
found
=
cmd
.
Subcommands
[
cmp
]
if
!
found
{
return
false
,
fmt
.
Errorf
(
"subcommand %s should be in root"
,
cmp
)
return
nil
,
debugerror
.
Errorf
(
"subcommand %s should be in root"
,
cmp
)
}
if
cmdDetails
,
found
:=
cmdDetailsMap
[
cmd
];
found
{
...
...
@@ -288,6 +323,21 @@ func commandShouldRunOnDaemon(req cmds.Request, root *cmds.Command) (bool, error
}
}
log
.
Debugf
(
"cmd perms for +%v: %s"
,
path
,
details
.
String
())
return
&
details
,
nil
}
// commandShouldRunOnDaemon determines, from commmand details, whether a
// command ought to be executed on an IPFS daemon.
//
// It returns true if the command should be executed on a daemon and false if
// it should be executed on a client. It returns an error if the command must
// NOT be executed on either.
func
commandShouldRunOnDaemon
(
details
cmdDetails
,
req
cmds
.
Request
,
root
*
cmds
.
Command
)
(
bool
,
error
)
{
path
:=
req
.
Path
()
// root command.
if
len
(
path
)
<
1
{
return
false
,
nil
}
if
details
.
cannotRunOnClient
&&
details
.
cannotRunOnDaemon
{
return
false
,
fmt
.
Errorf
(
"command disabled: %s"
,
path
[
0
])
...
...
config/config.go
View file @
2cb4e59e
...
...
@@ -5,11 +5,11 @@ import (
"crypto"
"crypto/x509"
"encoding/base64"
"errors"
"os"
"path/filepath"
u
"github.com/jbenet/go-ipfs/util"
"github.com/jbenet/go-ipfs/util/debugerror"
)
var
log
=
u
.
Logger
(
"config"
)
...
...
@@ -129,7 +129,7 @@ func (i *Identity) DecodePrivateKey(passphrase string) (crypto.PrivateKey, error
func
Load
(
filename
string
)
(
*
Config
,
error
)
{
// if nothing is there, fail. User must run 'ipfs init'
if
_
,
err
:=
os
.
Stat
(
filename
);
os
.
IsNotExist
(
err
)
{
return
nil
,
error
s
.
New
(
"ipfs not initialized, please run 'ipfs init'"
)
return
nil
,
debug
error
.
New
(
"ipfs not initialized, please run 'ipfs init'"
)
}
var
cfg
Config
...
...
util/debugerror/debugerror.go
0 → 100644
View file @
2cb4e59e
// package debugerror provides a way to augment errors with additional
// information to allow for easier debugging.
package
debugerror
import
(
"errors"
"fmt"
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/facebookgo/stackerr"
"github.com/jbenet/go-ipfs/util"
)
func
Errorf
(
format
string
,
a
...
interface
{})
error
{
return
Wrap
(
fmt
.
Errorf
(
format
,
a
...
))
}
// New returns an error that contains a stack trace (in debug mode)
func
New
(
s
string
)
error
{
if
util
.
Debug
{
return
stackerr
.
New
(
s
)
}
return
errors
.
New
(
s
)
}
func
Wrap
(
err
error
)
error
{
if
util
.
Debug
{
return
stackerr
.
Wrap
(
err
)
}
return
err
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment