Skip to content

feat(tools): implement dynamic prompt behaviour to migration generator#19151

Merged
Hotell merged 6 commits intomicrosoft:masterfrom
Hotell:hotell/build-system/nx-migration-prompts
Aug 4, 2021
Merged

feat(tools): implement dynamic prompt behaviour to migration generator#19151
Hotell merged 6 commits intomicrosoft:masterfrom
Hotell:hotell/build-system/nx-migration-prompts

Conversation

@Hotell
Copy link
Contributor

@Hotell Hotell commented Jul 27, 2021

Pull request checklist

Description of changes

When using build in nx tao CLI functionality to trigger prompts based on json.schema x-prompt, it is not possible to invoke prompts dynamically based on our custom logic.

As our generator contains only mutual exclusive option flags and because we wanna provide best possible DX we needed to opt out from DECLARATIVE x-prompt configuration and instead IMPERATIVELY invoke prompts.

Notes:

  • enquired is used by nx thus using the same prompt library is an obvious choice

BEFORE

tools-dynamic-prompts-before.mov

AFTER

tools-dynamic-prompts-after.mov

Additional changes:

  • FHL week demo how to use dynamic prompts within nx generators when needed
  • more robust test coverage

Focus areas to test

(optional)


Co-authored-by: @andrefcdias
Co-authored-by: @tringakrasniqi

@codesandbox-ci
Copy link

codesandbox-ci bot commented Jul 27, 2021

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

Latest deployment of this branch, based on commit 5ad7624:

Sandbox Source
Fluent UI React Starter Configuration

@size-auditor
Copy link

size-auditor bot commented Jul 27, 2021

Asset size changes

Size Auditor did not detect a change in bundle size for any component!

Baseline commit: 6ac944b99ccd5e916c5d767eff4cc3caf979220a (build)

@fabricteam
Copy link
Collaborator

fabricteam commented Jul 27, 2021

📊 Bundle size report

Unchanged fixtures
Package & Exports Size (minified/GZIP)
react-accordion
Accordion (including children components)
78.506 kB
23.21 kB
react-avatar
Avatar
54.242 kB
14.662 kB
react-badge
Badge
24.343 kB
7.165 kB
react-badge
CounterBadge
27.156 kB
7.851 kB
react-badge
PresenseBadge
237 B
177 B
react-button
Button
24.934 kB
8.001 kB
react-button
CompoundButton
30.226 kB
8.878 kB
react-button
MenuButton
26.521 kB
8.509 kB
react-button
ToggleButton
34.531 kB
8.637 kB
react-components
react-components: Accordion, Button, FluentProvider, Image, Menu, Popover
179.799 kB
50.935 kB
react-components
react-components: FluentProvider & webLightTheme
36.237 kB
11.596 kB
react-divider
Divider
15.889 kB
5.747 kB
react-image
Image
10.642 kB
4.264 kB
react-label
Label
9.397 kB
3.839 kB
react-link
Link
14.715 kB
6.012 kB
react-make-styles
makeStaticStyles (runtime)
7.59 kB
3.321 kB
react-make-styles
makeStyles + mergeClasses (runtime)
22.135 kB
8.356 kB
react-make-styles
makeStyles + mergeClasses (build time)
2.557 kB
1.202 kB
react-menu
Menu (including children components)
114.61 kB
34.554 kB
react-menu
Menu (including selectable components)
116.71 kB
34.824 kB
react-popover
Popover
124.181 kB
36.121 kB
react-portal
Portal
7.78 kB
2.672 kB
react-positioning
usePopper
23.157 kB
7.942 kB
react-provider
FluentProvider
16.235 kB
5.972 kB
react-theme
Teams: all themes
32.941 kB
6.674 kB
react-theme
Teams: Light theme
20.247 kB
5.662 kB
react-tooltip
Tooltip
45.281 kB
15.45 kB
react-utilities
SSRProvider
213 B
170 B
🤖 This report was generated against 6ac944b99ccd5e916c5d767eff4cc3caf979220a

@fabricteam
Copy link
Collaborator

fabricteam commented Jul 27, 2021

Perf Analysis (@fluentui/react)

No significant results to display.

All results

Scenario Render type Master Ticks PR Ticks Iterations Status
Avatar mount 789 798 5000
BaseButton mount 884 891 5000
Breadcrumb mount 2605 2643 1000
ButtonNext mount 426 427 5000
Checkbox mount 1525 1506 5000
CheckboxBase mount 1272 1315 5000
ChoiceGroup mount 4750 4780 5000
ComboBox mount 1020 972 1000
CommandBar mount 10216 10136 1000
ContextualMenu mount 6185 6189 1000
DefaultButton mount 1110 1124 5000
DetailsRow mount 3656 3756 5000
DetailsRowFast mount 3731 3735 5000
DetailsRowNoStyles mount 3528 3471 5000
Dialog mount 2195 2123 1000
DocumentCardTitle mount 142 143 1000
Dropdown mount 3205 3238 5000
FluentProviderNext mount 7525 7454 5000
FocusTrapZone mount 1796 1781 5000
FocusZone mount 1806 1775 5000
IconButton mount 1706 1711 5000
Label mount 337 324 5000
Layer mount 1772 1766 5000
Link mount 468 456 5000
MakeStyles mount 1851 1815 50000
MenuButton mount 1442 1456 5000
MessageBar mount 1975 1993 5000
Nav mount 3228 3227 1000
OverflowSet mount 1031 1034 5000
Panel mount 2086 2160 1000
Persona mount 816 801 1000
Pivot mount 1407 1421 1000
PrimaryButton mount 1257 1260 5000
Rating mount 7594 7630 5000
SearchBox mount 1317 1306 5000
Shimmer mount 2522 2536 5000
Slider mount 1963 1942 5000
SpinButton mount 4999 5192 5000
Spinner mount 425 437 5000
SplitButton mount 3212 3119 5000
Stack mount 492 497 5000
StackWithIntrinsicChildren mount 1508 1514 5000
StackWithTextChildren mount 4502 4449 5000
SwatchColorPicker mount 10212 10188 5000
Tabs mount 1412 1388 1000
TagPicker mount 2603 2529 5000
TeachingBubble mount 11864 11951 5000
Text mount 430 416 5000
TextField mount 1356 1389 5000
ThemeProvider mount 1166 1193 5000
ThemeProvider virtual-rerender 592 609 5000
Toggle mount 784 805 5000
buttonNative mount 123 108 5000

Perf Analysis (@fluentui/react-northstar)

Perf tests with no regressions
Scenario Current PR Ticks Baseline Ticks Ratio
AccordionMinimalPerf.default 161 140 1.15:1
TreeWith60ListItems.default 181 158 1.15:1
AvatarMinimalPerf.default 201 181 1.11:1
ButtonMinimalPerf.default 173 162 1.07:1
AnimationMinimalPerf.default 416 394 1.06:1
DividerMinimalPerf.default 367 353 1.04:1
GridMinimalPerf.default 337 324 1.04:1
LayoutMinimalPerf.default 370 357 1.04:1
HeaderMinimalPerf.default 361 352 1.03:1
ItemLayoutMinimalPerf.default 1225 1184 1.03:1
ListWith60ListItems.default 654 632 1.03:1
ButtonOverridesMissPerf.default 1728 1691 1.02:1
CardMinimalPerf.default 538 528 1.02:1
CheckboxMinimalPerf.default 2763 2720 1.02:1
DialogMinimalPerf.default 749 737 1.02:1
FormMinimalPerf.default 393 387 1.02:1
ListMinimalPerf.default 507 498 1.02:1
SkeletonMinimalPerf.default 355 347 1.02:1
TableMinimalPerf.default 398 392 1.02:1
TreeMinimalPerf.default 780 768 1.02:1
DatepickerMinimalPerf.default 5444 5404 1.01:1
EmbedMinimalPerf.default 4101 4078 1.01:1
FlexMinimalPerf.default 280 278 1.01:1
PopupMinimalPerf.default 594 588 1.01:1
SplitButtonMinimalPerf.default 3743 3707 1.01:1
CustomToolbarPrototype.default 3875 3836 1.01:1
AlertMinimalPerf.default 262 263 1:1
AttachmentSlotsPerf.default 1043 1048 1:1
CarouselMinimalPerf.default 457 457 1:1
ChatMinimalPerf.default 614 617 1:1
DropdownMinimalPerf.default 3092 3084 1:1
HeaderSlotsPerf.default 741 740 1:1
InputMinimalPerf.default 1261 1265 1:1
LabelMinimalPerf.default 377 376 1:1
MenuMinimalPerf.default 829 833 1:1
MenuButtonMinimalPerf.default 1617 1623 1:1
ProviderMergeThemesPerf.default 1667 1659 1:1
RadioGroupMinimalPerf.default 443 443 1:1
RefMinimalPerf.default 238 239 1:1
IconMinimalPerf.default 609 607 1:1
TableManyItemsPerf.default 1878 1882 1:1
TextAreaMinimalPerf.default 481 482 1:1
VideoMinimalPerf.default 597 596 1:1
DropdownManyItemsPerf.default 656 664 0.99:1
LoaderMinimalPerf.default 686 695 0.99:1
PortalMinimalPerf.default 177 178 0.99:1
ProviderMinimalPerf.default 968 982 0.99:1
StatusMinimalPerf.default 661 667 0.99:1
ToolbarMinimalPerf.default 912 924 0.99:1
SegmentMinimalPerf.default 342 350 0.98:1
AttachmentMinimalPerf.default 146 151 0.97:1
ButtonSlotsPerf.default 527 542 0.97:1
ChatWithPopoverPerf.default 346 358 0.97:1
ImageMinimalPerf.default 354 365 0.97:1
ListCommonPerf.default 601 617 0.97:1
ListNestedPerf.default 532 550 0.97:1
SliderMinimalPerf.default 1541 1581 0.97:1
TooltipMinimalPerf.default 998 1028 0.97:1
BoxMinimalPerf.default 343 356 0.96:1
ChatDuplicateMessagesPerf.default 283 294 0.96:1
RosterPerf.default 1113 1174 0.95:1
ReactionMinimalPerf.default 364 383 0.95:1
TextMinimalPerf.default 333 349 0.95:1

"danger": "^6.0.5",
"del": "6.0.0",
"enhanced-resolve": "5.8.2",
"enquirer": "2.3.6",
Copy link
Contributor Author

Choose a reason for hiding this comment

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

explicitly added dev dependency (used by @nrwl/tao, but not re-exported as part of public API)

"workspace-tools": "0.12.3",
"yargs": "13.3.2"
"yargs": "13.3.2",
"yargs-parser": "13.1.2"
Copy link
Contributor Author

Choose a reason for hiding this comment

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

explicitly added dev dependency (used by @nrwl/tao), so lint rules will not yell. also we are using yargs-parser on other places directly -> it's a good practice to provide transient dependencies explicitly when they are being used directly

> No actual migration will happen.

```sh
yarn nx workspace-generator migrate-converged-pkg --stats --no-interactive
Copy link
Contributor Author

Choose a reason for hiding this comment

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

no need to use "private" --no-interactive flag

@@ -1,3 +1,4 @@
import * as Enquirer from 'enquirer';
Copy link
Contributor Author

Choose a reason for hiding this comment

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

why is this PascalCase ? enquirer exports a class with static methods (not the best way for tree-shakeability, it is what it is)

name: string;
}

jest.mock(
Copy link
Contributor Author

@Hotell Hotell Jul 28, 2021

Choose a reason for hiding this comment

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

mock away whole enquirer for sake of tests.

  • only prompt is being used within our implementation
  • scoped mock overrides are collocated within test suites

NOTE: ideal scenario would be to use doMock to provide scoped mocking per test, but until we are using deprecated ts-jest we cannot use that functionality (works only with babel-jest)

return json;
describe('prompts', () => {
function setup(config: { promptResponse: Pick<MigrateConvergedPkgGeneratorSchema, 'name'> }) {
const promptSpy = jest.spyOn(Enquirer, 'prompt').mockImplementation(async () => {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

collocated mock overrides

if (shouldTriggerPrompt) {
const schemaPromptsResponse = await triggerDynamicPrompts();

newSchema = { ...newSchema, ...schemaPromptsResponse };
Copy link
Contributor Author

Choose a reason for hiding this comment

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

not a fan of using let with mutation or even changing reference value completely (this case), but it's most concise solution for this use-case

"$source": "argv",
"index": 0
},
"x-prompt": "Which converged package would you like migrate to new DX? (ex: @fluentui/react-menu)",
Copy link
Contributor Author

Choose a reason for hiding this comment

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

opting out from nx tao CLI framework - prompts are triggered manually by us only when necessary

@Hotell Hotell marked this pull request as ready for review July 28, 2021 10:53
@Hotell Hotell requested a review from a team as a code owner July 28, 2021 10:53
@Hotell Hotell added this to the July Project Cycle Q2 2021 milestone Jul 28, 2021
@Hotell Hotell requested a review from a team July 28, 2021 15:56
Copy link
Contributor

@theerebuss theerebuss left a comment

Choose a reason for hiding this comment

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

LGTM

Hotell and others added 3 commits August 4, 2021 12:53
Co-authored-by: André Dias <andredias@microsoft.com>
Co-authored-by: André Dias <andredias@microsoft.com>
@Hotell Hotell enabled auto-merge (squash) August 4, 2021 10:57
@Hotell Hotell merged commit 0dc13ae into microsoft:master Aug 4, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants