From cc1b5498851cc2e52dc265974c92eb2f5123c8c1 Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Mon, 12 Feb 2018 22:18:18 +0100 Subject: [PATCH] Doc: golint-ify path package. This removes all go-lint warnings in the path package. License: MIT Signed-off-by: Hector Sanjuan --- path/path.go | 31 ++++++++++++++++++++++++++----- path/resolver.go | 23 ++++++++++++++--------- 2 files changed, 40 insertions(+), 14 deletions(-) diff --git a/path/path.go b/path/path.go index decf28904..aeaeb5c7a 100644 --- a/path/path.go +++ b/path/path.go @@ -1,3 +1,4 @@ +// Package path contains utilities to work with ipfs paths. package path import ( @@ -11,20 +12,29 @@ import ( // ErrBadPath is returned when a given path is incorrectly formatted var ErrBadPath = errors.New("invalid 'ipfs ref' path") -// TODO: debate making this a private struct wrapped in a public interface -// would allow us to control creation, and cache segments. +// A Path represents an ipfs content path: +// * //path/to/file +// * /ipfs/ +// * /ipns//path/to/folder +// * etc 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 { 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 { return Path("/ipfs/" + c.String()) } +// Segments returns the different elements of a path +// (elements are delimited by a /). func (p Path) Segments() []string { cleaned := path.Clean(string(p)) segments := strings.Split(cleaned, "/") @@ -37,6 +47,7 @@ func (p Path) Segments() []string { return segments } +// String converts a path to string. func (p Path) String() string { return string(p) } @@ -65,10 +76,16 @@ func (p Path) PopLastSegment() (Path, string, error) { return newPath, segs[len(segs)-1], nil } +// FromSegments returns a path given its different segments. func FromSegments(prefix string, seg ...string) (Path, error) { 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) { parts := strings.Split(txt, "/") 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 if parts[0] != "" { if _, err := ParseCidToPath(parts[0]); err != nil { @@ -103,6 +120,7 @@ func ParsePath(txt string) (Path, error) { return Path(txt), nil } +// ParseCidToPath takes a CID in string form and returns a valid ipfs Path. func ParseCidToPath(txt string) (Path, error) { if txt == "" { return "", ErrNoComponents @@ -116,15 +134,18 @@ func ParseCidToPath(txt string) (Path, error) { return FromCid(c), nil } +// IsValid checks if a path is a valid ipfs Path. func (p *Path) IsValid() error { _, err := ParsePath(p.String()) return err } +// Join joins strings slices using / func Join(pths []string) string { return strings.Join(pths, "/") } +// SplitList splits strings usings / func SplitList(pth string) []string { return strings.Split(pth, "/") } diff --git a/path/resolver.go b/path/resolver.go index 30c249d45..64bdbf752 100644 --- a/path/resolver.go +++ b/path/resolver.go @@ -16,7 +16,8 @@ import ( 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( "path must contain at least one component") @@ -26,6 +27,8 @@ type ErrNoLink struct { Node *cid.Cid } +// Error implements the Error interface for ErrNoLink with a useful +// human readable message. func (e ErrNoLink) Error() 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 } +// 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) { c, p, err := SplitAbsPath(fpath) 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 // 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 if err := fpath.IsValid(); err != nil { return nil, err } - nodes, err := s.ResolvePathComponents(ctx, fpath) + nodes, err := r.ResolvePathComponents(ctx, fpath) if err != nil || nodes == nil { 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. // It uses the first path component as a hash (key) of the first node, then // 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}) defer evt.Done() @@ -142,13 +147,13 @@ func (s *Resolver) ResolvePathComponents(ctx context.Context, fpath Path) ([]ipl } log.Debug("resolve dag get") - nd, err := s.DAG.Get(ctx, h) + nd, err := r.DAG.Get(ctx, h) if err != nil { evt.Append(logging.LoggableMap{"error": err.Error()}) return nil, err } - return s.ResolveLinks(ctx, nd, parts) + return r.ResolveLinks(ctx, nd, parts) } // 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"}) // 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}) 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) 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 { evt.Append(logging.LoggableMap{"error": err.Error()}) 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 } - nextnode, err := lnk.GetNode(ctx, s.DAG) + nextnode, err := lnk.GetNode(ctx, r.DAG) if err != nil { evt.Append(logging.LoggableMap{"error": err.Error()}) return result, err