code: def _makeds(path, levels, ds=None, max_leading_dirs=2):
      """Create a hierarchy of datasets
  
      Used recursively, with current invocation generating datasets for the
      first level, and delegating sub-levels to recursive invocation
  
      Parameters
      ----------
      path : str
        Path to the top directory under which dataset will be created.
        If relative -- relative to current directory
      levels : list of list
        List of specifications for :func:`random.randint` call per each level.
      ds : Dataset, optional
        Super-dataset which would contain a new dataset (thus its path would be
        a parent of path. Note that ds needs to be installed.
      max_leading_dirs : int, optional
        Up to how many leading directories within a dataset could lead to a
        sub-dataset
  
      Yields
      ------
      str
         Path to the generated dataset(s)
  
      """
      # we apparently can't import api functionality within api
      from datalad.api import save
  
      # To simplify managing all the file paths etc
      if not isabs(path):
          path = abspath(path)
      # make it a git (or annex??) repository... ok - let's do randomly one or another ;)
      RepoClass = GitRepo if random.randint(0, 1) else AnnexRepo
      lgr.info("Generating repo of class %s under %s", RepoClass, path)
      repo = RepoClass(path, create=True)
      # let's create some dummy file and add it to the beast
      fn = opj(path, "file%d.dat" % random.randint(1, 1000))
      with open(fn, "w") as f:
          f.write(fn)
      repo.add(fn, git=True)
      repo.commit(msg="Added %s" % fn)
  
      yield path
  
      if levels:
          # make a dataset for that one since we want to add sub datasets
          ds_ = Dataset(path)
          # Process the levels
          level, levels_ = levels[0], levels[1:]
          nrepos = random.randint(*level)  # how many subds to generate
          for irepo in range(nrepos):
              # we would like to have up to 2 leading dirs
              subds_path = opj(
                  *(
                      [
                          "d%i" % i
                          for i in range(
                              random.randint(0, max_leading_dirs + 1)
                          )
                      ]
                      + ["r%i" % irepo]
                  )
              )
              subds_fpath = opj(path, subds_path)
              # yield all under
              for d in _makeds(subds_fpath, levels_, ds=ds_):
                  yield d
  
      if ds:
          assert ds.is_installed()
          out = save(
              path,
              dataset=ds,
          )
  
file_path: datalad/datalad/distribution/create_test_dataset.py
imports: import random
  import logging
  import tempfile
  from datalad.utils import get_tempfile_kwargs
  import os
  from os.path import join, exists, isabs, abspath
  from datalad.distribution.dataset import Dataset
  from datalad.support.param import Parameter
  from datalad.support.constraints import EnsureStr, EnsureNone, EnsureInt
  from datalad.support.gitrepo import GitRepo
  from datalad.support.annexrepo import AnnexRepo
  from datalad.interface.base import Interface
  from datalad.interface.base import build_doc
label_desc: Use image node_id 2 for calling a global function with example usage: _makeds(path, levels, ds, max_leading_dirs) without return types