-
Notifications
You must be signed in to change notification settings - Fork 3.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
chore: refactor server/lib/config.ts to pkg/config #22530
Conversation
Thanks for taking the time to open a PR!
|
a75a5e9
to
d5e2ebe
Compare
Test summaryRun details
View run in Cypress Dashboard ➡️ Flakiness
This comment has been generated by cypress-bot as a result of this project's GitHub integration settings. You can manage this integration in this project's settings in the Cypress Dashboard |
packages/config/src/project/utils.ts
Outdated
import _ from 'lodash' | ||
import path from 'path' | ||
|
||
import { getProcessEnvVars, CYPRESS_SPECIAL_ENV_VARS } from '@packages/server/lib/util/config' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any way we can drop pulling in @packages/server
or @packages/data-context
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm trying. I guess we can remove @package/server
from here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So excited to see these changes!
a3c694f
to
1d14c2b
Compare
packages/config/src/project/index.ts
Outdated
import deepDiff from 'return-deep-diff' | ||
|
||
import errors, { ConfigValidationFailureInfo, CypressError } from '@packages/errors' | ||
import { getCtx } from '@packages/data-context/src/globalContext' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This dependency cannot be removed until we move getFilesByGlob
to somewhere else.
Or call it inside data-context
and pass the value to this function.
Maybe, this can be solved in the future PRs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I researched it after writing this comment. It seems that it will work if we add supportFiles
member to setupFullConfigWithDefaults
.
I'll do this after this PR is merged. This PR is big and I tried not to change code much.
|
||
const debug = Debug('cypress:config:project') | ||
|
||
// TODO: any -> SetupFullConfigOptions in data-context/src/data/ProjectConfigManager.ts |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using data-context/src/data/ProjectConfigManager.ts
type definitions breaks the type. It seems that some types are missing. I postponed it for now because I need to read a lot of code to be sure that the new types are correct.
@@ -0,0 +1,49 @@ | |||
import type { DataContext } from './DataContext' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I created this file to bypass circular dependency.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where were you seeing this at?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pkg/config
uses getCtx
and pkg/data-context
uses pkg/config
functions. It causes circular dependency and breaks Cypress.
This file could be removed and merged back to index.ts
after fixing the problems I mentioned in this comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@sainthkh I think this can be removed now with your latest changes!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately, it can't. As I wrote in the comment below, we need getCtx
from pkg/data-context
dependency in tests. Check this code
I thought about injection dummy functions to the test. But its return value is used to throw errors. So, it can cause false positive when getFilesByGlob
is changed.
I think the only way to roll back this code is to:
- solve that
obj.supportFile
issue - pass
supportFile
frompkg/data-context
- remove
pkg/data-context
from tests inpkg/config
- remove this
globalContext
file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
able to delete now with the latest commits?
const parseClone = (urlObject: any) => { | ||
return url.parse(_.clone(urlObject)) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is really weird code. url.parse
expects string
as its first arg, but our code is written for the case that it's not a string
but an object.
I'll check this behavior and fix this in the part 2 of this PR.
import type { ConfigValidationFailureInfo, CypressError } from '@packages/errors' | ||
export const setupFullConfigWithDefaults = configUtils.setupFullConfigWithDefaults | ||
|
||
import { getCtx } from './makeDataContext' | ||
export const updateWithPluginValues = configUtils.updateWithPluginValues |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These are here because they're used in some tests in pkg/server
expect(errors.throwErr).not.to.be.called | ||
}) | ||
}) | ||
|
||
context('.get', () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The tests under .get
more suit pkg/data-context/test/unit/data/ProjectLifecycleManager
.
If you agree, I'll move them in the next PR.
@@ -3,7 +3,7 @@ | |||
/* Basic Options */ | |||
"target": "ES2018", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. */ | |||
"module": "commonjs", /* Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es2015'. */ | |||
"lib": ["es2018", "ES2020.Promise"], /* Specify library files to be included in the compilation: */ | |||
"lib": ["es2018", "ES2020.Promise", "ES2021.String"], /* Specify library files to be included in the compilation: */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
String.ReplaceAll
is used in several pacakges. So, I added it here to avoid surprise.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Glad to see the slow march from CJS+JS to TS, and gradual improvements to type safety. This generally looks like a pretty straight forward refactor - I don't see any obvious problems, just made a few recommendations around (potential) type safety improvements.
packages/config/src/project/index.ts
Outdated
config.projectName = projectName | ||
|
||
// @ts-ignore | ||
return mergeDefaults(config, options, cliConfig) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How come we need to ts-ignore here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alright, I figured it was something like this.
packages/config/src/project/index.ts
Outdated
import deepDiff from 'return-deep-diff' | ||
|
||
import errors, { ConfigValidationFailureInfo, CypressError } from '@packages/errors' | ||
import { getCtx } from '@packages/data-context/src/globalContext' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We are calling this from the data-context package. Can we drop this dependency and just pass in the configFile as an additional parameter to updateWithPluginValues
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
getCtx
is called in 2 functions:
updateWithPluginValues
ofproject/index.ts
setSupportFileAndFolder
ofproject/utils.ts
The solution for the first case is simple. We can simply add configFile
member inside buildBaseFullConfig
of ProjectConfigManager
.
But the problem is the second one.
To call the ctx.file.getFilesByGlob
, we need obj.supportFile
. But the problem is that global supportFile
option is legacy. It is splitted and moved under e2e
or component
from 10.
It means that current setSupportFileAndFolder
can be buggy or completely removable in the current version. I'm not 100% sure about this. I need to think about a test case that shows this problem. Maybe #22776 is the related case.
The goal of this PR is copying and moving server/lib/config.ts
to pkg/config
and adding types as much as possible. I focused on this because this PR can be too big and it makes reviewers hard to review this PR.
I think checking/fixing bugs and adding more specific types should be done in the future PRs. What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To call the ctx.file.getFilesByGlob, we need obj.supportFile. But the problem is that global supportFile option is legacy. It is splitted and moved under e2e or component from 10.
This log is correct, at this point we are testing the flattened configuration for the given testing type, so obj.supportFile
is valid.
I think making a few small changes seems needed to move this code over and would be worth making a small change to remove this circular dependency. Simply passing int he attribute needed is probably the simplest approach until / if we ever want to revisit how this is composed.
// data-context/ProjectConfigManger.ts
setupFullConfigWithDefaults({
projectRoot,
projectName,
configFile,
config,
envFile,
options,
cliConfig
},
ctx.file.getFilesByGlob)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I never thought about passing the function as an argument to remove the dependency. Thanks for the idea.
Unfortunately, this idea even cannot completely remove pkg/data-context
from config
. It can be removed from src
. But it had to be added to test
to run tests.
However, I think this change is much better.
@@ -0,0 +1,49 @@ | |||
import type { DataContext } from './DataContext' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where were you seeing this at?
They're only used inside config.ts
Conflicts: packages/server/test/unit/config_spec.js
Hi @sainthkh ! Can you update |
@@ -0,0 +1,1182 @@ | |||
import '@packages/server/test/spec_helper' | |||
import { getCtx } from '@packages/data-context/src/globalContext' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need globalContext
here. Otherwise, we need to import the entire pkg/data-context
.
const supportFilesByGlob = await getFilesByGlob(obj.projectRoot, obj.supportFile) | ||
|
||
if (supportFilesByGlob.length > 1) { | ||
return errors.throwErr('MULTIPLE_SUPPORT_FILES_FOUND', obj.supportFile, supportFilesByGlob) | ||
} | ||
|
||
if (supportFilesByGlob.length === 0) { | ||
if (obj.resolved.supportFile.from === 'default') { | ||
return errors.throwErr('DEFAULT_SUPPORT_FILE_NOT_FOUND', relativeToProjectRoot(obj.projectRoot, obj.supportFile)) | ||
} | ||
|
||
return errors.throwErr('SUPPORT_FILE_NOT_FOUND', relativeToProjectRoot(obj.projectRoot, obj.supportFile)) | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Return value is used to throw errors.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@sainthkh looks like we have a failing server performance test:
@rachelruderman For some reason, context was cleared before |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great, thank you for your contribution @sainthkh !
User facing changelog
N/A. Internal refactoring.
Additional details
pkg/server
makes us createconfigApi
insideDataContext
and not be able to call them directly.Any implementation details to explain?
At first, I thought this issue would be a simple copy and paste of a few lines of code. But I learned that it's a lot bigger than I thought.
To refactor
server/lib/config.ts
, I had to refactor these files, too:Because they're used mostly inside
config.ts
and related with manipulating config values.As we're migrating our code from
commonjs
toesm
, the code structure also had to be fixed.For this PR, I created 3 files to place the code.
config
package. I named them project because the type definitions were inProjectConfigManager
,ProjectLifecycleManager
.index.ts
. They areexport
ed to be unit-tested.hideKeys
andcoerce
are used outsidepkg/config
. They live here.As for
origin.ts
, I moved it topkg/network/lib/uri.ts
because it more suits the place.I renamed some functions to make it clear.
keys
->hideKeys
isDefault
->isResolvedConfigPropDefault
I added types for the functions. I added some
any
because I'm not sure about them now.Steps to test
No new features; ensure existing tests are passing.
How has the user experience changed?
N/A. It's a code cleanup.
PR Tasks
cypress-documentation
?type definitions
?