func TestOptionParsing(t *testing.T) { subCmd := &commands.Command{} cmd := &commands.Command{ Options: []commands.Option{ commands.StringOption("string", "s", "a string"), commands.BoolOption("bool", "b", "a bool"), }, Subcommands: map[string]*commands.Command{ "test": subCmd, }, } testHelper := func(args string, expectedOpts kvs, expectedWords words, expectErr bool) { _, opts, input, _, err := parseOpts(strings.Split(args, " "), cmd) if expectErr { if err == nil { t.Errorf("Command line '%v' parsing should have failed", args) } } else if err != nil { t.Errorf("Command line '%v' failed to parse: %v", args, err) } else if !sameWords(input, expectedWords) || !sameKVs(opts, expectedOpts) { t.Errorf("Command line '%v':\n parsed as %v %v\n instead of %v %v", args, opts, input, expectedOpts, expectedWords) } } testFail := func(args string) { testHelper(args, kvs{}, words{}, true) } test := func(args string, expectedOpts kvs, expectedWords words) { testHelper(args, expectedOpts, expectedWords, false) } test("-", kvs{}, words{"-"}) testFail("-b -b") test("beep boop", kvs{}, words{"beep", "boop"}) test("test beep boop", kvs{}, words{"beep", "boop"}) testFail("-s") test("-s foo", kvs{"s": "foo"}, words{}) test("-sfoo", kvs{"s": "foo"}, words{}) test("-s=foo", kvs{"s": "foo"}, words{}) test("-b", kvs{"b": ""}, words{}) test("-bs foo", kvs{"b": "", "s": "foo"}, words{}) test("-sb", kvs{"s": "b"}, words{}) test("-b foo", kvs{"b": ""}, words{"foo"}) test("--bool foo", kvs{"bool": ""}, words{"foo"}) testFail("--bool=foo") testFail("--string") test("--string foo", kvs{"string": "foo"}, words{}) test("--string=foo", kvs{"string": "foo"}, words{}) test("-- -b", kvs{}, words{"-b"}) test("foo -b", kvs{"b": ""}, words{"foo"}) }
DEPRECATION NOTICE Previously, IPFS used an environment variable as seen below: export API_ORIGIN="http://localhost:8888/" This is deprecated. It is still honored in this version, but will be removed in a future version, along with this notice. Please move to setting the HTTP Headers. `, }, Options: []cmds.Option{ cmds.BoolOption(initOptionKwd, "Initialize IPFS with default settings if not already initialized"), cmds.StringOption(routingOptionKwd, "Overrides the routing option (dht, supernode)"), cmds.BoolOption(mountKwd, "Mounts IPFS to the filesystem"), cmds.BoolOption(writableKwd, "Enable writing objects (with POST, PUT and DELETE)"), cmds.StringOption(ipfsMountKwd, "Path to the mountpoint for IPFS (if using --mount)"), cmds.StringOption(ipnsMountKwd, "Path to the mountpoint for IPNS (if using --mount)"), cmds.BoolOption(unrestrictedApiAccessKwd, "Allow API access to unlisted hashes"), cmds.BoolOption(unencryptTransportKwd, "Disable transport encryption (for debugging protocols)"), // TODO: add way to override addresses. tricky part: updating the config if also --init. // cmds.StringOption(apiAddrKwd, "Address for the daemon rpc API (overrides config)"), // cmds.StringOption(swarmAddrKwd, "Address for the swarm socket (overrides config)"), }, Subcommands: map[string]*cmds.Command{}, Run: daemonFunc, }
Tagline: "Query IPFS statistics", ShortDescription: ``, }, Subcommands: map[string]*cmds.Command{ "bw": statBwCmd, }, } var statBwCmd = &cmds.Command{ Helptext: cmds.HelpText{ Tagline: "Print ipfs bandwidth information", ShortDescription: ``, }, Options: []cmds.Option{ cmds.StringOption("peer", "p", "specify a peer to print bandwidth for"), cmds.StringOption("proto", "t", "specify a protocol to print bandwidth for"), cmds.BoolOption("poll", "print bandwidth at an interval"), cmds.StringOption("interval", "i", "time interval to wait between updating output"), }, Run: func(req cmds.Request, res cmds.Response) { nd, err := req.InvocContext().GetNode() if err != nil { res.SetError(err, cmds.ErrNormal) return } // Must be online! if !nd.OnlineMode() { res.SetError(errNotOnline, cmds.ErrClient)
remains to be implemented. `, }, Arguments: []cmds.Argument{ cmds.FileArg("path", true, true, "The path to a file to be added to IPFS").EnableRecursive().EnableStdin(), }, Options: []cmds.Option{ cmds.OptionRecursivePath, // a builtin option that allows recursive paths (-r, --recursive) cmds.BoolOption(quietOptionName, "q", "Write minimal output"), cmds.BoolOption(progressOptionName, "p", "Stream progress data"), cmds.BoolOption(trickleOptionName, "t", "Use trickle-dag format for dag generation"), cmds.BoolOption(onlyHashOptionName, "n", "Only chunk and hash - do not write to disk"), cmds.BoolOption(wrapOptionName, "w", "Wrap files with a directory object"), cmds.BoolOption(hiddenOptionName, "Include files that are hidden"), cmds.StringOption(chunkerOptionName, "s", "chunking algorithm to use"), }, PreRun: func(req cmds.Request) error { if quiet, _, _ := req.Option(quietOptionName).Bool(); quiet { return nil } req.SetOption(progressOptionName, true) sizeFile, ok := req.Files().(files.SizeFile) if !ok { // we don't need to error, the progress bar just won't know how big the files are return nil } size, err := sizeFile.Size()
Prints out information about the specified peer, if no peer is specified, prints out local peers info. ipfs id supports the format option for output with the following keys: <id> : the peers id <aver>: agent version <pver>: protocol version <pubkey>: public key <addrs>: addresses (newline delimited) `, }, Arguments: []cmds.Argument{ cmds.StringArg("peerid", false, false, "peer.ID of node to look up").EnableStdin(), }, Options: []cmds.Option{ cmds.StringOption("f", "format", "optional output format"), }, Run: func(req cmds.Request, res cmds.Response) { node, err := req.InvocContext().GetNode() if err != nil { res.SetError(err, cmds.ErrNormal) return } if len(req.Arguments()) == 0 { output, err := printSelf(node) if err != nil { res.SetError(err, cmds.ErrNormal) return } res.SetOutput(output)
"Hash": "QmXg9Pp2ytZ14xgmQjYEiHjVjMFXzCVVEcRTWJBmLgR39V", "Size": 8 } ] } and then run ipfs object put node.json `, }, Arguments: []cmds.Argument{ cmds.FileArg("data", true, false, "Data to be stored as a DAG object").EnableStdin(), }, Options: []cmds.Option{ cmds.StringOption("inputenc", "Encoding type of input data, either \"protobuf\" or \"json\""), }, Run: func(req cmds.Request, res cmds.Response) { n, err := req.InvocContext().GetNode() if err != nil { res.SetError(err, cmds.ErrNormal) return } input, err := req.Files().NextFile() if err != nil && err != io.EOF { res.SetError(err, cmds.ErrNormal) return } inputenc, found, err := req.Option("inputenc").String()
ks = append(ks, dec) } bs.CancelWants(ks) }, } var showWantlistCmd = &cmds.Command{ Helptext: cmds.HelpText{ Tagline: "Show blocks currently on the wantlist", ShortDescription: ` Print out all blocks currently on the bitswap wantlist for the local peer`, }, Options: []cmds.Option{ cmds.StringOption("peer", "p", "specify which peer to show wantlist for (default self)"), }, Type: KeyList{}, Run: func(req cmds.Request, res cmds.Response) { nd, err := req.InvocContext().GetNode() if err != nil { res.SetError(err, cmds.ErrNormal) return } if !nd.OnlineMode() { res.SetError(errNotOnline, cmds.ErrClient) return } bs, ok := nd.Exchange.(*bitswap.Bitswap)
dht Query the dht for values or peers ping Measure the latency of a connection diag Print diagnostics TOOL COMMANDS config Manage configuration version Show ipfs version information update Download and apply go-ipfs updates commands List all available commands Use 'ipfs <command> --help' to learn more about each command. `, }, Options: []cmds.Option{ cmds.StringOption("config", "c", "Path to the configuration file to use"), cmds.BoolOption("debug", "D", "Operate in debug mode"), cmds.BoolOption("help", "Show the full command help text"), cmds.BoolOption("h", "Show a short version of the command help text"), cmds.BoolOption("local", "L", "Run the command locally, instead of using the daemon"), cmds.StringOption(ApiOption, "Overrides the routing option (dht, supernode)"), }, } // commandsDaemonCmd is the "ipfs commands" command for daemon var CommandsDaemonCmd = CommandsCmd(Root) var rootSubcommands = map[string]*cmds.Command{ "add": AddCmd, "block": BlockCmd, "bootstrap": BootstrapCmd,
Retrieves the object named by <ipfs-path> and displays the link hashes it contains, with the following format: <link base58 hash> Note: list all refs recursively with -r. `, }, Subcommands: map[string]*cmds.Command{ "local": RefsLocalCmd, }, Arguments: []cmds.Argument{ cmds.StringArg("ipfs-path", true, true, "Path to the object(s) to list refs from").EnableStdin(), }, Options: []cmds.Option{ cmds.StringOption("format", "Emit edges with given format. tokens: <src> <dst> <linkname>"), cmds.BoolOption("edges", "e", "Emit edge format: `<from> -> <to>`"), cmds.BoolOption("unique", "u", "Omit duplicate refs from output"), cmds.BoolOption("recursive", "r", "Recursively list links of child nodes"), }, Run: func(req cmds.Request, res cmds.Response) { ctx := req.Context() n, err := req.InvocContext().GetNode() if err != nil { res.SetError(err, cmds.ErrNormal) return } unique, _, err := req.Option("unique").Bool() if err != nil { res.SetError(err, cmds.ErrNormal)
> ipfs mount IPFS mounted at: /ipfs IPNS mounted at: /ipns > cd /ipfs/QmSh5e7S6fdcu75LAbXNZAFY2nGyZUJXyLCJDvn2zRkWyC > ls bar > cat bar baz > cat /ipfs/QmSh5e7S6fdcu75LAbXNZAFY2nGyZUJXyLCJDvn2zRkWyC/bar baz > cat /ipfs/QmWLdkp93sNxGRjnFHPaYg8tCQ35NBY3XPn6KiETd3Z4WR baz `, }, Options: []cmds.Option{ cmds.StringOption("ipfs-path", "f", "The path where IPFS should be mounted"), cmds.StringOption("ipns-path", "n", "The path where IPNS should be mounted"), }, Run: func(req cmds.Request, res cmds.Response) { cfg, err := req.InvocContext().GetConfig() if err != nil { res.SetError(err, cmds.ErrNormal) return } node, err := req.InvocContext().GetNode() if err != nil { res.SetError(err, cmds.ErrNormal) return }
By default, the output will be stored at ./<ipfs-path>, but an alternate path can be specified with '--output=<path>' or '-o=<path>'. To output a TAR archive instead of unpacked files, use '--archive' or '-a'. To compress the output with GZIP compression, use '--compress' or '-C'. You may also specify the level of compression by specifying '-l=<1-9>'. `, }, Arguments: []cmds.Argument{ cmds.StringArg("ipfs-path", true, false, "The path to the IPFS object(s) to be outputted").EnableStdin(), }, Options: []cmds.Option{ cmds.StringOption("output", "o", "The path where output should be stored"), cmds.BoolOption("archive", "a", "Output a TAR archive"), cmds.BoolOption("compress", "C", "Compress the output with GZIP compression"), cmds.IntOption("compression-level", "l", "The level of compression (1-9)"), }, PreRun: func(req cmds.Request) error { _, err := getCompressOptions(req) return err }, Run: func(req cmds.Request, res cmds.Response) { cmplvl, err := getCompressOptions(req) if err != nil { res.SetError(err, cmds.ErrClient) return }
Returns a list of hashes of objects being pinned. Objects that are indirectly or recursively pinned are not included in the list. Use --type=<type> to specify the type of pinned keys to list. Valid values are: * "direct": pin that specific object. * "recursive": pin that specific object, and indirectly pin all its decendants * "indirect": pinned indirectly by an ancestor (like a refcount) * "all" To see the ref count on indirect pins, pass the -count option flag. Defaults to "direct". `, }, Options: []cmds.Option{ cmds.StringOption("type", "t", "The type of pinned keys to list. Can be \"direct\", \"indirect\", \"recursive\", or \"all\". Defaults to \"direct\""), cmds.BoolOption("count", "n", "Show refcount when listing indirect pins"), cmds.BoolOption("quiet", "q", "Write just hashes of objects"), }, Run: func(req cmds.Request, res cmds.Response) { n, err := req.InvocContext().GetNode() if err != nil { res.SetError(err, cmds.ErrNormal) return } typeStr, found, err := req.Option("type").String() if err != nil { res.SetError(err, cmds.ErrNormal) return }