func formatItem(item lsItem, longFormat bool) [][]string {
	var entries []apitypes.Entry
	if item.Type() != dirItem {
		item.entry.CName = item.path
		entries = append(entries, item.entry)
	} else {
		entries = item.children
	}
	var rows [][]string
	for _, entry := range entries {
		var row []string
		if !longFormat {
			row = []string{cname(entry)}
		} else {
			mtimeStr, sizeStr := "<mtime unknown>", "<size unknown>"
			if entry.Attributes.HasMtime() {
				mtimeStr = formatTime(entry.Attributes.Mtime())
			}
			if entry.Attributes.HasSize() {
				sizeStr = strconv.FormatUint(entry.Attributes.Size(), 10)
			}
			sort.Strings(entry.Actions)
			verbs := strings.Join(entry.Actions, ", ")
			row = []string{verbs, sizeStr, mtimeStr, cname(entry)}
		}
		rows = append(rows, row)
	}
	return rows
}
item should be a "file"/"dir" type item. formatItem returns
an array of rows representing that item's entries
package cmd
import (
	"fmt"
	"sort"
	"strconv"
	"strings"
	"sync"
	"time"
	"github.com/spf13/cobra"
	apitypes "github.com/puppetlabs/wash/api/types"
	cmdutil "github.com/puppetlabs/wash/cmd/util"
	"github.com/puppetlabs/wash/plugin"
)
func lsCommand() *cobra.Command {
	lsCmd := &cobra.Command{
		Use:   "ls [<path>]...",
		Short: "Lists the children of the specified paths, or current directory if not specified",
		Long: `Lists the children of the specified paths, or current directory if
no path is specified. If the -l option is set, then the name,
last modified time, and supported actions are displayed for
each child.`,
		RunE: toRunE(lsMain),
	}
	lsCmd.Flags().BoolP("long", "l", false, "List in long format")
	return lsCmd
}
func formatTime(t time.Time) string {
	return t.Format(time.RFC822)
}
func cname(entry apitypes.Entry) string {
	cname := entry.CName
	if entry.Supports(plugin.ListAction()) {
		cname += "/"
	}
	return cname
}