Skip to content
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

Deterministic GUIDs for cargo-wix init #85

Closed
slonopotamus opened this issue Sep 5, 2019 · 8 comments
Closed

Deterministic GUIDs for cargo-wix init #85

slonopotamus opened this issue Sep 5, 2019 · 8 comments

Comments

@slonopotamus
Copy link
Contributor

Currently, cargo-wix init produces new random GUIDs each time it is run: for product and for binary.

Instead, I suggest seeding RNG that is used to generate UUIDs with crate name for product UUID and with crate name + binary name for per-binary UUID. That would allow simple applications to completely avoid storing wxs file in repository and instead directly run cargo wix init && cargo wix in one go (this could possibly later be made a single command).

@volks73
Copy link
Owner

volks73 commented Sep 5, 2019

I wonder if this would be better implemented as CLI options instead of messing with random number generation seeding? Something like:

> cargo wix init --product-guid xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx --binary-puid xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

I do recognize that it is not very user friendly to have to type the GUID on the command-line, but I am imagine the desire for deterministic GUIDs is for automated deployment/build reasons. These options could be added to the build configuration.

Additionally, if I ever get #20 completed, then these GUIDs could be added there as well and not have to be typed out each time. This would enable a secondary flag that would delete the WXS after build. A sort of variant of your single init and create command.

Can you just add the WXS file to the vcs ignore list? What about putting the WXS file in a hidden folder or somewhere outside of the project's version control root?

I would also mention that according to the WiX Toolset developers, it is best practice to include the WXS file in the project's version control and keep along with the source code. They consider it source code.

@slonopotamus
Copy link
Contributor Author

slonopotamus commented Sep 5, 2019

cargo wix init --product-guid

OK, this would work for my scenario.

--binary-puid

That won't work if/when #78 is implemented.

Can you just add the WXS file to the vcs ignore list?

No. UpgradeCode needs to be stable, otherwise upgrades won't work. Windows Installer uses UpgradeCode to understand that multiple MSI packages are different versions of the same software.

They consider it source code.

Thanks to cargo-wix, we can (almost) consider WXS as an intermediate build artifact.

Actually, I see contradicting signals here:

  1. On one side, you say that you don't want to proxy WXS configuration through cargo-wix and instead expect users to use cargo wix --init as a one-time operation.
  2. On the other side, you want to add [package.metadata.wix]. For one-time operation, why?Command-line options are more than enough.

@volks73
Copy link
Owner

volks73 commented Sep 5, 2019

That won't work if/when #78 is implemented.

The binary GUID is for the PATH environment variable, not the individual binary (exe) files or components. The binary components within the Bin directory have a placeholder GUID, i.e. *. So, only one binary GUID is needed, but the CLI option should probably be --path-guid instead of --binary-guid.

An explicit GUID is not needed for the binaries. The default template does not currently account for explicitly providing a GUID for the binary (exe) components. Is there is a situtation where they need to be explicit? If so, then another flag should be added to the init command: --explicit-binary-guid or something similar.

Actually, I see contradicting signals here:

These were some initial thoughts and ideas before coffee, so I am not surprised they were not fully coherent or consistent.

  1. On one side, you say that you don't want to proxy WXS configuration through cargo-wix and instead expect users to use cargo wix --init as a one-time operation.

Yes, I envision the cargo wix init (it has since been updated from the --init flag) to be used only once for a project. From there, all configurations and complex customizations for the installer should be handled in the WXS file because it already does an excellent job handling all of the various customizations and edge cases for building Windows installer.

As you mention, the product GUID is a configuration and should not change. So, ayny command-line option for it would be associated with the init command.

  1. On the other side, you want to add [package.metadata.wix]. For one-time operation, why? Command-line options are more than enough.

Yes, since the potential --product-guid and --path-guid would be used with the init command and not used in the create (default) command, it does not make sense to have them be part of any potential [package.metadata.wxi] configuration. See above about initial, poorly formed ideas. The [package.metadata.wix] section should only contain the options and flags from the create (default) command to alleviate having to constantly re-type the same options/flags over and over when building the project and installer through cargo.

Thanks to cargo-wix, we can (almost) consider WXS as an intermediate build artifact.

Can you elaborate a little more on the desire, or use-case, of wanting to eliminate the WXS file as a source file?

Additional thoughts (ramblings?):

Seeding the RNG with the crate name is an elegant solution but wouldn't this increase the likelihood of generating a collision since multiple applications of the same name, inside or outside the Rust and crates.io ecosystem, are possible? Granted, it is still unlikely, but increasing the likelihood of collisions is kind of bad, right? Maybe seeding it with the authors (vendor) and crate/product/project name? This would alleviate the need for relying on crates.io to ensure crate/application/product name uniqueness.

Is playing with the seeding overly complicating things? I did some (very brief) investigation, and the IETF RFC for UUIDs allows for an "Algorithm for Creating a Name-Based UUID" (Section 4.3). Could the crate/project/package/product name be the name and the authors (vendor) be the namespace? The uuid crate supports both v3 and v5 UUIDs that can be used for this scheme.

At the very least, I would want this to be behind a CLI flag of some kind for the create (default) command and not the default behavior because it currently feels like a minority use case. A --deterministic-guid or --no-wxs flag or something similar for the create (default) command. This flag would also indicate that the init command is not needed and be the combined init and create command. Since it would be part of the create command, it would be a field in any future [package.metadata.wix] implementation.

Yet another thought: the flag could be an option instead, where the value is the name and namespace that is passed to the UUID generator. Something like --guid-name <NAME> and --guid-namespace <NAMESPACE> or --named-guid <NAMESPACE>=<NAME>?

@slonopotamus
Copy link
Contributor Author

slonopotamus commented Sep 5, 2019

imagine the desire for deterministic GUIDs is for automated deployment/build reasons

Yes, you're absolutely right.

Can you elaborate a little more on the desire, or use-case, of wanting to eliminate the WXS file as a source file

All data that cargo wix init currently takes fron Cargo.toml can possibly change and if WXS is not meant to be regenerated, that data will need to be updated in two places. As I already said, for my little application I don't need to touch anything in autogenerated WXS, it works as is, and could drop WXS from repository if there was a way to generate stable GUIDs (no matter if they are seeded from Cargo.toml or there's a command-line switch).

I do understand that more complex apps will require custom WXS, so it is good that you separated init from create.

I thought once again and think there is another route: more dynamic things could be proxied via WIX variables to WXS, like you're currently doing with Version.

Anyway, possibly I am being too much a perfectionist here and current cargo-wix behavior is Good Enough.

And seems like you're right, seeding from project data GUIDs is not so trivial and can cause issues, so command-line switch to pass them from outside is a better way to go. Though, again, if cargo wix init is supposed to bea one-time action, even command-line switch is an overkill - user can go and edit WXS however he needs.

@slonopotamus
Copy link
Contributor Author

increasing the likelihood of collisions is kind of bad

My 10y+ programming experience tells me that any system that involves GUIDs stored in files sooner or later hits problems caused by users copying those files all over around and eventually forgetting to change GUID after copying :)

Okay, let's forget that seeding idea and instead go --product-guid route.

@slonopotamus
Copy link
Contributor Author

slonopotamus commented Sep 5, 2019

For the history: #50 also doesn't want to store WXS in VCS but instead produce MSI from Cargo.toml in one go.

@volks73
Copy link
Owner

volks73 commented Sep 6, 2019

I agree, let's add some mechanism for a combined create-init command to the CLI. Should we rename this issue or create a separate one to track this feature, maybe something like "Ephemeral Builds"?

I have been thinking about the implementation of this feature and would appreciate some comments on the following:

  1. What should the name of the option be? We have discussed --product-guid option for the create (default) command, but I am actually leaning towards a new subcommand: cargo wix ephemeral <UPGRADE-CODE-GUID> <PATH-GUID> <WXS-FILE>|<CARGO-TOML>. The <UPGRADE-CODE-GUID> and <PATH-GUID> (See Item 3) would be required, while <WXS-FILE>|<CARGO-TOML> would be optional. If specified, a customized WXS file could be used, but it would need to contain the WIX variables for the Upgrade Code and path, respectively (See Item 2). This would allow users to generate a WXS file once with the cargo wix init command, customize as necessary, but store the Upgrade and Path GUIDs somewhere else. If not specified or the value is a path to a Cargo.toml file, the internal ephemeral template (See Item 2) would be used. The issue is that the GUIDs must be supplied and what is the best way to make this obvious and ergomonic?
  2. The WXS template will need to be updated to include/exclude a WIX variable for the Upgrade Code and PATH Guid so the GUIDs can be passed through the CLI.
  3. Does the PATH system environment variable need a hard-coded/explicit GUID? It was a long time ago that I developed and tested the current WXS template. I think the GUID needs to be hard-coded/explicit so that it is properly uninstalled and/or not added twice during upgrades. Then, we need to figure out how to require this value and the upgrade code GUID in the CLI and a WIX variable will need to be added for the PATH GUID.
  4. The cargo wix print subcommand will need a new flag or new template value to allow for printing of the concrete WXS template (auto-generates a GUID each time) or the ephemeral WXS template (includes the WIX variables).
  5. Does a separate ephemeral.rs source file need to be created or should the create.rs be updated with two Execution types: Concrete and Ephemeral? The answer to this question would be: Is the Builder the same for both "creation" executions?
  6. Links and information for generating GUIDs outside of cargo wix should be added to the crate's documentation. Is a cargo wix guid command needed/useful?
  7. If and when Add support for a Wix.toml manifest #20 is implemented, an ephemeral field with Upgrade Code and PATH Guid sub-fields would be needed.

Some additional comments and background:

All data that cargo wix init currently takes fron Cargo.toml can possibly change and if WXS is not meant to be regenerated, that data will need to be updated in two places.

Having to update the same information in multiple places ultimately leads to chaos.

I think the variability of the contents of the Cargo.toml file and use of a concrete WXS file is related to the timing of the project's development process and introduction of an installer. Do you want, or need, an installer during the early stages of project development when configurations, names, etc. are highly instable (changing frequently), or is an installer only needed in later, stable stages of project development? There is no right or wrong answer to this question, but currently cargo wix is only supporting the late, stable stage of development, which is mostly due to its origin story.

The subcommand came about from another project where I needed to create a Windows installer for an existing, stable project and I had several other cargo-related, stable projects that would benefit from Windows installers. I was copying-n-pasting the same WXS file over-and-over and making small modifications to the product name, upgrade code, etc. which we all agree is a source of pain and headaches. So, cargo wix was the solution to adding installers to late stage development projects.

@volks73
Copy link
Owner

volks73 commented Sep 7, 2019

I have created a new issue for artifact-free builds (#88). Please continue discussion there as I feel this issue can be closed.

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

No branches or pull requests

2 participants