Skip to content

Commit

Permalink
fix: enable and fix fp/no-loops (#2852)
Browse files Browse the repository at this point in the history
  • Loading branch information
tinfoil-knight authored Jul 12, 2021
1 parent 9ef19aa commit aa6c8fb
Show file tree
Hide file tree
Showing 18 changed files with 42 additions and 115 deletions.
4 changes: 2 additions & 2 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ module.exports = {
'fp/no-delete': 0,
'fp/no-get-set': 0,
'fp/no-let': 0,
'fp/no-loops': 0,
'fp/no-loops': 'error',
'fp/no-mutating-assign': 0,
'fp/no-mutating-methods': 0,
'fp/no-mutation': 0,
Expand All @@ -28,7 +28,6 @@ module.exports = {
'node/no-sync': 0,
'unicorn/prefer-spread': 0,
'unicorn/consistent-destructuring': 0,

// TODO: harmonize with filename snake_case in other Netlify Dev projects
'unicorn/filename-case': [2, { case: 'kebabCase' }],
},
Expand All @@ -55,6 +54,7 @@ module.exports = {
'node/no-unsupported-features/es-syntax': 0,
'unicorn/consistent-destructuring': 0,
'max-lines': 0,
'array-callback-return': ['error', { checkForEach: true }],
},
},
// Example functions
Expand Down
4 changes: 1 addition & 3 deletions src/commands/env/import.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,7 @@ class EnvImportCommand extends Command {
const table = new AsciiTable(`Imported environment variables`)

table.setHeading('Key', 'Value')
for (const [key, value] of Object.entries(importedEnv)) {
table.addRow(key, value)
}
table.addRowMatrix(Object.entries(importedEnv))
this.log(table.toString())
}
}
Expand Down
4 changes: 1 addition & 3 deletions src/commands/env/list.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,7 @@ class EnvListCommand extends Command {
const table = new AsciiTable(`Environment variables`)

table.setHeading('Key', 'Value')
for (const [key, value] of Object.entries(environment)) {
table.addRow(key, value)
}
table.addRowMatrix(Object.entries(environment))
this.log(table.toString())
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/commands/init.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const isEmpty = require('lodash/isEmpty')

const Command = require('../utils/command')
const { getRepoData } = require('../utils/get-repo-data')
const { ensureNetlifyIgnore } = require('../utils/gitignore')
const ensureNetlifyIgnore = require('../utils/gitignore')
const { configureRepo } = require('../utils/init/config')
const { track } = require('../utils/telemetry')

Expand Down
2 changes: 1 addition & 1 deletion src/commands/link.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const chalk = require('chalk')

const { listSites } = require('../lib/api')
const Command = require('../utils/command')
const { ensureNetlifyIgnore } = require('../utils/gitignore')
const ensureNetlifyIgnore = require('../utils/gitignore')
const linkPrompt = require('../utils/link/link-by-prompt')
const { track } = require('../utils/telemetry')

Expand Down
18 changes: 4 additions & 14 deletions src/detectors/utils/jsdetect.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,22 +33,12 @@ const getYarnOrNPMCommand = function () {

const hasRequiredDeps = function (requiredDepArray) {
const { dependencies, devDependencies } = getPkgJSON()
for (const depName of requiredDepArray) {
const hasItInDeps = dependencies && dependencies[depName]
const hasItInDevDeps = devDependencies && devDependencies[depName]
if (!hasItInDeps && !hasItInDevDeps) {
return false
}
}
return true
const allDependencies = { ...dependencies, ...devDependencies }
return requiredDepArray.every((depName) => allDependencies[depName])
}

const hasRequiredFiles = function (filenameArr) {
for (const filename of filenameArr) {
if (!existsSync(filename)) {
return false
}
}
return true
return filenameArr.every((filename) => existsSync(filename))
}

// preferredScriptsArr is in decreasing order of preference
Expand Down
1 change: 1 addition & 0 deletions src/lib/functions/runtimes/js/builders/netlify-lambda.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const detectNetlifyLambda = async function ({ packageJson } = {}) {

const matchingScripts = Object.entries(scripts).filter(([, script]) => script.match(/netlify-lambda\s+build/))

// eslint-disable-next-line fp/no-loops
for (const [key, script] of matchingScripts) {
// E.g. ["netlify-lambda", "build", "functions/folder"]
const match = minimist(script.split(' '))
Expand Down
20 changes: 13 additions & 7 deletions src/lib/functions/synchronous.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,16 @@ const { Buffer } = require('buffer')

const { NETLIFYDEVERR } = require('../../utils/logo')

const addHeaders = (headers, response) => {
if (!headers) {
return
}

Object.entries(headers).forEach(([key, value]) => {
response.setHeader(key, value)
})
}

const handleSynchronousFunction = function (err, result, response) {
if (err) {
return handleErr(err, response)
Expand All @@ -14,13 +24,9 @@ const handleSynchronousFunction = function (err, result, response) {
}

response.statusCode = result.statusCode
for (const key in result.headers) {
response.setHeader(key, result.headers[key])
}
for (const key in result.multiValueHeaders) {
const items = result.multiValueHeaders[key]
response.setHeader(key, items)
}
addHeaders(result.headers, response)
addHeaders(result.multiValueHeaders, response)

if (result.body) {
response.write(result.isBase64Encoded ? Buffer.from(result.body, 'base64') : result.body)
}
Expand Down
1 change: 1 addition & 0 deletions src/utils/detect-functions-builder.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const detectFunctionsBuilder = async function (parameters) {
// eslint-disable-next-line node/global-require, import/no-dynamic-require
.map((det) => require(path.join(buildersPath, det)))

// eslint-disable-next-line fp/no-loops
for (const detector of detectors) {
// eslint-disable-next-line no-await-in-loop
const settings = await detector(parameters)
Expand Down
7 changes: 2 additions & 5 deletions src/utils/detect-server.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ const serverSettings = async (devConfig, flags, projectDir, log) => {
}
})
} else if (devConfig.framework === '#auto' && !(devConfig.command && devConfig.targetPort)) {
const settingsArr = []
const detectors = detectorsFiles.map((det) => {
try {
return loadDetector(det)
Expand All @@ -67,10 +66,8 @@ const serverSettings = async (devConfig, flags, projectDir, log) => {
return null
}
})
for (const detector of detectors) {
const detectorResult = detector(projectDir)
if (detectorResult) settingsArr.push(detectorResult)
}

const settingsArr = detectors.map((detector) => detector(projectDir)).filter((el) => el)
if (settingsArr.length === 1) {
const [firstSettings] = settingsArr
settings = firstSettings
Expand Down
13 changes: 7 additions & 6 deletions src/utils/dev.js
Original file line number Diff line number Diff line change
Expand Up @@ -135,24 +135,25 @@ const injectEnvVariables = async ({ env, log, site, warn }) => {
const environment = new Map(Object.entries(env))
const dotEnvFiles = await loadDotEnvFiles({ projectDir: site.root, warn })

for (const { file, env: fileEnv } of dotEnvFiles) {
for (const key in fileEnv) {
dotEnvFiles.forEach(({ file, env: fileEnv }) => {
Object.keys(fileEnv).forEach((key) => {
const newSourceName = `${file} file`
const sources = environment.has(key) ? [newSourceName, ...environment.get(key).sources] : [newSourceName]

environment.set(key, {
sources,
value: fileEnv[key],
})
}
}
})
})

// eslint-disable-next-line fp/no-loops
for (const [key, variable] of environment) {
const existsInProcess = process.env[key] !== undefined
const [usedSource, ...overriddenSources] = existsInProcess ? ['process', ...variable.sources] : variable.sources
const usedSourceName = getEnvSourceName(usedSource)

for (const source of overriddenSources) {
overriddenSources.forEach((source) => {
const sourceName = getEnvSourceName(source)

log(
Expand All @@ -162,7 +163,7 @@ const injectEnvVariables = async ({ env, log, site, warn }) => {
)} (defined in ${usedSourceName})`,
),
)
}
})

if (!existsInProcess) {
// Omitting `general` env vars to reduce noise in the logs.
Expand Down
1 change: 1 addition & 0 deletions src/utils/get-global-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ const getGlobalConfigOnce = async function () {

const getGlobalConfig = async function () {
const retries = 3
// eslint-disable-next-line fp/no-loops
for (let retry = 1; retry <= retries; retry++) {
try {
// eslint-disable-next-line no-await-in-loop
Expand Down
1 change: 0 additions & 1 deletion src/utils/get-global-config.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@ test.serial("should create config in netlify's config dir if none exists and sto
// Remove config dirs
await rmdirRecursiveAsync(getPathInHome([]))
await rmdirRecursiveAsync(getLegacyPathInHome([]))

const globalConfig = await getGlobalConfig()
globalConfig.set('newProp', 'newValue')
const configFile = JSON.parse(await readFileAsync(configPath))
Expand Down
70 changes: 1 addition & 69 deletions src/utils/gitignore.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,69 +10,6 @@ const hasGitIgnore = async function (dir) {
return hasIgnore
}

const parser = function (input, fn = (line) => line) {
const lines = input.toString().split(/\r?\n/)
let section = { name: 'default', patterns: [] }
const state = { patterns: [], sections: [section] }

for (const line of lines) {
if (line.charAt(0) === '#') {
section = { name: line.slice(1).trim(), patterns: [] }
state.sections.push(section)
continue
}

if (line.trim() !== '') {
const pattern = fn(line, section, state)
section.patterns.push(pattern)
state.patterns.push(pattern)
}
}
return state
}

const stringify = function (state) {
return parseIgnore.stringify(state.sections, (section) => {
if (section.patterns.length === 0) {
return ''
}

return `# ${section.name}\n${section.patterns.join('\n')}\n\n`
})
}

const parse = function (input, fn) {
const state = parser(input, fn)

state.concat = (stateInput) => {
const newState = parser(stateInput, fn)

for (const s2 in newState.sections) {
const sec2 = newState.sections[s2]

let sectionExists = false
for (const s1 in state.sections) {
const sec1 = state.sections[s1]

// Join sections under common name
if (sec1.name === sec2.name) {
sectionExists = true
sec1.patterns = [...new Set(sec1.patterns.concat(sec2.patterns))]
}
}

// Add new section
if (!sectionExists) {
state.sections.push(sec2)
}
}

return state
}

return state
}

const ensureNetlifyIgnore = async function (dir) {
const gitIgnorePath = path.join(dir, '.gitignore')
const ignoreContent = '# Local Netlify folder\n.netlify'
Expand All @@ -98,9 +35,4 @@ const ensureNetlifyIgnore = async function (dir) {
}
}

module.exports = {
parse,
stringify,
format: parseIgnore.format,
ensureNetlifyIgnore,
}
module.exports = ensureNetlifyIgnore
1 change: 1 addition & 0 deletions src/utils/headers.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ const parseHeadersFile = function (filePath) {

let path
let rules = {}
// eslint-disable-next-line fp/no-loops
for (const { line, index } of lines) {
if (line.startsWith(TOKEN_PATH)) {
path = line
Expand Down
6 changes: 3 additions & 3 deletions src/utils/state-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,9 @@ class StateConfig {
const config = this.all

if (args.length === 1) {
for (const keyPart of Object.keys(key)) {
dotProp.set(config, keyPart, key[keyPart])
}
Object.entries(key).forEach(([keyPart, value]) => {
dotProp.set(config, keyPart, value)
})
} else {
dotProp.set(config, key, val)
}
Expand Down
1 change: 1 addition & 0 deletions tests/utils/dev-server.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ const startServer = async ({ cwd, offline = true, env = {}, args = [] }) => {

const startDevServer = async (options, expectFailure) => {
const maxAttempts = 5
// eslint-disable-next-line fp/no-loops
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
try {
// eslint-disable-next-line no-await-in-loop
Expand Down
1 change: 1 addition & 0 deletions tests/utils/site-builder.js
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ const createSiteBuilder = ({ siteName }) => {
return builder
},
buildAsync: async () => {
// eslint-disable-next-line fp/no-loops
for (const task of tasks) {
// eslint-disable-next-line no-await-in-loop
await task()
Expand Down

1 comment on commit aa6c8fb

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📊 Benchmark results

Package size: 330 MB

Please sign in to comment.