joyfullservice / msaccess-vcs-addin

Synchronize your Access Forms, Macros, Modules, Queries, Reports, and more with a version control system.
Other
207 stars 41 forks source link

Support Rubberduck @Folder annotations in modules #222

Open bodywithoutorgans opened 3 years ago

bodywithoutorgans commented 3 years ago

It would be useful in larger projects if Rubberduck @Folder annotations in modules were optionally respected causing module files to be exported to respective sub-folders under 'modules' (forms, reports) folder.

joyfullservice commented 3 years ago

That is an interesting idea... I would be happy to review a PR for this if there is sufficient interest. While the export is pretty straight-forward, the import/change detection would require some more refactoring since the source folders would need to be recursively queried for changes.

hecon5 commented 3 years ago

I think instead of having to parse the file, this could be added to a configuration, and an asynchronous parse.

Much like the table import/export settings are base on each table (data/config only, etc.), perhaps if the @folder mentions were present in the Module/form, the parser could snag that and save the location of the folder. This would considerably speed export/import, as it wouldn't need to be Just-In-Time parsed, or recursive checking, it only checks the file / folder that's been configured, or (if the module/form is new/unset) the Module/form folder.

hecon5 commented 1 year ago

I just came up with a use case where this would be REALLY nice. We have a few applications that share a fair number of common modules between them. This requires us to hand-copy over the relevant modules, and track twice the code changes in both repositories because Git doesn't do per-file versioning with submodules (EG "these" files are that submodule, those are the other one).

If we could tag the "common" modules to be exported to a specific folder, we could easily turn that folder into a submodule within git and then manage them together instead of needing to deal with hand-managing and duplication of version data.

Shoot, even within this tool it'd be nice to see what's required to customize this Addin vs what could be commonly used, or "standard" parts (like modJsonConverter or modUtcConverter). This also makes managing license and attribution requirements easier, too!).

hecon5 commented 1 year ago

import/change detection would require some more refactoring since the source folders would need to be recursively queried for changes.

Would it, though? Now since the index & hash is almost exclusively used for change detection, we already know what files exist, we would simply need to know the file is now in the "other" location for export/import.

It would have the single outcome of we could not have two files / objects with the same name in the database (which is already a bad practice), so honestly...I don't see many downsides.

joyfullservice commented 1 year ago

import/change detection would require some more refactoring since the source folders would need to be recursively queried for changes.

Would it, though?

The export side is pretty simple, since you are parsing the tag from the code module object. Where it gets a little more tricky is on the build side. A build is performed based on source files (even if no index is present) and up to this point all the source files have specifically defined locations where they are expected to exist. (I.e. forms, reports, modules)

Let's say you are running a build on a project that grouped several modules into a RubberDuck tag folder called Gateways\Square. This means the actual source files would be located in \modules\Gateways\Square\*.bas. That's why I was describing the recursive nature. Basically every subfolder under the known source files folder would also need to be iterated to identify any source files that had been tagged.

It also introduces some potential considerations that would have to be kept in mind from the perspective of managing a project at the source level. If you have an object in your database called Module1, and modules only use one folder in the source files, then Windows itself will not allow you to create a second file with the same name. But with tagging, you could have multiple copies of this file in different subfolders. These duplicate file conflicts should be highlighted during a build so the user is aware of the problem.

Another consideration is that a tag is a free text value that does not have the same limitations as Windows folder names. So there would need to be a translation from the tag name to the folder name for exporting and verifying the file.

Exactly how this would integrate with the index is another thing that would need to be thought through from a performance standpoint For example, do we store the tag name as an attribute with the component entry? We would need to review the various scans and comparisons that take place during exports, builds, merges, conflict detection, and orphaned file detection to determine the most appropriate way to handle this.

I like the idea of implementing this, it is just a matter of carefully working through the side affects and potential gotchas so that it can be a robust feature without adding too much complexity to the underlying code base. I think enough people use the RubberDuck folders to warrant implementing support for this. (And even if they don't use RD, the @Folder tags would still be useful for organizing the export of large numbers of source file objects.)

Something to keep in mind for the future is that while the RD Folder annotations work great for the items visible in the VBA IDE, there are other types of objects, such as queries that don't contain VBA source code, and therefore don't have a way to add the Folder tag. Custom document properties might be a good way to manage folder tags for other non-VBA objects, but we can cross that bridge later as the need arises.

hecon5 commented 1 year ago

What do we do on a merge build for building an index? Wouldn't we need to iterate the "unused" folder anyway (if someone adds a "modules" folder & code when all your code is in the forms in the one you're working on)? If we enforced a one-deep structure, would that be a decent trade off? or is building a folder iteration mechanism just as hard as a recursive iteration tool? We've done something a little similar, but not for indexing.

To me, really the biggest bang/buck would be from VBA modules (bas/cls), then Forms/reports, then macros, and lastly queries / tables, so not being able to natively tag the objects would be a-ok from me.

mwolfe02 commented 1 year ago

Another consideration is that a tag is a free text value that does not have the same limitations as Windows folder names. So there would need to be a translation from the tag name to the folder name for exporting and verifying the file.

That's a great point. I think the only sane way to handle that would be to halt the export to source and raise an error if a folder tag had invalid file characters in it.

MarkJohnstoneGitHub commented 9 months ago

From a brief read @bodywithoutorgans proposing an export tool to export components according to the RD folder annotations. I have developed a tool help with that. Rubberduck Export All Utility I require to update it as the latest version that I use is in another project Rubberduck Export All Utility that also gives warnings when module/class names are greater then 31 characters. Initially didn't realise Excel doesn't like more then 31characters for modules names where Ms-Acccess is fine with it. Will be looking forward to when Rubberduck 3 is "released" with workspaces. I've really focused on exporting modules and class, some features proposed above would require some tweaking.