Skip to content

Heavy Refactor#1

Merged
zharovdv merged 16 commits intozharovdv:mainfrom
StefanRickli:refactor
Apr 13, 2025
Merged

Heavy Refactor#1
zharovdv merged 16 commits intozharovdv:mainfrom
StefanRickli:refactor

Conversation

@StefanRickli
Copy link
Contributor

@StefanRickli StefanRickli commented Apr 11, 2025

Hey, I'm working on a rewrite of this project (love your effort by the way!) to eventually support Altium's project releaser with Variants.

In the end, it probably will be a separate project on its own, but on the way - thus far - I have just refactored your code base a lot, and I'd like to contribute this back to you, before I make any incompatible changes.

Work done so far:

  • Deleted unused functions, variables
  • Reordered functions/procedures, put them into groups of similar functions
  • Renamed functions, variables
  • Clarified GUI a little bit
  • Fixed standalone GUI, so that it can be opened by just running the .pas script itself
  • Minor additions to generic JSON

Is it okay for you if I make my own project from this point on with your code base as starting point (acknowledging your authorship), because I can't find a license in the project. I suggest releasing it under the MIT license then.

(You will probably see a lot of activity on my end until next week, because I got exactly this time frame to work on it.)

Best, Stefan

@StefanRickli
Copy link
Contributor Author

Hey again - just to clarify, I really appreciate your original work here and definitely don’t want to step on any toes...

I realize my message might’ve come across a bit blunt - the idea isn’t to hijack the project or anything like that. I’ve just been doing a deep dive and wanted to contribute back before I go off into any custom or incompatible changes.

Also, if you have any preferences around licensing, project direction, or how you'd like contributions to happen, I’m very open to aligning with that. I’d love to hear your thoughts.

Thanks again for putting this together in the first place - it’s been super helpful!

@zharovdv
Copy link
Owner

Wow - give me some time to review :)

@zharovdv
Copy link
Owner

Hi! All good — you’ve done a great job. Developing plugins for Altium is a real pain — poor documentation, a terrible IDE, no debugging, and constant crashes. As a result, the code gradually turns into a mess full of endless trial-and-error attempts and heaps of commented-out code “for later” or “just in case.” I’m honestly a bit ashamed of the current state of the code, and you've improved it a lot — thank you.

As for the license — I’m not very experienced in that area, but I think it’s best to go with something as permissive as possible, like MIT. I’ll add it to the project ASAP.

The direction of the project is simple — to provide people with an open-source iBOM for Altium, and maybe also serve as an example of what Altium scripting can do. There are two main principles: stay compatible with InteractiveHtmlBom and be standalone (i.e., be able to generate HTML even without Python). I even managed to get the project mentioned on the original InteractiveHtmlBom repo, hoping to attract some community — and it looks like it’s working.

About the dummy parameters — let me explain why I do it that way. If a function has even one parameter, it doesn’t show up in the “Run Script” list — avoiding that makes the script much easier to use for non-technical users.

Since my last pull to the project, I’ve made a number of updates, and I’ve merged them with your pull request — preserving as much of your work as possible. I’ve dropped my custom JSON format and rewrote the JS part so it works with the original JSON schema. This helped remove a lot of duplicate code, plus I added some small improvements — arc, text, drill, nets, first pin, etc. I hope none of that broke anything on your end.

Regarding code style — I try to stick with the Delphi code style, since it’s kind of the de facto standard for Pascal.

I see you're working on an interesting project — altium-ibom-releaser. Just curious: why are you going with JSON + Python instead of using the HTML output generated by the plugin?

P.S. I’ve also been working on a PnP script, since I’m not happy with how Altium’s built-in one works.

@zharovdv zharovdv merged commit 37805be into zharovdv:main Apr 13, 2025
@StefanRickli
Copy link
Contributor Author

@zharovdv Awesome! 🎉 I'll take a closer look at your rewrite tomorrow. Super excited about the missing object types - I was already dreading having to add them next week 😄 And yes, the scripting engine is a total trainwreck, so I completely relate - my first attempts look just as messy as yours used to 😅

Thanks for the clarification with the Dummy variables. I missed that detail where the procedure picker excludes procedures with arguments. Maybe a simple comment somewhere explaining it would be enough to prevent any future overeager refactorer like me to remove them again, haha!

MIT sounds great 🙌


Here’s the reasoning behind my hybrid Pascal + Python approach:

When I first reviewed your code, I noticed that even though a variant was selected in the Output Job, the generated iBOM didn’t include any components that were actually varied (i.e., alternate parts from our company vault with the same footprint were missing). I tracked this down to the for loop where the Board Iterator simply skipped all components with variations - unless NO_VARIATION was selected.

So I concluded that to reliably get complete variant data, I’d have to pull that info from another source. I considered using ODB++, which is probably the most robust option - but due to time constraints and the lack of a good Python parser, I ended up using Altium’s native Pick & Place file instead. That’s why I added the Python transformer as an intermediate step.

(That said - maybe I missed something! If your Pascal script can export variants correctly, I’d love to be wrong about this!)


Why I plan to use InteractiveHtmlBom as-is:

Now that I already have a Python transformer in place, it’s easy to pull in InteractiveHtmlBom as a simple package dependency and call its code directly. Using it unmodified feels like the most sustainable solution in terms of maintenance - especially as it evolves.


My thoughts on the HTML/JS files in the Altium project folder:

From what I understand, your current approach expects the project to include the HTML/JS template files as part of the repo. That totally works, but it has some drawbacks I’m hoping to solve in altium-ibom-releaser:

  • The extra files add clutter to the project tree in Altium.
  • Updates to InteractiveHtmlBom need to be applied per project, which doesn’t scale well.

So instead, my plan is for the Pascal script to generate just the generic JSON - with only two files (.pas and .dfm) added to the project. That’s the minimal footprint. Then the user has two options:

  1. (Recommended): Let the Pascal script invoke a globally installed altium-ibom-releaser binary automatically as part of the Project Releaser. This works well because the directory structure is predictable during a release preparation.
  2. (Advanced): Just export the JSON and run a separate background watcher that bulk-transforms it using altium-ibom-releaser. Not ideal though, since variant directories can be more dynamic.

In both cases, the goal is to keep the integration minimal and maintainable, so projects can automatically generate iBOMs for all variants without having to trigger a manual update when InteractiveHtmlBom changes.


Thanks again for being so open and for merging the changes so cleanly! I’m really glad we found this synergy 🙌

@zharovdv
Copy link
Owner

Yes, maybe it's worth adding a comment in the code about the Dummy parameters. I thought it was a standard practice in the community — or maybe I just convinced myself it was 😄

It's really strange that the variant support didn’t work. I haven’t specifically tested it in this plugin, but I actively use variants in another plugin I wrote for generating PnP and BOM files — and there it works reliably and cleanly. I’ll double-check and fix it if needed.

About including HTML/JS in the repository — here's how I usually handle scripts. I have a directory at /home/user/altium/scripts/ where I keep all the scripts I use, each in a single instance. Then I link them to the projects I need. That way, I only have one copy of each script, which makes updates super easy.

You might ask: what about collaborative development? There’s a solution — Altium is smart enough to store paths relative to the project file’s location. So if your plugins and projects are placed more or less nearby, and your teammates stick to the same structure, everything transfers smoothly.

That said, I’ll think about it — nothing stops us from adding an option to bundle the HTML/JS files inside the plugin itself. That would let us keep everything in one place.

@StefanRickli StefanRickli deleted the refactor branch April 14, 2025 07:42
@StefanRickli
Copy link
Contributor Author

StefanRickli commented Apr 14, 2025

@zharovdv

I'll take care of improving the code documentation and will clean up function/variable names a bit more - thanks for pointing me to the Delphi style guide! I'll try to stick to it as best I can.

For now, I'll keep working on top of your code and try to stay compatible with the current functionality. I'll also bring my intermediate variant-fixer to a proper release state. And if we find that the Pascal script can indeed handle variants cleanly, I'll be more than happy to throw my workaround away 🫠


A few things that already came up - curious to hear your thoughts:

  • Font data extraction (altium-fontdata.js):
    How did you extract the SVG font data originally? It seems some characters are missing, and you're patching them manually in fixtext(). I'd be happy to regenerate this file properly if I know your method.

  • InteractiveHtmlBom v2.10.0:
    It was just released and includes your fix for rectangle-shaped pad holes 🙌 So I assume we can now remove that workaround from altium-user.js, right?

  • Script linking with A365 / Project Releaser:
    Your setup with symlinked scripts is genius - but unfortunately I hit a few walls using it in Altium 365 with the Project Releaser:

    • Even after committing the linked script, Altium constantly complains about unsaved changes. Clicking "Save to server" sometimes creates empty commits and doesn't resolve the warning.
    • During "Prepare" in the Project Releaser, Altium warns about the linked file (fine), but then fails to find the script when running the OutJob. I suspect this is because it clones the repo into a temp folder, which breaks the relative link.
    • TL;DR: As much as I love your setup, it seems unusable for us under A365 + Project Releaser 😢 Do you see any workaround for this? Otherwise, I guess we'll need to commit physical copies of the Pascal scripts to each project.
  • Font embedding breaking generic JSON output:
    With altium-fontdata.js now being external, generating generic JSON without this file inside the project breaks. What do you think about embedding the long string directly into the Pascal script again? I'm happy to take care of that too, if you're okay with it.


Let me know what you think - and thanks again for the super open and helpful collaboration!

@zharovdv
Copy link
Owner

  1. Yes, I do have a script for generating the font, but I couldn't convert it to a Pascal script that runs within a reasonable time, so I’m currently using a pre-generated file. I’ll regenerate a complete version of the font and share the script with you as soon as I find it :)

  2. That’s right — done.

  3. Honestly, I don’t use Project Releaser in my workflow, though I’ve been meaning to for a while. I’ll try it out in the next few days — if anything breaks, I’ll take a look and fix it.

  4. That’s really strange — I use the generator pretty much every day. There might be a bug that’s preventing the document from embedding properly — it’s better to debug that first. The font is extracted in the ParseFontData function, and nothing there should break except possibly GetWDFileName. A lot depends on that function — if it’s the source of the issue, we definitely need to fix it. Let’s keep re-embedding the font as plan B.

P.S. We could also take another look at the Variants — could you describe in more detail what’s not working? What result are you getting, and what are you expecting?

@zharovdv
Copy link
Owner

Maybe we should add an option to specify the path to the web directory and the font file?

@zharovdv
Copy link
Owner

zharovdv commented Apr 14, 2025

I just tried Release Manager — and yes, the problem is that it copies the entire project into a new folder, so there's no way to determine the original project path. There are three possible solutions:

  1. Include the HTML/JS files directly in the project — that way, the Release Manager will copy them as well.

  2. I made a nasty hack that finds the original project among the open ones and builds the correct path based on that. It might break in the future.

  3. Add an explicit option to specify the font and HTML location.

@StefanRickli
Copy link
Contributor Author

I'll regenerate a complete version of the font and share the script with you as soon as I find it :)

❤️ Much appreciated!

Project Releaser

It's surprisingly useful. Our company uses it to release everything - all docs for all variants - to a mapped network drive. That way, everything is kept together in a nice structure. We don't use release to A365 itself, since we follow a custom version/revision scheme that doesn't integrate well with it.

HTML generation

I can see you've put a lot of effort into generating the HTML directly via Pascal - hats off for getting that working! 🙌
However, with the current behavior of the Project Releaser (copying everything into a temp dir), I'm increasingly convinced it might be too brittle to handle this approach reliably in the long run.

Three possible solutions…

I've actually been working on a fourth option (should be in a previewable state tomorrow) - and I think it could simplify things a lot:

I'm building altium-ibom-releaser as a single Windows executable, bundling InteractiveHtmlBom and some custom transformation logic. It'll be installable via a small script that adds it to the system PATH.

The Pascal script (InteractiveHTMLBOM4Altium.pas) can then simply call it via RunApplication, without needing to know the exact path.

Why this could work well:

  • No need to generate HTML inside the Pascal script --> cleaner code in InteractiveHTMLBOM4Altium.pas
  • Direct dependency on InteractiveHtmlBom without modification: easy to update
  • No need to ship or update template files per project (except for the .pas/.dfm files).
  • Simple for the user:
    • Initial setup: run the installer once --> executable is placed in PATH
    • Per project:
      • Add .pas/.dfm files to the project (not linked)
      • Configure the Output Job: Pick & Place + JSON export via InteractiveHTMLBOM4Altium.pas
      • Commit / Save to Server
    • Per release:
      • Just hit "Release" --> the Pascal script runs and calls the bundled altium-ibom-releaser to generate the final iBOM from the JSON

Curious to hear your thoughts!

@zharovdv
Copy link
Owner

I need some time to respond properly.

@zharovdv
Copy link
Owner

I've made some updates to bring our approaches closer together.

  1. Reworked base folder detection logic – now it behaves like OutJob, Standalone, and Release Manager. I believe this works correctly in the vast majority of cases, so you can safely use any mode. This is how I envision the plugin – download and use, no configuration needed.

  2. Added diagnostics to the base folder search – it now reports when it can't find the folder and shows where it expected it to be.

  3. Code ready a fallback base folder field – if you specify an absolute path there, it will work consistently and reliably regardless of the launch mode. This is plan B.

  4. Brought back the font into the code as plan C – hopefully temporarily (but what could be more permanent than something temporary, right?).

  5. Restored full support for field passing to iBOM and grouping.

  6. Lots of other tweaks to ensure the script works stably and correctly in various modes. I encountered some black magic during debugging – not only was Altium crashing constantly, but the code started acting weird and refused to launch...


P.S.:

  1. I remember the font generation script
  2. I see you changed the default naming format – Altium plugins typically follow two styles: the one I used and the one you chose. Yours might actually be better suited for this plugin, so I’ll likely switch to it too.
  3. I saw you're working with PnP and Variants – I understand you need DNP support. I had that mechanism before, and I plan to reintroduce it in the next patch.
  4. Not quite sure why you need ExportConfig and RunInteractiveHtmlBom.

P.P.S.:

The original idea behind my script had three working modes:

  • iBOM – the main one,
  • JS – a specific format for ERP integration,
  • JSON – for the original Python-based iBOM that you could launch with the right parameters directly from the plugin. Haven’t implemented this stage yet.

P.P.P.S.:

Your version is also a valid approach, but I'm still hopeful I can manage with a pure Pascal script, without relying on EXE/Python/etc. I have another complex plugin that heavily uses RunApplication, and it works just fine.

@StefanRickli
Copy link
Contributor Author

Man, you're gold, I'm enjoying this collaboration!

Alas, unfortunately, tomorrow is the last day I can work on it. After that, I'm on vacation, won't be working for that company anymore, and won't have access to Altium 🥲. That's why I was in such a rush (sorry for that!).

I will review your changes and merge my latest modifications, if time allows!

@StefanRickli
Copy link
Contributor Author

Maybe we can schedule a brief video call where you show me how you're using it - I'm still not sure if I got 100% the same mental picture. Would love to know. Hit me up at my committer email if you're interested.

@StefanRickli
Copy link
Contributor Author

StefanRickli commented Apr 16, 2025

I will open a new pull request and add my refactors there, so you get updates on what i'm doing.

@zharovdv
Copy link
Owner

Man, you're gold, I'm enjoying this collaboration!

Alas, unfortunately, tomorrow is the last day I can work on it. After that, I'm on vacation, won't be working for that company anymore, and won't have access to Altium 🥲. That's why I was in such a rush (sorry for that!).

I will review your changes and merge my latest modifications, if time allows!

Oh, that's a shame — you gave me a fresh creative spark to get back to working on the plugin again; I had sort of abandoned it. Have a great rest!

@zharovdv
Copy link
Owner

I will open a new pull request and add my refactors there, so you get updates on what i'm doing.

Yeap, I see, on my way. I'm a busy with work at the moment.

@zharovdv
Copy link
Owner

Maybe we can schedule a brief video call where you show me how you're using it - I'm still not sure if I got 100% the same mental picture. Would love to know. Hit me up at my committer email if you're interested.

Ok

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants