1
0
mirror of https://github.com/ipfs/kubo.git synced 2025-07-03 04:37:30 +08:00

Doc: golint-ify path package.

This removes all go-lint warnings in the path package.

License: MIT
Signed-off-by: Hector Sanjuan <hector@protocol.ai>
This commit is contained in:
Hector Sanjuan
2018-02-12 22:18:18 +01:00
parent d3c005a7ca
commit cc1b549885
2 changed files with 40 additions and 14 deletions

View File

@ -1,3 +1,4 @@
// Package path contains utilities to work with ipfs paths.
package path package path
import ( import (
@ -11,20 +12,29 @@ import (
// ErrBadPath is returned when a given path is incorrectly formatted // ErrBadPath is returned when a given path is incorrectly formatted
var ErrBadPath = errors.New("invalid 'ipfs ref' path") var ErrBadPath = errors.New("invalid 'ipfs ref' path")
// TODO: debate making this a private struct wrapped in a public interface // A Path represents an ipfs content path:
// would allow us to control creation, and cache segments. // * /<cid>/path/to/file
// * /ipfs/<cid>
// * /ipns/<cid>/path/to/folder
// * etc
type Path string type Path string
// FromString safely converts a string type to a Path type // ^^^
// TODO: debate making this a private struct wrapped in a public interface
// would allow us to control creation, and cache segments.
// FromString safely converts a string type to a Path type.
func FromString(s string) Path { func FromString(s string) Path {
return Path(s) return Path(s)
} }
// FromCid safely converts a cid.Cid type to a Path type // FromCid safely converts a cid.Cid type to a Path type.
func FromCid(c *cid.Cid) Path { func FromCid(c *cid.Cid) Path {
return Path("/ipfs/" + c.String()) return Path("/ipfs/" + c.String())
} }
// Segments returns the different elements of a path
// (elements are delimited by a /).
func (p Path) Segments() []string { func (p Path) Segments() []string {
cleaned := path.Clean(string(p)) cleaned := path.Clean(string(p))
segments := strings.Split(cleaned, "/") segments := strings.Split(cleaned, "/")
@ -37,6 +47,7 @@ func (p Path) Segments() []string {
return segments return segments
} }
// String converts a path to string.
func (p Path) String() string { func (p Path) String() string {
return string(p) return string(p)
} }
@ -65,10 +76,16 @@ func (p Path) PopLastSegment() (Path, string, error) {
return newPath, segs[len(segs)-1], nil return newPath, segs[len(segs)-1], nil
} }
// FromSegments returns a path given its different segments.
func FromSegments(prefix string, seg ...string) (Path, error) { func FromSegments(prefix string, seg ...string) (Path, error) {
return ParsePath(prefix + strings.Join(seg, "/")) return ParsePath(prefix + strings.Join(seg, "/"))
} }
// ParsePath returns a well-formed ipfs Path.
// The returned path will always be prefixed with /ipfs/ or /ipns/.
// The prefix will be added if not present in the given string.
// This function will return an error when the given string is
// not a valid ipfs path.
func ParsePath(txt string) (Path, error) { func ParsePath(txt string) (Path, error) {
parts := strings.Split(txt, "/") parts := strings.Split(txt, "/")
if len(parts) == 1 { if len(parts) == 1 {
@ -78,7 +95,7 @@ func ParsePath(txt string) (Path, error) {
} }
} }
// if the path doesnt being with a '/' // if the path doesnt begin with a '/'
// we expect this to start with a hash, and be an 'ipfs' path // we expect this to start with a hash, and be an 'ipfs' path
if parts[0] != "" { if parts[0] != "" {
if _, err := ParseCidToPath(parts[0]); err != nil { if _, err := ParseCidToPath(parts[0]); err != nil {
@ -103,6 +120,7 @@ func ParsePath(txt string) (Path, error) {
return Path(txt), nil return Path(txt), nil
} }
// ParseCidToPath takes a CID in string form and returns a valid ipfs Path.
func ParseCidToPath(txt string) (Path, error) { func ParseCidToPath(txt string) (Path, error) {
if txt == "" { if txt == "" {
return "", ErrNoComponents return "", ErrNoComponents
@ -116,15 +134,18 @@ func ParseCidToPath(txt string) (Path, error) {
return FromCid(c), nil return FromCid(c), nil
} }
// IsValid checks if a path is a valid ipfs Path.
func (p *Path) IsValid() error { func (p *Path) IsValid() error {
_, err := ParsePath(p.String()) _, err := ParsePath(p.String())
return err return err
} }
// Join joins strings slices using /
func Join(pths []string) string { func Join(pths []string) string {
return strings.Join(pths, "/") return strings.Join(pths, "/")
} }
// SplitList splits strings usings /
func SplitList(pth string) []string { func SplitList(pth string) []string {
return strings.Split(pth, "/") return strings.Split(pth, "/")
} }

View File

@ -16,7 +16,8 @@ import (
var log = logging.Logger("path") var log = logging.Logger("path")
// Paths after a protocol must contain at least one component // ErrNoComponents is used when Paths after a protocol
// do not contain at least one component
var ErrNoComponents = errors.New( var ErrNoComponents = errors.New(
"path must contain at least one component") "path must contain at least one component")
@ -26,6 +27,8 @@ type ErrNoLink struct {
Node *cid.Cid Node *cid.Cid
} }
// Error implements the Error interface for ErrNoLink with a useful
// human readable message.
func (e ErrNoLink) Error() string { func (e ErrNoLink) Error() string {
return fmt.Sprintf("no link named %q under %s", e.Name, e.Node.String()) return fmt.Sprintf("no link named %q under %s", e.Name, e.Node.String())
} }
@ -74,6 +77,8 @@ func SplitAbsPath(fpath Path) (*cid.Cid, []string, error) {
return c, parts[1:], nil return c, parts[1:], nil
} }
// ResolveToLastNode walks the given path and returns the ipld.Node
// referenced by the last element in it.
func (r *Resolver) ResolveToLastNode(ctx context.Context, fpath Path) (ipld.Node, []string, error) { func (r *Resolver) ResolveToLastNode(ctx context.Context, fpath Path) (ipld.Node, []string, error) {
c, p, err := SplitAbsPath(fpath) c, p, err := SplitAbsPath(fpath)
if err != nil { if err != nil {
@ -109,13 +114,13 @@ func (r *Resolver) ResolveToLastNode(ctx context.Context, fpath Path) (ipld.Node
// ResolvePath fetches the node for given path. It returns the last item // ResolvePath fetches the node for given path. It returns the last item
// returned by ResolvePathComponents. // returned by ResolvePathComponents.
func (s *Resolver) ResolvePath(ctx context.Context, fpath Path) (ipld.Node, error) { func (r *Resolver) ResolvePath(ctx context.Context, fpath Path) (ipld.Node, error) {
// validate path // validate path
if err := fpath.IsValid(); err != nil { if err := fpath.IsValid(); err != nil {
return nil, err return nil, err
} }
nodes, err := s.ResolvePathComponents(ctx, fpath) nodes, err := r.ResolvePathComponents(ctx, fpath)
if err != nil || nodes == nil { if err != nil || nodes == nil {
return nil, err return nil, err
} }
@ -131,7 +136,7 @@ func ResolveSingle(ctx context.Context, ds ipld.NodeGetter, nd ipld.Node, names
// ResolvePathComponents fetches the nodes for each segment of the given path. // ResolvePathComponents fetches the nodes for each segment of the given path.
// It uses the first path component as a hash (key) of the first node, then // It uses the first path component as a hash (key) of the first node, then
// resolves all other components walking the links, with ResolveLinks. // resolves all other components walking the links, with ResolveLinks.
func (s *Resolver) ResolvePathComponents(ctx context.Context, fpath Path) ([]ipld.Node, error) { func (r *Resolver) ResolvePathComponents(ctx context.Context, fpath Path) ([]ipld.Node, error) {
evt := log.EventBegin(ctx, "resolvePathComponents", logging.LoggableMap{"fpath": fpath}) evt := log.EventBegin(ctx, "resolvePathComponents", logging.LoggableMap{"fpath": fpath})
defer evt.Done() defer evt.Done()
@ -142,13 +147,13 @@ func (s *Resolver) ResolvePathComponents(ctx context.Context, fpath Path) ([]ipl
} }
log.Debug("resolve dag get") log.Debug("resolve dag get")
nd, err := s.DAG.Get(ctx, h) nd, err := r.DAG.Get(ctx, h)
if err != nil { if err != nil {
evt.Append(logging.LoggableMap{"error": err.Error()}) evt.Append(logging.LoggableMap{"error": err.Error()})
return nil, err return nil, err
} }
return s.ResolveLinks(ctx, nd, parts) return r.ResolveLinks(ctx, nd, parts)
} }
// ResolveLinks iteratively resolves names by walking the link hierarchy. // ResolveLinks iteratively resolves names by walking the link hierarchy.
@ -158,7 +163,7 @@ func (s *Resolver) ResolvePathComponents(ctx context.Context, fpath Path) ([]ipl
// //
// ResolveLinks(nd, []string{"foo", "bar", "baz"}) // ResolveLinks(nd, []string{"foo", "bar", "baz"})
// would retrieve "baz" in ("bar" in ("foo" in nd.Links).Links).Links // would retrieve "baz" in ("bar" in ("foo" in nd.Links).Links).Links
func (s *Resolver) ResolveLinks(ctx context.Context, ndd ipld.Node, names []string) ([]ipld.Node, error) { func (r *Resolver) ResolveLinks(ctx context.Context, ndd ipld.Node, names []string) ([]ipld.Node, error) {
evt := log.EventBegin(ctx, "resolveLinks", logging.LoggableMap{"names": names}) evt := log.EventBegin(ctx, "resolveLinks", logging.LoggableMap{"names": names})
defer evt.Done() defer evt.Done()
@ -172,7 +177,7 @@ func (s *Resolver) ResolveLinks(ctx context.Context, ndd ipld.Node, names []stri
ctx, cancel = context.WithTimeout(ctx, time.Minute) ctx, cancel = context.WithTimeout(ctx, time.Minute)
defer cancel() defer cancel()
lnk, rest, err := s.ResolveOnce(ctx, s.DAG, nd, names) lnk, rest, err := r.ResolveOnce(ctx, r.DAG, nd, names)
if err == dag.ErrLinkNotFound { if err == dag.ErrLinkNotFound {
evt.Append(logging.LoggableMap{"error": err.Error()}) evt.Append(logging.LoggableMap{"error": err.Error()})
return result, ErrNoLink{Name: names[0], Node: nd.Cid()} return result, ErrNoLink{Name: names[0], Node: nd.Cid()}
@ -181,7 +186,7 @@ func (s *Resolver) ResolveLinks(ctx context.Context, ndd ipld.Node, names []stri
return result, err return result, err
} }
nextnode, err := lnk.GetNode(ctx, s.DAG) nextnode, err := lnk.GetNode(ctx, r.DAG)
if err != nil { if err != nil {
evt.Append(logging.LoggableMap{"error": err.Error()}) evt.Append(logging.LoggableMap{"error": err.Error()})
return result, err return result, err