mkdir method

Future<void> mkdir(
  1. String path, {
  2. bool recursive = false,
  3. bool parents = false,
  4. int? cidVersion,
  5. String? hash,
  6. int? mode,
  7. int? mtimeSecs,
  8. int? mtimeNsecs,
})

Creates a directory at the given path.

parents and recursive are aliases for creating intermediate directories and succeeding when the directory already exists — matching Kubo's ipfs files mkdir --parents. Without them an existing path is an error, as is a path whose parent does not exist.

mode, mtimeSecs and mtimeNsecs store optional UnixFS 1.5 metadata on the created directory.

Implementation

Future<void> mkdir(
  String path, {
  bool recursive = false,
  bool parents = false,
  int? cidVersion,
  String? hash,
  int? mode,
  int? mtimeSecs,
  int? mtimeNsecs,
}) async {
  final createMissing = recursive || parents;
  final parts = _splitPath(path);
  if (parts.isEmpty) {
    // `mkdir /` is a no-op only when parents is requested.
    if (createMissing) return;
    throw Exception('file already exists: $path');
  }

  await _mutationLock.synchronized(() async {
    await _modifyPath(
      parts,
      (currentCid) async {
        if (currentCid != null) {
          final existingType = await _unixfsType(currentCid);
          if (createMissing && existingType == Data_DataType.Directory) {
            // Directory already exists: `mkdir -p` is idempotent.
            return currentCid;
          }
          throw Exception('file already exists: $path');
        }
        final dirManager = IPFSDirectoryManager();
        if (mode != null) dirManager.setMode(mode);
        if (mtimeSecs != null) {
          dirManager.setModificationTime(
            DateTime.fromMillisecondsSinceEpoch(
              mtimeSecs * 1000,
              isUtc: true,
            ),
          );
        }
        final node = dirManager.build();
        if (mtimeNsecs != null) {
          final unixData = Data.fromBuffer(node.data)
            ..mtimeNsecs = mtimeNsecs;
          node.data = unixData.writeToBuffer();
        }
        final data = marshalDagPBNode(node);
        final cid = await CID.fromContent(
          data,
          codec: 'dag-pb',
          hashType: hash ?? 'sha2-256',
          version: cidVersion ?? 0,
        );
        await _blockStore.putBlock(
          Block(cid: cid, data: data, format: 'dag-pb'),
        );
        return cid;
      },
      recursive: createMissing,
      isDirectory: true,
    );
  });
}