28
offline "github.com/ipfs/boxo/exchange/offline"
29
dag "github.com/ipfs/boxo/ipld/merkledag"
30
ft "github.com/ipfs/boxo/ipld/unixfs"
31
- uio "github.com/ipfs/boxo/ipld/unixfs/io"
31
mfs "github.com/ipfs/boxo/mfs"
32
"github.com/ipfs/boxo/path"
33
cid "github.com/ipfs/go-cid"
504
return err
505
}
506
508
- prefix, err := getPrefixNew(req, &cfg.Import)
507
+ prefix, err := getPrefix(req, &cfg.Import)
508
if err != nil {
509
return err
510
}
557
if mkParents {
558
maxDirLinks := int(cfg.Import.UnixFSDirectoryMaxLinks.WithDefault(config.DefaultUnixFSDirectoryMaxLinks))
559
sizeEstimationMode := cfg.Import.HAMTSizeEstimationMode()
561
- err := ensureContainingDirectoryExists(nd.FilesRoot, dst, prefix, maxDirLinks, &sizeEstimationMode)
560
+ err := ensureContainingDirectoryExists(nd.FilesRoot, dst,
561
+ mfs.WithCidBuilder(prefix),
562
+ mfs.WithMaxLinks(maxDirLinks),
563
+ mfs.WithSizeEstimationMode(sizeEstimationMode),
564
+ )
565
if err != nil {
566
return err
567
}
1063
rawLeaves = cfg.Import.UnixFSRawLeaves.WithDefault(config.DefaultUnixFSRawLeaves)
1064
}
1065
1063
- prefix, err := getPrefixNew(req, &cfg.Import)
1066
+ prefix, err := getPrefix(req, &cfg.Import)
1067
if err != nil {
1068
return err
1069
}
1076
if mkParents {
1077
maxDirLinks := int(cfg.Import.UnixFSDirectoryMaxLinks.WithDefault(config.DefaultUnixFSDirectoryMaxLinks))
1078
sizeEstimationMode := cfg.Import.HAMTSizeEstimationMode()
1076
- err := ensureContainingDirectoryExists(nd.FilesRoot, path, prefix, maxDirLinks, &sizeEstimationMode)
1079
+ err := ensureContainingDirectoryExists(nd.FilesRoot, path,
1080
+ mfs.WithCidBuilder(prefix),
1081
+ mfs.WithMaxLinks(maxDirLinks),
1082
+ mfs.WithSizeEstimationMode(sizeEstimationMode),
1083
+ )
1084
if err != nil {
1085
return err
1086
}
1210
maxDirLinks := int(cfg.Import.UnixFSDirectoryMaxLinks.WithDefault(config.DefaultUnixFSDirectoryMaxLinks))
1211
sizeEstimationMode := cfg.Import.HAMTSizeEstimationMode()
1212
1206
- err = mfs.Mkdir(root, dirtomake, mfs.MkdirOpts{
1207
- Mkparents: dashp,
1208
- Flush: flush,
1209
- CidBuilder: prefix,
1210
- MaxLinks: maxDirLinks,
1211
- SizeEstimationMode: &sizeEstimationMode,
1212
- })
1213
+ err = mfs.Mkdir(root, dirtomake, mfs.MkdirOpts{Mkparents: dashp, Flush: flush},
1214
+ mfs.WithCidBuilder(prefix),
1215
+ mfs.WithMaxLinks(maxDirLinks),
1216
+ mfs.WithSizeEstimationMode(sizeEstimationMode),
1217
+ )
1218
1219
return err
1220
},
1269
Tagline: "Change the CID version or hash function of the root node of a given path.",
1270
ShortDescription: `
1271
Change the CID version or hash function of the root node of a given path.
1272
+
1273
+Note: the MFS root ('/') CID format is controlled by Import.CidVersion and
1274
+Import.HashFunction in the config and cannot be changed with this command.
1275
+Use 'ipfs config' to modify these values instead. This command only works
1276
+on subdirectories of the MFS root.
1277
`,
1278
},
1279
Arguments: []cmds.Argument{
1270
- cmds.StringArg("path", false, false, "Path to change. Default: '/'."),
1280
+ cmds.StringArg("path", true, false, "Path to change (must not be '/')."),
1281
},
1282
Options: []cmds.Option{
1283
cidVersionOption,
1289
return err
1290
}
1291
1282
- path := "/"
1283
- if len(req.Arguments) > 0 {
1284
- path = req.Arguments[0]
1292
+ path := req.Arguments[0]
1293
+ if path == "/" {
1294
+ return fmt.Errorf("cannot change CID format of the MFS root; " +
1295
+ "use 'ipfs config Import.CidVersion' and 'ipfs config Import.HashFunction' instead")
1296
}
1297
1298
flush, _ := req.Options[filesFlushOptionName].(bool)
1457
return pdir.Flush()
1458
}
1459
1449
-func getPrefixNew(req *cmds.Request, importCfg *config.Import) (cid.Builder, error) {
1450
- cidVer, cidVerSet := req.Options[filesCidVersionOptionName].(int)
1451
- hashFunStr, hashFunSet := req.Options[filesHashOptionName].(string)
1452
-
1453
- // Fall back to Import config if CLI options not set
1454
- if !cidVerSet && importCfg != nil && !importCfg.CidVersion.IsDefault() {
1455
- cidVer = int(importCfg.CidVersion.WithDefault(config.DefaultCidVersion))
1456
- cidVerSet = true
1457
- }
1458
- if !hashFunSet && importCfg != nil && !importCfg.HashFunction.IsDefault() {
1459
- hashFunStr = importCfg.HashFunction.WithDefault(config.DefaultHashFunction)
1460
- hashFunSet = true
1461
- }
1462
-
1463
- if !cidVerSet && !hashFunSet {
1464
- return nil, nil
1465
- }
1466
-
1467
- if hashFunSet && cidVer == 0 {
1468
- cidVer = 1
1469
- }
1470
-
1471
- prefix, err := dag.PrefixForCidVersion(cidVer)
1472
- if err != nil {
1473
- return nil, err
1474
- }
1475
-
1476
- if hashFunSet {
1477
- hashFunCode, ok := mh.Names[strings.ToLower(hashFunStr)]
1478
- if !ok {
1479
- return nil, fmt.Errorf("unrecognized hash function: %s", strings.ToLower(hashFunStr))
1480
- }
1481
- prefix.MhType = hashFunCode
1482
- prefix.MhLength = -1
1483
- }
1484
-
1485
- return &prefix, nil
1486
-}
1487
-
1460
+// getPrefix builds a cid.Builder from CLI flags, falling back to importCfg
1461
+// when provided. Returns (nil, nil) when neither CLI nor config set a value.
1462
func getPrefix(req *cmds.Request, importCfg *config.Import) (cid.Builder, error) {
1463
cidVer, cidVerSet := req.Options[filesCidVersionOptionName].(int)
1464
hashFunStr, hashFunSet := req.Options[filesHashOptionName].(string)
1465
1492
- // Fall back to Import config if CLI options not set
1493
- if !cidVerSet && importCfg != nil && !importCfg.CidVersion.IsDefault() {
1494
- cidVer = int(importCfg.CidVersion.WithDefault(config.DefaultCidVersion))
1495
- cidVerSet = true
1496
- }
1497
- if !hashFunSet && importCfg != nil && !importCfg.HashFunction.IsDefault() {
1498
- hashFunStr = importCfg.HashFunction.WithDefault(config.DefaultHashFunction)
1499
- hashFunSet = true
1500
- }
1501
-
1502
- if !cidVerSet && !hashFunSet {
1503
- return nil, nil
1504
- }
1505
-
1506
- if hashFunSet && cidVer == 0 {
1507
- cidVer = 1
1508
- }
1509
-
1510
- prefix, err := dag.PrefixForCidVersion(cidVer)
1511
- if err != nil {
1512
- return nil, err
1466
+ if cidVerSet || hashFunSet {
1467
+ // CLI flags take precedence: build prefix from them directly.
1468
+ if hashFunSet && cidVer == 0 {
1469
+ cidVer = 1
1470
+ }
1471
+ prefix, err := dag.PrefixForCidVersion(cidVer)
1472
+ if err != nil {
1473
+ return nil, err
1474
+ }
1475
+ if hashFunSet {
1476
+ hashFunCode, ok := mh.Names[strings.ToLower(hashFunStr)]
1477
+ if !ok {
1478
+ return nil, fmt.Errorf("unrecognized hash function: %q", hashFunStr)
1479
+ }
1480
+ prefix.MhType = hashFunCode
1481
+ prefix.MhLength = -1
1482
+ }
1483
+ return &prefix, nil
1484
}
1485
1515
- if hashFunSet {
1516
- hashFunCode, ok := mh.Names[strings.ToLower(hashFunStr)]
1517
- if !ok {
1518
- return nil, fmt.Errorf("unrecognized hash function: %s", strings.ToLower(hashFunStr))
1519
- }
1520
- prefix.MhType = hashFunCode
1521
- prefix.MhLength = -1
1486
+ // No CLI flags: fall back to Import config.
1487
+ if importCfg != nil {
1488
+ return importCfg.UnixFSCidBuilder()
1489
}
1490
1524
- return &prefix, nil
1491
+ return nil, nil
1492
}
1493
1527
-func ensureContainingDirectoryExists(r *mfs.Root, path string, builder cid.Builder, maxLinks int, sizeEstimationMode *uio.SizeEstimationMode) error {
1494
+func ensureContainingDirectoryExists(r *mfs.Root, path string, opts ...mfs.Option) error {
1495
dirtomake := gopath.Dir(path)
1496
1497
if dirtomake == "/" {
1498
return nil
1499
}
1500
1534
- return mfs.Mkdir(r, dirtomake, mfs.MkdirOpts{
1535
- Mkparents: true,
1536
- CidBuilder: builder,
1537
- MaxLinks: maxLinks,
1538
- SizeEstimationMode: sizeEstimationMode,
1539
- })
1501
+ return mfs.Mkdir(r, dirtomake, mfs.MkdirOpts{Mkparents: true}, opts...)
1502
}
1503
1504
func getFileHandle(r *mfs.Root, path string, create bool, builder cid.Builder) (*mfs.File, error) {