Documentationcurrent version
Help us improve the docs by fixing typos and proposing enhancements.


Action "fs.mkdir"

Recursively create a directory. The behavior is similar to the Unix command mkdir -p. It supports an alternative syntax where config is simply the path of the directory to create.

Permissions defined in the mode configuration are set on directory creation. Use force to update the target directory if it exists and if its value is different than expected. Parent directories are not impacted by force.


  • err
    Error object if any.
  • status
    Value is "true" if directory was created or modified.

Simple usage

const {$status} = await nikita.fs.mkdir('./some/dir')`Directory was created: ${$status}`)

Advanced usage

const {$status} = await nikita.fs.mkdir({
  $ssh: ssh,
  target: './some/dir',
  uid: 'a_user',
  gid: 'a_group'
  mode: 0o0777 // or '777'
})`Directory was created: ${$status}`)


on_action = ({config, metadata}) ->
  config.parent ?= {}
  config.parent = {} if config.parent is true

Schema definitions

definitions =
    type: 'object'
        type: ['boolean', 'string']
        description: '''
        Current working directory for relative paths. A boolean value only
        apply without an SSH connection and default to `process.cwd()`.
        instanceof: 'RegExp'
        description: '''
        Exclude directories matching a regular expression. For example, the
        expression `/\${/` on './var/cache/${user}' exclude the directories
        containing a variables and only apply to `./var/cache/`.
        type: ['boolean']
        description: '''
        Overwrite permissions on the target directory. By default,
        permissions on only set on directory creation. It does not impact
        the parent directory permissions.
        $ref: 'module://@nikitajs/core/src/actions/fs/chown#/definitions/config/properties/gid'
        $ref: 'module://@nikitajs/core/src/actions/fs/chmod#/definitions/config/properties/mode'
        oneOf: [
          type: 'boolean'
          type: 'object'
              $ref: 'module://@nikitajs/core/src/actions/fs/mkdir#/definitions/config/properties/gid'
              $ref: 'module://@nikitajs/core/src/actions/fs/mkdir#/definitions/config/properties/mode'
              $ref: 'module://@nikitajs/core/src/actions/fs/mkdir#/definitions/config/properties/uid'
        description: '''
        Create parent directory with provided attributes if an object or
        default system options if "true", supported attributes include 'mode',
        'uid', 'gid', 'size', 'atime', and 'mtime'.
        type: 'string'
        description: '''
        Location of the directory to create.
        $ref: 'module://@nikitajs/core/src/actions/fs/chown#/definitions/config/properties/uid'
    required: ['target']


handler = ({config, tools: {log, path}, ssh}) ->
  # Configuration validation
  config.cwd = process.cwd() if not ssh and (config.cwd is true or not config.cwd)
  config.parent = {} if config.parent is true = if config.cwd then path.resolve config.cwd, else path.normalize
  if ssh and not path.isAbsolute
    throw errors.NIKITA_MKDIR_TARGET_RELATIVE config: config
  # Retrieve every directories including parents
  parents = path.sep
  parents.shift() # first element is empty with absolute path
  parents.pop() if parents[parents.length - 1] is ''
  parents = for i in [0...parents.length]
    '/' + parents.slice(0, parents.length - i).join '/'
  # Discovery of directories to create
  creates = []
  for target, i in parents
      {stats} = await @fs.base.stat target
      break if utils.stats.isDirectory stats.mode
      throw errors.NIKITA_MKDIR_TARGET_INVALID_TYPE stats: stats, target: target
    catch err
      if err.code is 'NIKITA_FS_STAT_TARGET_ENOENT'
        creates.push target
      else throw err
  # Target and parent directory creation
  for target, i in creates.reverse()
    if config.exclude? and config.exclude instanceof RegExp
      break if config.exclude.test path.basename target
    opts = {}
    for attr in ['mode', 'uid', 'gid', 'size', 'atime', 'mtime']
      val = if i is creates.length - 1 then config[attr] else config.parent?[attr]
      opts[attr] = val if val?
    await @fs.base.mkdir target, opts
    log message: "Directory \"#{target}\" created ", level: 'INFO'
  # Target directory update
  # Do not create directory unless `force` is set
  if config.force and creates.length is 0
    log message: "Directory already exists", level: 'DEBUG'
    await @fs.chown
      $if: config.uid? or config.gid?
      stats: stats
      uid: config.uid
      gid: config.gid
    await @fs.chmod
      $if: config.mode?
      stats: stats
      mode: config.mode


module.exports =
  handler: handler
    on_action: on_action
    argument_to_config: 'target'
    definitions: definitions


errors =
      'only absolute path are supported over SSH,'
      'target is relative and config `cwd` is not provided,'
      "got #{JSON.stringify}"
  NIKITA_MKDIR_TARGET_INVALID_TYPE: ({stats, target}) ->
      'target exists but it is not a directory,'
      "got #{JSON.stringify utils.stats.type stats.mode} type"
      "for #{JSON.stringify target}"
      target: target


utils = require '../../utils'
Edit on GitHub

Nikita is an open source project hosted on GitHub and developed by Adaltas.