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"}) }
ipfs config --json API.HTTPHeaders.Access-Control-Allow-Credentials '["true"]' 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, }
}, 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) return }
namesys "github.com/djbarber/ipfs-hack/namesys" config "github.com/djbarber/ipfs-hack/repo/config" fsrepo "github.com/djbarber/ipfs-hack/repo/fsrepo" ) const nBitsForKeypairDefault = 2048 var initCmd = &cmds.Command{ Helptext: cmds.HelpText{ Tagline: "Initializes IPFS config file", ShortDescription: "Initializes IPFS configuration files and generates a new keypair.", }, Options: []cmds.Option{ cmds.IntOption("bits", "b", fmt.Sprintf("Number of bits to use in the generated RSA private key (defaults to %d)", nBitsForKeypairDefault)), cmds.BoolOption("force", "f", "Overwrite existing config (if it exists)"), cmds.BoolOption("empty-repo", "e", "Don't add and pin help files to the local storage"), // TODO need to decide whether to expose the override as a file or a // directory. That is: should we allow the user to also specify the // name of the file? // TODO cmds.StringOption("event-logs", "l", "Location for machine-readable event logs"), }, PreRun: func(req cmds.Request) error { daemonLocked, err := fsrepo.LockedByOtherProcess(req.InvocContext().ConfigRoot) if err != nil { return err } log.Info("checking if daemon is running...") if daemonLocked {
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 } node, err := req.InvocContext().GetNode()
} return buf, nil }, }, Type: addrMap{}, } var swarmAddrsLocalCmd = &cmds.Command{ Helptext: cmds.HelpText{ Tagline: "List local addresses.", ShortDescription: ` ipfs swarm addrs local lists all local addresses the node is listening on. `, }, Options: []cmds.Option{ cmds.BoolOption("id", "Show peer ID in addresses"), }, Run: func(req cmds.Request, res cmds.Response) { n, err := req.InvocContext().GetNode() if err != nil { res.SetError(err, cmds.ErrNormal) return } if n.PeerHost == nil { res.SetError(errNotOnline, cmds.ErrClient) return } showid, _, _ := req.Option("id").Bool()
cmds "github.com/djbarber/ipfs-hack/commands" config "github.com/djbarber/ipfs-hack/repo/config" ) type VersionOutput struct { Version string } var VersionCmd = &cmds.Command{ Helptext: cmds.HelpText{ Tagline: "Shows ipfs version information", ShortDescription: "Returns the current version of ipfs and exits.", }, Options: []cmds.Option{ cmds.BoolOption("number", "n", "Only show the version number"), }, Run: func(req cmds.Request, res cmds.Response) { res.SetOutput(&VersionOutput{ Version: config.CurrentVersionNumber, }) }, Marshalers: cmds.MarshalerMap{ cmds.Text: func(res cmds.Response) (io.Reader, error) { v := res.Output().(*VersionOutput) number, found, err := res.Request().Option("number").Bool() if err != nil { return nil, err } if found && number {
var LsCmd = &cmds.Command{ Helptext: cmds.HelpText{ Tagline: "List links from an object.", ShortDescription: ` Retrieves the object named by <ipfs-or-ipns-path> and displays the links it contains, with the following format: <link base58 hash> <link size in bytes> <link name> `, }, Arguments: []cmds.Argument{ cmds.StringArg("ipfs-path", true, true, "The path to the IPFS object(s) to list links from").EnableStdin(), }, Options: []cmds.Option{ cmds.BoolOption("headers", "", "Print table headers (Hash, Name, Size)"), }, Run: func(req cmds.Request, res cmds.Response) { node, err := req.InvocContext().GetNode() if err != nil { res.SetError(err, cmds.ErrNormal) return } // get options early -> exit early in case of error if _, _, err := req.Option("headers").Bool(); err != nil { res.SetError(err, cmds.ErrNormal) return } paths := req.Arguments()
"gc": repoGcCmd, }, } var repoGcCmd = &cmds.Command{ Helptext: cmds.HelpText{ Tagline: "Perform a garbage collection sweep on the repo", ShortDescription: ` 'ipfs repo gc' is a plumbing command that will sweep the local set of stored objects and remove ones that are not pinned in order to reclaim hard disk space. `, }, Options: []cmds.Option{ cmds.BoolOption("quiet", "q", "Write minimal output"), }, Run: func(req cmds.Request, res cmds.Response) { n, err := req.InvocContext().GetNode() if err != nil { res.SetError(err, cmds.ErrNormal) return } gcOutChan, err := corerepo.GarbageCollectAsync(n, req.Context()) if err != nil { res.SetError(err, cmds.ErrNormal) return } outChan := make(chan interface{})
a file containing 'bar', and returns the hash of the new object. ipfs object patch $FOO_BAR rm-link foo This removes the link named foo from the hash in $FOO_BAR and returns the resulting object hash. The data inside the node can be modified as well: ipfs object patch $FOO_BAR set-data < file.dat ipfs object patch $FOO_BAR append-data < file.dat `, }, Options: []cmds.Option{ cmds.BoolOption("create", "p", "create intermediate directories on add-link"), }, Arguments: []cmds.Argument{ cmds.StringArg("root", true, false, "the hash of the node to modify"), cmds.StringArg("command", true, false, "the operation to perform"), cmds.StringArg("args", true, true, "extra arguments").EnableStdin(), }, Type: Object{}, Run: func(req cmds.Request, res cmds.Response) { nd, err := req.InvocContext().GetNode() if err != nil { res.SetError(err, cmds.ErrNormal) return } rootarg := req.Arguments()[0]
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, "cat": CatCmd,
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) return
"get": getValueDhtCmd, "put": putValueDhtCmd, }, } var queryDhtCmd = &cmds.Command{ Helptext: cmds.HelpText{ Tagline: "Run a 'findClosestPeers' query through the DHT", ShortDescription: ``, }, Arguments: []cmds.Argument{ cmds.StringArg("peerID", true, true, "The peerID to run the query against"), }, Options: []cmds.Option{ cmds.BoolOption("verbose", "v", "Write extra information"), }, Run: func(req cmds.Request, res cmds.Response) { n, err := req.InvocContext().GetNode() if err != nil { res.SetError(err, cmds.ErrNormal) return } dht, ok := n.Routing.(*ipdht.IpfsDHT) if !ok { res.SetError(ErrNotDHT, cmds.ErrNormal) return } events := make(chan *notif.QueryEvent)
ipfs.ipfs.io. TXT "dnslink=/dns/ipfs.io ..." The resolver will give: > ipfs dns ipfs.io /dns/ipfs.io > ipfs dns --recursive /ipfs/QmRzTuh2Lpuz7Gr39stNr6mTFdqAghsZec1JoUnfySUzcy `, }, Arguments: []cmds.Argument{ cmds.StringArg("domain-name", true, false, "The domain-name name to resolve.").EnableStdin(), }, Options: []cmds.Option{ cmds.BoolOption("recursive", "r", "Resolve until the result is not a DNS link"), }, Run: func(req cmds.Request, res cmds.Response) { recursive, _, _ := req.Option("recursive").Bool() name := req.Arguments()[0] resolver := namesys.NewDNSResolver() depth := 1 if recursive { depth = namesys.DefaultDepthLimit } output, err := resolver.ResolveN(req.Context(), name, depth) if err != nil { res.SetError(err, cmds.ErrNormal) return
Get the value of the 'datastore.path' key: ipfs config datastore.path Set the value of the 'datastore.path' key: ipfs config datastore.path ~/.ipfs/datastore `, }, Arguments: []cmds.Argument{ cmds.StringArg("key", true, false, "The key of the config entry (e.g. \"Addresses.API\")"), cmds.StringArg("value", false, false, "The value to set the config entry to"), }, Options: []cmds.Option{ cmds.BoolOption("bool", "Set a boolean value"), cmds.BoolOption("json", "Parse stringified JSON"), }, Run: func(req cmds.Request, res cmds.Response) { args := req.Arguments() key := args[0] r, err := fsrepo.Open(req.InvocContext().ConfigRoot) if err != nil { res.SetError(err, cmds.ErrNormal) return } defer r.Close() var output *ConfigField if len(args) == 2 {
} var bootstrapAddCmd = &cmds.Command{ Helptext: cmds.HelpText{ Tagline: "Add peers to the bootstrap list", ShortDescription: `Outputs a list of peers that were added (that weren't already in the bootstrap list). ` + bootstrapSecurityWarning, }, Arguments: []cmds.Argument{ cmds.StringArg("peer", false, true, peerOptionDesc).EnableStdin(), }, Options: []cmds.Option{ cmds.BoolOption("default", "add default bootstrap nodes"), }, Run: func(req cmds.Request, res cmds.Response) { inputPeers, err := config.ParseBootstrapPeers(req.Arguments()) if err != nil { res.SetError(err, cmds.ErrNormal) return } r, err := fsrepo.Open(req.InvocContext().ConfigRoot) if err != nil { res.SetError(err, cmds.ErrNormal) return } defer r.Close()
Helptext: cmds.HelpText{ Tagline: "Add an object to ipfs.", ShortDescription: ` Adds contents of <path> to ipfs. Use -r to add directories. Note that directories are added recursively, to form the ipfs MerkleDAG. A smarter partial add with a staging area (like git) 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)
> ipfs resolve /ipns/QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n /ipns/QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy Resolve the value of another name recursively: > ipfs resolve -r /ipns/QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n /ipfs/Qmcqtw8FfrVSBaRmbWwHxt3AuySBhJLcvmFYi3Lbc4xnwj `, }, Arguments: []cmds.Argument{ cmds.StringArg("name", true, false, "The name to resolve.").EnableStdin(), }, Options: []cmds.Option{ cmds.BoolOption("recursive", "r", "Resolve until the result is an IPFS name"), }, Run: func(req cmds.Request, res cmds.Response) { n, err := req.InvocContext().GetNode() if err != nil { res.SetError(err, cmds.ErrNormal) return } if !n.OnlineMode() { err := n.SetupOfflineRouting() if err != nil { res.SetError(err, cmds.ErrNormal) return }
} var addPinCmd = &cmds.Command{ Helptext: cmds.HelpText{ Tagline: "Pins objects to local storage", ShortDescription: ` Retrieves the object named by <ipfs-path> and stores it locally on disk. `, }, Arguments: []cmds.Argument{ cmds.StringArg("ipfs-path", true, true, "Path to object(s) to be pinned").EnableStdin(), }, Options: []cmds.Option{ cmds.BoolOption("recursive", "r", "Recursively pin the object linked to by the specified object(s)"), }, Type: PinOutput{}, Run: func(req cmds.Request, res cmds.Response) { n, err := req.InvocContext().GetNode() if err != nil { res.SetError(err, cmds.ErrNormal) return } // set recursive flag recursive, found, err := req.Option("recursive").Bool() if err != nil { res.SetError(err, cmds.ErrNormal) return }