Clarity on GHPY component guid

Hi, I am compiling GHPY, and want to clarify what does each GUID (there are two) in each GHPY do?

There is a component GUID, and there is an assembly GUID.

I understand that the component GUID ensures that your existing GH scripts wont break when you update the component. is this correct?

I have no clue what the assembly GUID does. Anyone have knowledge of this?

Cheers

assembly guid ensures that you gh definitions won’t break, yes.

Think of the assembly guid as a dll.
It can have numerous components inside one dll.
That’s why you have separate guids for a component and an assembly.

McNeel said somewhere that they do not recommend compiling multiple components into a single assembly, but it is possible. This is also what I have done.

Make sure you write down these guids though :wink:

therefore both assembly guid and component guid must be the same when updating. got it. thanks

1 Like

Although in an update you may want to give the new update a new component GUID and keep the old one with the old component GUID but marked as _OBSOLETE and an exposure level of hidden. (not sure if it works that way in python, in traditional C# or VB components that is how it is, this gives the previous component an “old” tag and lets it still exist in the definition in case users do not want it replaced, you can then find the old components still in Grasshopper by searching with a # character).

1 Like

I am attemping to automate the compiling process using piac’s assembly functions.
And guid is one of the things im automating.

my workflow relies on users keeping a copy of the compiling files somewhere, maybe the depo where they store the components, that they can reuse later to update the components.

so i am persisting guid for assemblies and components inside this package. although i dont have a guid history, i am currently considering adding it…

Me neither. Perhaps a good puzzle for @piac? :slight_smile:

I thought we should keep the guid the same between updates, so that it wont break existing GH scripts using those components?

btw this is how I compile multiple components into a single assembly :wink:

image

image

Ok so there are things to consider and why the “old” tag exists. If you change component GUID then yes it will break the definition, UNLESS you keep a copy of the old one with the old GUID also in your assembly. Then any existing versions in the definition will be old version and it will be up to the user to replace them manually with the new component if they want, but the definition will not break.

You can just update with the same GUID not changing it and GH will automatically replace the component. However, you do not want to do this in some cases which will also break the definition. Those cases are things like: If your update has new or less inputs / outputs, If your update inputs / outputs a different data structure than before (item / list / tree), etc.

Another not breaking but possibly annoying thing could be if functionality changes or the component works differently than how someone used it before, you may not want to force them to use a new method if their definition relys on the old method.

So it is really discretionary, and this is why sometimes you see components marked as old in gh definitions when the newer version was updated, it means the update was a breaking change more than likely.

2 Likes

This is very good discussion, I think I will stick with inserting the old tag, while putting in new tag for components, by default. It is very hard to automate this using some sort of component analyser, that compares the old and new, to see whether there are breaking changes…

you can use *filenames here

Yes i have something very similar. The compiling process is trivial using piac’s assembly functions.

The hard bit is how to automate the guid for old and new components… how to keep track of old GUID, and when to update guid, are hard decisions to automate.

currently, i am using a uuid4 seed to generate pseudo guid.

for example:

  1. If i insert 4 new component to compile, it will generate 4 new guid.
  2. If i remove 1 of these components, the guid list will remove that associated guid.
  3. but if I add back this component, the guid list will generate the same guid again, from the seed.
  4. if i want to do a total update of all guid, then i refresh the seed.
  5. the GH file saves all the seeds into its hidden document settings, so that it can always be retrieved in future.
  6. Therefore , if I save this gh file on the cloud, I can open it anywhere else and have those same guid’s, and continually update the components

However there are still many guid related issues to do with updating components with or without breaking changes.

I believe you just keep the component and keep note of the guid.
The new version is a new component but with the same name and slightly different (updated) functionality.
As for how to do that, I don’t know I hope Giulio (@piac) has some examples.

What I do is generate a bunch of guids and keep them in a ListComponent with the name of the component. And before assembling the code, before the compilation I pick from the dropdown the component name and it spits out the guid.

I don’t think is a good idea to re-generate the guid. What if they change the algorithm and suddenly using the same seed doesn’t give you the same guid?

Yes that is good thoughts, currently I am storing the seed and the {guid: component name} keyvaluepair. It is stored inside the GH document settings. I didn’t want to rely entirely on the component name since I do not trust people working at a consistent enough level to maintain same names (I have to design this with thousands of users in mind).

The algorithm to generate guid from my seed relies on the random.getrandbits. Perhaps I will re-implement this function in full so that it is never changed in future update.

@piac Hello Giulio - is it possible To add the old tag and hidden exposure using ghpython GHPY code geneneration ?

I am using these:

GhPython.Assemblies.ComponentGenerationParams(component).settings

GhPython.Assemblies.CodeGeneration.GenerateComponentCode(component, settings, randomIds=False)

In C# and VB you just name the component with _OBSOLETE in its name to get the old tag. So for instance A component named PullPoint would be named as PullPoint_OBSOLETE. You can see if that works.

interesting!

Cheers -

I’ve tested out the _OBSOLETE prefix in component name, from what I see, it doesn’t do anything. The behaviour I see is, as long as the old component is in the plugin with the old guid, no matter what you name the obsolete component, the obsolete components in the gh file will still be there, with the old name.

Being able to see the actual “old tag” on the component, and also able to hide the obsolete component using the exposure level, is highly critical.

Any clue how to get these behaviours?

In C# it is like

public override GH_Exposure Exposure
{
get { return GH_Exposure.hidden; }
}

Aside from .hidden there are other options you can see here. https://apidocs.co/apps/grasshopper/6.8.18210/T_Grasshopper_Kernel_GH_Exposure.htm

Thanks - I will see what happens if I just plug this into the pre compiled ghpy python code!