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

Nikita

Action "fs.glob"

Search for files in a directory hierarchy.

Implementation

The action use the POXIX find command to fetch all files and filter the paths locally using the Minimatch package.

Output

  • files
    List of files matching the globing expression.

Examples

Short notation:

const {files} = await nikita.fs.glob(`${process.cwd()}/*`)
for(const file of files){
  console.info(`Found: ${file}`)
}

Extended notation:

const {files} = await nikita.fs.glob({
  dot: true,
  target: `${process.cwd()}/*`
})
for(const file of files){
  console.info(`Found: ${file}`)
}

Schema definitions

definitions =
  config:
    type: 'object'
    properties:
      'dot':
        type: 'boolean'
        description: '''
        Minimatch option to handle files starting with a ".".
        '''
      'target':
        type: 'string'
        description: '''
        Globbing expression of the directory tree to match.
        '''
      'trailing':
        type: 'boolean'
        default: false
        description: '''
        Leave a slash at the end of directories.
        '''
      'minimatch':
        type: 'object'
        description: '''
        Pass any additionnal config to Minimatch.
        '''
    required: ['target']

Handler

handler = ({config, tools: {path}}) ->
  config.minimatch ?= {}
  config.minimatch.dot ?= config.dot if config.dot?
  config.target = path.normalize config.target
  minimatch = new Minimatch config.target, config.minimatch
  {stdout, exit_code} = await @execute
    command: [
      'find'
      ...(getprefix s for s in minimatch.set)
      # trailing slash
      '-type d -exec sh -c \'printf "%s/\\n" "$0"\' {} \\; -or -print'
    ].join ' '
    $relax: true
    trim: true
  # Find returns exit code 1 when no match is found, treat it as an empty output
  stdout ?= ''
  # Filter each entries
  files = utils.string.lines(stdout).filter (file) ->
    minimatch.match file
  # Remove the trailing slash introduced by the find command
  unless config.trailing
    files = files.map (file) ->
      if file.slice(-1) is '/'
      then file.slice 0, -1
      else file
  files: files

Exports

module.exports =
  handler: handler
  metadata:
    argument_to_config: 'target'
    definitions: definitions
    shy: true

Dependencies

{Minimatch} = require 'minimatch'
utils = require '../../utils'

Utility

getprefix = (pattern) ->
  prefix = null
  n = 0
  while typeof pattern[n] is "string" then n++
  # now n is the index of the first one that is *not* a string.
  # see if there's anything else
  switch n
    # if not, then this is rather simple
    when pattern.length
      prefix = pattern.join '/'
      return prefix
    when 0
      # pattern *starts* with some non-trivial item.
      # going to readdir(cwd), but not include the prefix in matches.
      return null
    else
      # pattern has some string bits in the front.
      # whatever it starts with, whether that's "absolute" like /foo/bar,
      # or "relative" like "../baz"
      prefix = pattern.slice 0, n
      prefix = prefix.join '/'
      return prefix
Edit on GitHub
Navigate
About

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