314873b3e007e8f32257bc2b8e31557729b027839030038bb6667629eeb19b6888ae77bef7b3997bdc0a1da9e378228274a2506791a3a8df1c95e6e43f8bba 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. 'use strict'
  2. const debug = require('debug')('lint-staged:chunkFiles')
  3. const normalize = require('normalize-path')
  4. const path = require('path')
  5. /**
  6. * Chunk array into sub-arrays
  7. * @param {Array} arr
  8. * @param {Number} chunkCount
  9. * @retuns {Array<Array>}
  10. */
  11. function chunkArray(arr, chunkCount) {
  12. if (chunkCount === 1) return [arr]
  13. const chunked = []
  14. let position = 0
  15. for (let i = 0; i < chunkCount; i++) {
  16. const chunkLength = Math.ceil((arr.length - position) / (chunkCount - i))
  17. chunked.push([])
  18. chunked[i] = arr.slice(position, chunkLength + position)
  19. position += chunkLength
  20. }
  21. return chunked
  22. }
  23. /**
  24. * Chunk files into sub-arrays based on the length of the resulting argument string
  25. * @param {Object} opts
  26. * @param {Array<String>} opts.files
  27. * @param {String} [opts.baseDir] The optional base directory to resolve relative paths.
  28. * @param {number} [opts.maxArgLength] the maximum argument string length
  29. * @param {Boolean} [opts.relative] whether files are relative to `gitDir` or should be resolved as absolute
  30. * @returns {Array<Array<String>>}
  31. */
  32. module.exports = function chunkFiles({ files, baseDir, maxArgLength = null, relative = false }) {
  33. const normalizedFiles = files.map((file) =>
  34. normalize(relative || !baseDir ? file : path.resolve(baseDir, file))
  35. )
  36. if (!maxArgLength) {
  37. debug('Skip chunking files because of undefined maxArgLength')
  38. return [normalizedFiles] // wrap in an array to return a single chunk
  39. }
  40. const fileListLength = normalizedFiles.join(' ').length
  41. debug(
  42. `Resolved an argument string length of ${fileListLength} characters from ${normalizedFiles.length} files`
  43. )
  44. const chunkCount = Math.min(Math.ceil(fileListLength / maxArgLength), normalizedFiles.length)
  45. debug(`Creating ${chunkCount} chunks for maxArgLength of ${maxArgLength}`)
  46. return chunkArray(normalizedFiles, chunkCount)
  47. }