microsoft / PowerToys

Windows system utilities to maximize productivity
MIT License
111.65k stars 6.57k forks source link

Simple API / plugin design #30061

Open TonyGravagno opened 12 months ago

TonyGravagno commented 12 months ago

Description of the new feature / enhancement

There are many requests for PowerRename to support features from other utilities, or to support special syntax. Rather than attempting to implement each of these in the core PowerRename Utility, consider an extension methodology that allows custom modules to perform operations based on hooks like pre_rename and post_rename.

Summary

At critical points in this utility, execute a BAT file using a well-defined API, and incorporate the well-defined result from that call into subsequent operations. Take time to think through all of the data that would be useful at each hook point. The better a job that's done on this thinking the less that will need to be done later to accommodate applications.

Detail

For the greatest impact support is required for .NET, NodeJS, Python, or Java. Supporting languages and an API is too difficult and will doom a suggestion like this. This application can implement the functionality by executing a .BAT file at every hook point, and using the results. Developers can do anything they want to get that BAT file to call their application, no matter the language or architecture.

Example: pre_file.BAT (fired before each file) Contents: foo.exe --regex 1 --from "...." --to "...." --flagx "...." --filename "current_file.ext"

A developer can replace foo.exe with whatever they want.
The return value from the bat should be parsed to derive a new from/to change for the current file. (Use output from a cmd invocation or in the API define a text or JSON structure for return values.)
If the filename has already changed, use that filename as the result. (An enhancement might be added to support a flag which causes the new filename to be used for continued processing.
Another post_file.BAT would allow for conversion, for example, of sequential numeric indices from base10 to hex, or allow a local application to re-index the new filename in a database. It would also allow for logging the name of the --original_filename and the new --new_filename along with information like who did it and the specifications that were used - in case triage is required.

Add a pre_all.BAT and post_all.BAT which might allow a user to log the fact that files were changed, or allow a for pre-copying or zipping all files before a rename.

This can also be used to implement PowerRename for compressed file archives. A high-level pre_app.BAT might decompress a zip or gz or 7z file into a folder and return the name of the folder for PowerRename to operate on. post_app.BAT would allow the developer to compress the folder back into its original form. This application wouldn't need to support that new feature!
Values passed to x_app.BAT need to include the original folder/file selected for renaming. This data can be used for subsequent logging in-context and other operations that are common to an entire run.

Scenario when this would be used?

Any scenario applies that has prompted a change request here for enhancements to the From/To mechanism.
Requests like #4929 are common.

Supporting information

Many users have applications that are outside the known scope of the original SmartRename application and the imagination of those who maintain PowerRename. As with any core platform that supports a plugin architecture, we don't know all of the possible scenarios where this utility can or will be used, so rather than everyone here waiting for someone to triage and maybe process requests, this simple API implementation can be used by anyone, and we can turn requests for new features into references to gists, wiki pages, and blogs where solutions have been implemented.

How does a hook know what code to use for a given file or folder?

For the first iteration of this feature I think it would be adequate to suffix the from or to replacement strings with any sytax a developer prefers. For example, if I end a From string with [[git1]], PowerRename will pass the request to the common BAT file, and my utility will remove that text from the From string and pass the request to the correct utility to process the current request.
A v2 implementation might add a dropdown list of processors to be invoked for the current run for defined hooks, but the intent of this ticket is intended to facilitate implementation without any UI changes at all.
In summary on this : PowerRename does not need to be concerned about this.

Possible arguments against

  1. It will affect performance : Does anyone care?
  2. It's inefficient to execute a BAT file via exec/cmd if there is nothing there to process : Require command-line flags on flags on the PowerRename executable, or a registry entry, or (best) read for files up-front and if they don't exist, don't do the calls.
  3. What if a user-defined process fails? : Not the problem of this application or any platform that supports such an architecture. Timeouts and try/catch can be added but that's overkill for a v1 of this feature.
TheJoeFin commented 12 months ago

This sounds pretty cool, @TonyGravagno is this something you would be interested in working on? Maybe even a small proof of concept to get an estimate of effort.