@@ -4,6 +4,9 @@ import { EOL } from 'os'
44import path from 'path'
55import process from 'process'
66
7+ import { Project } from '@netlify/build-info'
8+ // eslint-disable-next-line import/extensions, n/no-missing-import
9+ import { NodeFS } from '@netlify/build-info/node'
710import { getFramework , listFrameworks } from '@netlify/framework-info'
811import fuzzy from 'fuzzy'
912import getPort from 'get-port'
@@ -12,6 +15,7 @@ import isPlainObject from 'is-plain-obj'
1215import { NETLIFYDEVWARN , chalk , log } from './command-helpers.mjs'
1316import { acquirePort } from './dev.mjs'
1417import { getInternalFunctionsDir } from './functions/functions.mjs'
18+ import { reportError } from './telemetry/report-error.mjs'
1519
1620const formatProperty = ( str ) => chalk . magenta ( `'${ str } '` )
1721const formatValue = ( str ) => chalk . green ( `'${ str } '` )
@@ -112,10 +116,10 @@ const getStaticServerPort = async ({ devConfig }) => {
112116/**
113117 *
114118 * @param {object } param0
115- * @param {import('../commands/dev/types').DevConfig } param0.devConfig
119+ * @param {import('../commands/dev/types.js ').DevConfig } param0.devConfig
116120 * @param {import('commander').OptionValues } param0.options
117121 * @param {string } param0.projectDir
118- * @returns {Promise<import('./types').BaseServerSettings> }
122+ * @returns {Promise<import('./types.js ').BaseServerSettings> }
119123 */
120124const handleStaticServer = async ( { devConfig, options, projectDir } ) => {
121125 validateNumberProperty ( { devConfig, property : 'staticServerPort' } )
@@ -152,8 +156,8 @@ const handleStaticServer = async ({ devConfig, options, projectDir }) => {
152156
153157/**
154158 * Retrieves the settings from a framework
155- * @param {import('./types').FrameworkInfo } framework
156- * @returns {import('./types').BaseServerSettings }
159+ * @param {import('./types.js ').FrameworkInfo } framework
160+ * @returns {import('./types.js ').BaseServerSettings }
157161 */
158162const getSettingsFromFramework = ( framework ) => {
159163 const {
@@ -182,6 +186,71 @@ const getSettingsFromFramework = (framework) => {
182186
183187const hasDevCommand = ( framework ) => Array . isArray ( framework . dev . commands ) && framework . dev . commands . length !== 0
184188
189+ /**
190+ * The new build setting detection with build systems and frameworks combined
191+ * @param {string } projectDir
192+ */
193+ const detectSettings = async ( projectDir ) => {
194+ const fs = new NodeFS ( )
195+ const project = new Project ( fs , projectDir )
196+
197+ return await project . getBuildSettings ( )
198+ }
199+
200+ /**
201+ *
202+ * @param {import('./types.js').BaseServerSettings | undefined } frameworkSettings
203+ * @param {import('@netlify/build-info').Settings[] } newSettings
204+ * @param {Record<string, Record<string, any>> } [metadata]
205+ */
206+ const detectChangesInNewSettings = ( frameworkSettings , newSettings , metadata ) => {
207+ /** @type {string[] } */
208+ const message = [ '' ]
209+ const [ setting ] = newSettings
210+
211+ if ( frameworkSettings ?. framework !== setting ?. framework ) {
212+ message . push (
213+ `- Framework does not match:` ,
214+ ` [old]: ${ frameworkSettings ?. framework } ` ,
215+ ` [new]: ${ setting ?. framework } ` ,
216+ '' ,
217+ )
218+ }
219+
220+ if ( frameworkSettings ?. command !== setting ?. devCommand ) {
221+ message . push (
222+ `- command does not match:` ,
223+ ` [old]: ${ frameworkSettings ?. command } ` ,
224+ ` [new]: ${ setting ?. devCommand } ` ,
225+ '' ,
226+ )
227+ }
228+
229+ if ( frameworkSettings ?. dist !== setting ?. dist ) {
230+ message . push ( `- dist does not match:` , ` [old]: ${ frameworkSettings ?. dist } ` , ` [new]: ${ setting ?. dist } ` , '' )
231+ }
232+
233+ if ( frameworkSettings ?. frameworkPort !== setting ?. frameworkPort ) {
234+ message . push (
235+ `- frameworkPort does not match:` ,
236+ ` [old]: ${ frameworkSettings ?. frameworkPort } ` ,
237+ ` [new]: ${ setting ?. frameworkPort } ` ,
238+ '' ,
239+ )
240+ }
241+
242+ if ( message . length !== 0 ) {
243+ reportError (
244+ {
245+ name : 'NewSettingsDetectionMismatch' ,
246+ errorMessage : 'New Settings detection does not match old one' ,
247+ message : message . join ( '\n' ) ,
248+ } ,
249+ { severity : 'info' , metadata } ,
250+ )
251+ }
252+ }
253+
185254const detectFrameworkSettings = async ( { projectDir } ) => {
186255 const projectFrameworks = await listFrameworks ( { projectDir } )
187256 const frameworks = projectFrameworks . filter ( ( framework ) => hasDevCommand ( framework ) )
@@ -224,7 +293,7 @@ const hasCommandAndTargetPort = ({ devConfig }) => devConfig.command && devConfi
224293/**
225294 * Creates settings for the custom framework
226295 * @param {* } param0
227- * @returns {import('./types').BaseServerSettings }
296+ * @returns {import('./types.js ').BaseServerSettings }
228297 */
229298const handleCustomFramework = ( { devConfig } ) => {
230299 if ( ! hasCommandAndTargetPort ( { devConfig } ) ) {
@@ -271,7 +340,7 @@ const mergeSettings = async ({ devConfig, frameworkSettings = {} }) => {
271340/**
272341 * Handles a forced framework and retrieves the settings for it
273342 * @param {* } param0
274- * @returns {Promise<import('./types').BaseServerSettings> }
343+ * @returns {Promise<import('./types.js ').BaseServerSettings> }
275344 */
276345const handleForcedFramework = async ( { devConfig, projectDir } ) => {
277346 // this throws if `devConfig.framework` is not a supported framework
@@ -281,15 +350,16 @@ const handleForcedFramework = async ({ devConfig, projectDir }) => {
281350
282351/**
283352 * Get the server settings based on the flags and the devConfig
284- * @param {import('../commands/dev/types').DevConfig } devConfig
353+ * @param {import('../commands/dev/types.js ').DevConfig } devConfig
285354 * @param {import('commander').OptionValues } options
286355 * @param {string } projectDir
287- * @returns {Promise<import('./types').ServerSettings> }
356+ * @param {Record<string, Record<string, any>> } [metadata]
357+ * @returns {Promise<import('./types.js').ServerSettings> }
288358 */
289- const detectServerSettings = async ( devConfig , options , projectDir ) => {
359+ const detectServerSettings = async ( devConfig , options , projectDir , metadata ) => {
290360 validateStringProperty ( { devConfig, property : 'framework' } )
291361
292- /** @type {Partial<import('./types').BaseServerSettings> } */
362+ /** @type {Partial<import('./types.js ').BaseServerSettings> } */
293363 let settings = { }
294364
295365 if ( options . dir || devConfig . framework === '#static' ) {
@@ -300,6 +370,19 @@ const detectServerSettings = async (devConfig, options, projectDir) => {
300370
301371 const runDetection = ! hasCommandAndTargetPort ( { devConfig } )
302372 const frameworkSettings = runDetection ? await detectFrameworkSettings ( { projectDir } ) : undefined
373+ const newSettings = runDetection ? await detectSettings ( projectDir ) : undefined
374+
375+ // just report differences in the settings
376+ detectChangesInNewSettings ( frameworkSettings , newSettings || [ ] , {
377+ ...metadata ,
378+ settings : {
379+ projectDir,
380+ devConfig,
381+ options,
382+ old : frameworkSettings ,
383+ settings : newSettings ,
384+ } ,
385+ } )
303386
304387 if ( frameworkSettings === undefined && runDetection ) {
305388 log ( `${ NETLIFYDEVWARN } No app server detected. Using simple static server` )
@@ -368,7 +451,7 @@ const formatSettingsArrForInquirer = function (frameworks) {
368451 * Returns a copy of the provided config with any plugins provided by the
369452 * server settings
370453 * @param {* } config
371- * @param {Partial<import('./types').ServerSettings> } settings
454+ * @param {Partial<import('./types.js ').ServerSettings> } settings
372455 * @returns {* } Modified config
373456 */
374457export const getConfigWithPlugins = ( config , settings ) => {
0 commit comments