-
Notifications
You must be signed in to change notification settings - Fork 67
Clean Unlocked Packages #1423
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
base: main
Are you sure you want to change the base?
Clean Unlocked Packages #1423
Conversation
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 looks promising :)
In order to keep consistency with other commands, please:
- rename the file into unlocked-packages.ts
- move run method just after protected debugMode = false;
- fill static description like other commands (behavior + technical explanations ) -> GitHub copilot or any AI coding tool will do that for you :)
- If many features are not covered yet, please state it in the description as limitations
- add (beta) in the title as everything is not covered yet ^^
To test the result in VsCode sfdx-hardis (uxlog stuff ^^), you can use the extension setting option "Commands are used in VsCode terminal"

if you need to debug, you can even use Debug option :)

I've made a number of those updates. There are still 1 or two things pending (properly handling quickaction and remotesite files, cleaning up use of uxlog) so that needs resolving before anything gets merged, even while flagged beta. (Also, I have no idea how to clean up the mess I made on my other PR. It's basically referenced every PR in the past 12 months, leaving a mention on all of those PRs) |
So I've found one place in salesforce source management libraries where they also manually handle QuickActionDefinition uniquely (and have a bug tracked against it): https://github.com/forcedotcom/source-tracking/blob/86aae0f555aaa48683e730fd1127994b0e091876/src/shared/remote/orgQueries.ts#L98 I'm struggling to find the same for RemoteProxy/remotesite but it still stands that source-deploy-retrieve doesn't handle translating that metadata type to a folder. The big unknown for me is how many other sources (apart from those that are entirely unknown to globalDescribe/tooling globalDescribe) are going to need manually handling like this. I think I would have been comfortable to say "It's only QuickActions" if I had an explanation for RemoteProxy, but given I don't have that explanation, I would struggle to say it can come out of beta until there's been more general use and we've not found any more outliers. |
Here's a proof of concept clean unlocked packages.
You get a list of packages, and can choose one to clean up. After that, a series of API calls determines the members of that package, looks at your sfdx project and finds the files from that list of members you currently have in your project, and then you can select on a file-by-file basis which ones you would like to delete. It then deletes those files on confirmation.
Outstanding issues:
Dependencies - At the moment I'm importing modules that are dependencies of dependencies, didn't want to personally muck around with package.json, but if these are necessary imports then they'll need to be promoted to first class dependencies.
Edge cases - I haven't handled every edge case, nor done extensive testing on what those edge cases are. You'll note in the source code I'm already manually handling RemoteProxy (remotesite) and QuickActionDefinition (quickAction) as @salesforce/source-deploy-retrieve can't match and return the directory for these items. I'm sure there are plenty more. Further to this, I'm not actually successfully deleting quickaction or remotesite files yet.
Unknown items - There are some things I don't know how to process. For example, NebulaLogger references sobjects with prefix '0A7' and '02m' (I don't know if they are determined per install, so the specific prefixes may not matter) which I can't look up in describeGlobal for either Rest API or Tooling API, so I just can't handle those items. I am currently logging out "Could not find reference to the component prefix: 0A7. No items of this type fetched." so the user is aware things have been skipped.
Batching - I haven't got any in-code batching for API calls going on. I'm leveraging both Tooling API composite requests (
/services/data/vXX.X/tooling/composite
) and SObject collections (/services/data/vXX.X/composite/sobjects
) to get each type of member in one hit. However, composite requests are limited to 25 subrequests or 5 if using certain kinds of subrequests. Technically, I could use/services/data/vXX.X/composite
to batch 5 SObject Collection calls (that's one limited as above) but I haven't done so yet.Skipping large lists of members - The above means, at the moment, for any given type, if it's over 25 items, I check whether it's available from sObject collections and fetch details from there, and if it's not supported, then I'm just not fetching it (and log out "Too many members to fetch: TypeName(pfx)"). For example this impacts CustomField because it's not available via sObject collections, and with a few custom objects in the package, tends to be more than 25 items.
Skipped members on standard objects - When the CustomFields are limited to the CustomObjects from the installed package, the above issue isn't a problem, they get cleaned up when we clean out the Custom Object. It becomes a problem where an unlocked package modifies a standard object (or an object of a dependent package) and we're not reaching in and grabbing that CustomField. This would be solved with an adequate in-code batching solution.
ux - I've also not thought really at all about what gets a uxLog and each file removal has its own uxLog which is a poor choice.
I'm sure there's more issues to manage, but this is a start.