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

Nikita

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.

Output

  • 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')
console.info(`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'
})
console.info(`Directory was created: ${$status}`)

Hooks

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

Schema definitions

definitions =
  config:
    type: 'object'
    properties:
      'cwd':
        type: ['boolean', 'string']
        description: '''
        Current working directory for relative paths. A boolean value only
        apply without an SSH connection and default to `process.cwd()`.
        '''
      'exclude':
        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/`.
        '''
      'force':
        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.
        '''
      'gid':
        $ref: 'module://@nikitajs/core/src/actions/fs/chown#/definitions/config/properties/gid'
      'mode':
        $ref: 'module://@nikitajs/core/src/actions/fs/chmod#/definitions/config/properties/mode'
      'parent':
        oneOf: [
          type: 'boolean'
        ,
          type: 'object'
          properties:
            'gid':
              $ref: 'module://@nikitajs/core/src/actions/fs/mkdir#/definitions/config/properties/gid'
            'mode':
              $ref: 'module://@nikitajs/core/src/actions/fs/mkdir#/definitions/config/properties/mode'
            'uid':
              $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'.
        '''
      'target':
        type: 'string'
        description: '''
        Location of the directory to create.
        '''
      'uid':
        $ref: 'module://@nikitajs/core/src/actions/fs/chown#/definitions/config/properties/uid'
    required: ['target']
    

Handler

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
  config.target = if config.cwd then path.resolve config.cwd, config.target else path.normalize config.target
  if ssh and not path.isAbsolute config.target
    throw errors.NIKITA_MKDIR_TARGET_RELATIVE config: config
  # Retrieve every directories including parents
  parents = config.target.split 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
    try
      {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?
      target: config.target
      stats: stats
      uid: config.uid
      gid: config.gid
    await @fs.chmod
      $if: config.mode?
      target: config.target
      stats: stats
      mode: config.mode
  {}

Exports

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

Errors

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

Dependencies

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

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