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

gitversion: downgrade, use mono. #53092

Merged
merged 1 commit into from
Apr 14, 2020
Merged

gitversion: downgrade, use mono. #53092

merged 1 commit into from
Apr 14, 2020

Conversation

MikeMcQuaid
Copy link
Member

The current version uses a macOS binary which is forbidden in homebrew/core.

This will likely fail CI due to being a downgrade but we don't want to intentionally downgrade anyone.

CC @Bo98 as we talked about this formula.

  • Have you followed the guidelines for contributing?
  • Have you checked that there aren't other open pull requests for the same formula update/change?
  • Have you built your formula locally with brew install --build-from-source <formula>, where <formula> is the name of the formula you're submitting?
  • Is your test running fine brew test <formula>, where <formula> is the name of the formula you're submitting?
  • Does your build pass brew audit --strict <formula> (after doing brew install <formula>)?

@Bo98
Copy link
Member

Bo98 commented Apr 13, 2020

This makes sense for now. I think it's time for me to try tackle .NET Core since that's what is preventing us building this from source.

uses_from_macos "icu4c"

def install
libexec.install Dir["*"]
(bin/"gitversion").write <<~EOS
#!/bin/sh
exec "#{libexec}/GitVersion" "$@"
exec "#{Formula["mono"]/opt_bin}/mono" "#{libexec}/GitVersion.exe" "$@"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
exec "#{Formula["mono"]/opt_bin}/mono" "#{libexec}/GitVersion.exe" "$@"
exec "#{Formula["mono"].opt_bin}/mono" "#{libexec}/GitVersion.exe" "$@"

The current version uses a macOS binary which is forbidden in
homebrew/core.

This will likely fail CI due to being a downgrade but we don't want to
intentionally downgrade anyone.
@SMillerDev SMillerDev added the ready to merge PR can be merged once CI is green label Apr 14, 2020
@MikeMcQuaid MikeMcQuaid merged commit 5d08c09 into Homebrew:master Apr 14, 2020
@MikeMcQuaid MikeMcQuaid deleted the gitversion branch April 14, 2020 10:44
@asbjornu
Copy link
Contributor

asbjornu commented Jul 7, 2020

In @GitTools we are discussing how to keep the GitVersion formulae in Homebrew up to date with every release and are wondering what the grounds for this argument is:

The current version uses a macOS binary which is forbidden in homebrew/core.

@MikeMcQuaid, can you please point to where this is forbidden that also explain why? We are providing a self-contained macOS binary that doesn't require Mono or .NET Core installed, both of which I doubt most macOS users ever will want to install. Isn't it better to provide a dependency-free binary than one which requires a full installation of Mono or .NET Core?

@SMillerDev
Copy link
Member

can you please point to where this is forbidden that also explain why? We are providing a self-contained macOS binary that doesn't require Mono or .NET Core installed, both of which I doubt most macOS users ever will want to install. Isn't it better to provide a dependency-free binary than one which requires a full installation of Mono or .NET Core?

https://docs.brew.sh/Acceptable-Formulae#we-dont-like-binary-formulae

@Bo98
Copy link
Member

Bo98 commented Jul 7, 2020

one which requires a full installation of Mono or .NET Core

It is possible to have them build-only dependencies so that installing from a bottle does not require those dependencies.

I tried to get .NET Core in Homebrew/core to help here. Unfortunately .NET Core's source build system is not yet in a state suitable for Homebrew/core but we would consider a system that used the Cask .NET Core (like we do for osxfuse etc.). This shouldn't be too difficult to do.

@MikeMcQuaid
Copy link
Member Author

See also: https://github.com/Homebrew/brew/blob/99aee978568f0b104c070967d001af4c8a8fdc89/Library/Homebrew/rubocops/urls.rb#L274-L283.

This automated check will fail if you add binaries with osx in the URL.

We are providing a self-contained macOS binary that doesn't require Mono or .NET Core installed, both of which I doubt most macOS users ever will want to install. Isn't it better to provide a dependency-free binary than one which requires a full installation of Mono or .NET Core?

Open source binary package managers (e.g. Debian) want to build our own binaries and distribute them to users rather than having upstream do so. Package managers do not like "dependency-free binaries" because they aren't "dependency-free" but instead are "we have bundled all the dependencies into the binary". If there's a critical security vulnerability in Mono: we update Mono and everything depending on it receives the security update. If we have "dependency-free binaries" they all need rebuilt, redistributed and reinstalled before anyone will receive any security updates.

Additionally, we (Homebrew) target both macOS and Linux now so binaries built for a single OS are not suitable for us.

Unfortunately .NET Core's source build system is not yet in a state suitable for Homebrew/core but we would consider a system that used the Cask .NET Core (like we do for osxfuse etc.). This shouldn't be too difficult to do.

Sorry to contract you here @Bo98 but we wouldn't accept formulae in Homebrew/homebrew-core that are dependent on new casks (i.e. those that aren't already installed on our CI machines).

@Bo98
Copy link
Member

Bo98 commented Jul 7, 2020

Sorry to contract you here @Bo98 but we wouldn't accept formulae in Homebrew/homebrew-core that are dependent on new casks (i.e. those that aren't already installed on our CI machines).

Apologies - I think I must have misremembered a previous conversation about it from a few months ago.

@asbjornu
Copy link
Contributor

asbjornu commented Jul 7, 2020

@SMillerDev, thanks for the reference. By this argument, I can't see why the GitVersion formulae is permitted to exist at all, since it includes a binary regardless of being self-contained or not. Even in this very PR, a reference is made to https://github.com/GitTools/GitVersion/releases/download/5.0.1/GitVersion-bin-fullfx-v5.0.1.zip, which only contains pre-built binaries.

@Bo98:
It is possible to have them build-only dependencies so that installing from a bottle does not require those dependencies.

.NET Core is a runtime and needs to be installed just like Mono for the setup the GitVersion formulae has now to work. To work in as a build-only dependency, we would have to replicate building of a self-contained macOS binary within Homebrew somehow. Why is that preferable to GitVersion doing this in our own CI/CD pipeline?

@MikeMcQuaid:
Package managers do not like "dependency-free binaries" because they aren't "dependency-free" but instead are "we have bundled all the dependencies into the binary". If there's a critical security vulnerability in Mono: we update Mono and everything depending on it receives the security update. If we have "dependency-free binaries" they all need rebuilt, redistributed and reinstalled before anyone will receive any security updates.

That's a good point.

Additionally, we (Homebrew) target both macOS and Linux now so binaries built for a single OS are not suitable for us.

Another good point. Would moving GitVersion to a cask be the way to go, then?

@MikeMcQuaid
Copy link
Member Author

thanks for the reference. By this argument, I can't see why the GitVersion formulae is permitted to exist at all, since it includes a binary regardless of being self-contained or not

Did you read it?

either built from source or produce cross-platform binaries (e.g. Java, Mono)

These are cross-platform binaries hence the mono dependency, no?

Why is that preferable to GitVersion doing this in our own CI/CD pipeline?

Because open source system package managers don't redistribute upstream binaries. We are not alone in this.

Another good point. Would moving GitVersion to a cask be the way to go, then?

No, I don't think so if it can be made to be built from source. If it can be but won't be: a tap may be a good option for users to get the latest versions.

@asbjornu
Copy link
Contributor

asbjornu commented Jul 7, 2020

Thanks for the answers, @MikeMcQuaid.

Did you read it?

Yes, but now that you pushed me to read it again, I noticed:

or produce cross-platform binaries (e.g. Java, Mono)

… which in combination with:

we (Homebrew) target both macOS and Linux now

… explains everything.

These are cross-platform binaries hence the mono dependency, no?

Correct.

Another good point. Would moving GitVersion to a cask be the way to go, then?

No, I don't think so if it can be made to be built from source. If it can be but won't be: a tap may be a good option for users to get the latest versions.

Would keeping the current formulae, but changing the dependency to .NET Core be a better way forward, then?

@MikeMcQuaid
Copy link
Member Author

… explains everything.

Great 👍

Would keeping the current formulae, but changing the dependency to .NET Core be a better way forward, then?

That seems ideal to me. We'll need to figure out a way to get .NET Core packaged in homebrew-core eventually.

@arturcic
Copy link
Contributor

arturcic commented Jul 7, 2020

.NET core is a better option indeed.

.NET Core packaged in homebrew-core eventually.

What are the options to have the .NET core as dependency before it's available in homebrew-core?

@MikeMcQuaid
Copy link
Member Author

Someone submitting a PR to add it will have to happen for this. #3691 was the last previous version I can find. @Bo98 may be able to provide other thoughts on what may need to be done.

@asbjornu
Copy link
Contributor

asbjornu commented Jul 7, 2020

Thanks for the pointer, @MikeMcQuaid! From my reading, we should be able to fix most of the issues in that PR by submitting a new formulae with a newer version of .NET Core.

How do you deal with simultaneous different versions of the same formulae, by the way? I expect that people would like there to exist more than just the latest version of .NET Core in Homebrew; at least the last two major versions should probably be available, if not more. Thoughts?

I'll also await @Bo98's input before submitting a PR.

@MikeMcQuaid
Copy link
Member Author

Thanks for the pointer, @MikeMcQuaid! From my reading, we should be able to fix most of the issues in that PR by submitting a new formulae with a newer version of .NET Core.

Hope so!

How do you deal with simultaneous different versions of the same formulae, by the way? I expect that people would like there to exist more than just the latest version of .NET Core in Homebrew; at least the last two major versions should probably be available, if not more. Thoughts?

https://docs.brew.sh/Versions should clarify most of it. The TL;DR for this case would be: it's worth just adding the latest version and we can consider other versions when they are needed.

@asbjornu
Copy link
Contributor

asbjornu commented Aug 5, 2020

I've made some progress on a dotnet formula, but as it requires building from a Git clone, a downloadable .tar.gz is not really a suitable way to retrieve the source code. Can you please elaborate what you mean by this comment, @MikeMcQuaid?

Still better to use a GitHub checkout here and it'll remove the need for the patch.

Is it possible to use "GitHub checkout" without ending up with a "head only formula"? If it is, how?

@SMillerDev
Copy link
Member

Look for formula defining the url as something.git and have a tag and a revision.

@MikeMcQuaid
Copy link
Member Author

I've made some progress on a dotnet formula, but as it requires building from a Git clone, a downloadable .tar.gz is not really a suitable way to retrieve the source code.

Is that because submodules are used/needed or some other reason?

Can you please elaborate what you mean by this comment, @MikeMcQuaid?

Ignore that: it was (almost) four years ago and related to it being a preview tarball which was then patched.

@MikeMcQuaid
Copy link
Member Author

Is that because submodules are used/needed or some other reason?

I caught up on this from dotnet/sdk#11795. What a mess! Yeh, no worries.

Just to let you know: this formula may need some hacks to get it working and I'm fine with that (as long as we let upstream know about them so they can change them in future, hopefully).

@asbjornu
Copy link
Contributor

asbjornu commented Aug 7, 2020

Look for formula defining the url as something.git and have a tag and a revision.

The problem with that, is that without a url, the Formula will be uninstallable without the --HEAD argument and I don't even know how it will affect dependent formulae.

I've made some progress on a dotnet formula, but as it requires building from a Git clone, a downloadable .tar.gz is not really a suitable way to retrieve the source code.

Is that because submodules are used/needed or some other reason?

There are submodules, but while they are not required, they are highly recommended in order to get valuable source information into the build. More importantly, until dotnet/source-build#1695 is released, build.sh requires .git in order to not bomb completely.

Can you please elaborate what you mean by this comment, @MikeMcQuaid?

Ignore that: it was (almost) four years ago and related to it being a preview tarball which was then patched.

Ok.

I caught up on this from dotnet/sdk#11795. What a mess! Yeh, no worries.

😅 👍

Just to let you know: this formula may need some hacks to get it working and I'm fine with that (as long as we let upstream know about them so they can change them in future, hopefully).

Thanks, much appreciated. Now that dotnet/source-build#1646 was closed without actually resolving dotnet/source-build#1646 (comment), we don't have a tarball with source information available.

This means the build needs to be started with a lot of flags that attempts to circumvent the fact that it is not being done on a Git clone. In other words:

  1. Building dotnet from anything but a git clone leads to a sub-optimal result.
  2. The .NET team does not seem willing to offer a tarball with a .git directory and initialized submodules.

Because of this, the best option seems to be to somehow do a git clone of a tag and revision and not offer a url. Is this possible without ending up with a "head only" formula?

@SMillerDev
Copy link
Member

The problem with that, is that without a url, the Formula will be uninstallable without the --HEAD argument and I don't even know how it will affect dependent formulae.

It will, look at https://github.com/Homebrew/homebrew-core/blob/master/Formula/cling.rb#L4-L6

@MikeMcQuaid
Copy link
Member Author

There are submodules, but while they are not required, they are highly recommended in order to get valuable source information into the build. More importantly, until dotnet/source-build#1695 is released, build.sh requires .git in order to not bomb completely.

Cool, fine with me. If there's submodules: it makes sense to use them, too.

  • Building dotnet from anything but a git clone leads to a sub-optimal result.

This is fine. See @SMillerDev's pointer above on an example formula that does this.

@asbjornu
Copy link
Contributor

asbjornu commented Aug 7, 2020

The problem with that, is that without a url, the Formula will be uninstallable without the --HEAD argument and I don't even know how it will affect dependent formulae.

It will, look at https://github.com/Homebrew/homebrew-core/blob/master/Formula/cling.rb#L4-L6

Ah, I didn't know the url method had that capability – I thought you had to use head in order to do a git clone. Awesome!

@asbjornu
Copy link
Contributor

asbjornu commented Aug 7, 2020

Yay! I finally have a working build. The final part to nail down is installation. As far as I understand the build instructions, the build should produce a file named something like artifacts/x64/Release/dotnet-sdk-3.1.106-macos.x64.tar.gz as per the specification artifacts/${ARCHITECTURE}/Release/dotnet-sdk-${SDK_VERSION}-${RUNTIME_ID}.tar.gz.

Given the successfully built tarball, what must happen, is:

  1. The tarball must be extracted somewhere.
  2. A symlink for the dotnet executable must be created.
  3. The file /etc/dotnet/install_location must be created with the path from step 1.
  4. The environment variable DOTNET_ROOT must be defined.

I'm not clear on exactly how the build has been performed by running brew install --verbose --debug dotnet. What's logged in the console references paths such as /private/tmp/dotnet-20200807-8016-1m7ouwu/ which doesn't seem to exist. This and a few other unclear things leaves me with the following questions:

  1. Can I find the build output somewhere without running the entire thing again (it took over 3 hours to complete)?
  2. Does Homebrew have variables I can substitute for the ones in the path to the tarball? (${ARCHITECTURE}, ${SDK_VERSION} and ${RUNTIME_ID})
  3. How do I figure out the path to where the tarball should be extracted to and how exactly should I extract it inside the Formula?
  4. Given how long the build takes, should the formula be built into a bottle, and if so, what should I do in the formula to ensure that happens?

@asbjornu
Copy link
Contributor

asbjornu commented Aug 7, 2020

Another question, as I discovered depends_on :x11, could something similar be done for this dotnet formula as well? I expect that the .NET SDK may be installed with Microsoft's installer and not through Homebrew, so it would be neat if dependent formulae could use an existing dotnet installation, regardless of through which means it was installed.

@gromgit
Copy link
Member

gromgit commented Aug 8, 2020

What's logged in the console references paths such as /private/tmp/dotnet-20200807-8016-1m7ouwu/ which doesn't seem to exist.

Homebrew builds in disposable sandboxes, hence the odd paths you're seeing.

Can I find the build output somewhere without running the entire thing again (it took over 3 hours to complete)?

Look in ~/Library/Logs/Homebrew/mono/ for the build logs, but the tarball is long gone. Build it again with brew install --build-from-source --keep-tmp, then the build sandbox will not be automatically removed at the end.

Does Homebrew have variables I can substitute for the ones in the path to the tarball? (${ARCHITECTURE}, ${SDK_VERSION} and ${RUNTIME_ID})

If you just need the values to construct the path, there's an easier way that leverages on the fact that builds happen in a sandbox, and therefore There Should Be Only One Tarball: Dir["artifacts/*/*.tar.gz"]

How do I figure out the path to where the tarball should be extracted to

Use the relevant variables here: https://docs.brew.sh/Formula-Cookbook#just-moving-some-files

how exactly should I extract it inside the Formula

system "tar", "xf", ... seems about right.

Given how long the build takes, should the formula be built into a bottle, and if so, what should I do in the formula to ensure that happens?

That happens automagically during pull request CI, so you don't have to worry about it.


Since you seem to be new to Homebrew formula building, you should probably spend some time reading https://docs.brew.sh/Formula-Cookbook.

@gromgit
Copy link
Member

gromgit commented Aug 8, 2020

as I discovered depends_on :x11, could something similar be done for this dotnet formula as well?

Don't use that unless absolutely necessary, especially if that causes the build script to build an X11 GUI instead of a native one.

it would be neat if dependent formulae could use an existing dotnet installation, regardless of through which means it was installed

There are no optional dependencies permitted in homebrew/core formulae, so this is not gonna happen. All formulae that depend on .NET will declare, and be irrevocably tied to, the mono formula.

What you suggest also makes CI testing pointless; when users can point to any .NET version that they installed via other means and say "use that", then scream to high heaven when formulae break, why waste the time and effort?

@asbjornu
Copy link
Contributor

asbjornu commented Aug 8, 2020

Build it again with brew install --build-from-source --keep-tmp, then the build sandbox will not be automatically removed at the end.

Excellent, thanks.

If you just need the values to construct the path, there's an easier way that leverages on the fact that builds happen in a sandbox, and therefore There Should Be Only One Tarball: Dir["artifacts/*/*.tar.gz"]

Good point. 👍

How do I figure out the path to where the tarball should be extracted to

Use the relevant variables here: https://docs.brew.sh/Formula-Cookbook#just-moving-some-files

I'm now doing the following, which I hope both works and is correct:

system "tar", "-xzf", Dir["artifacts/*/*.tar.gz"], "--directory", lib

That happens automagically during pull request CI, so you don't have to worry about it.

Brilliant!

Since you seem to be new to Homebrew formula building, you should probably spend some time reading https://docs.brew.sh/Formula-Cookbook.

I've read it quite thoroughly, but things like --keep-tmp and other advanced (at least imho) topics aren't covered very well.

as I discovered depends_on :x11, could something similar be done for this dotnet formula as well?

Don't use that unless absolutely necessary, especially if that causes the build script to build an X11 GUI instead of a native one.

Sorry for being unclear. What I meant was that it would perhaps be a good idea to declare the dotnet formula I'm working on the same way :java is available as a symbol formula, which as far as I can understand, means Java just needs to exist on the PATH and doesn't have to be installed by Homebrew.

There are no optional dependencies permitted in homebrew/core formulae, so this is not gonna happen. All formulae that depend on .NET will declare, and be irrevocably tied to, the mono formula.

I was thinking of allowing formulae dependent on .NET to declare :dotnet the same way formulae can declare :java, such as in the couchdb-lucene formula:

depends_on java: "1.8"

What you suggest also makes CI testing pointless; when users can point to any .NET version that they installed via other means and say "use that", then scream to high heaven when formulae break, why waste the time and effort?

That's a good point, but since it's not possible to declare version dependencies, isn't this the case whenever a formula is upgraded already? Or will a formula upgrade be rejected if any dependent formulae break in the CI tests?

@asbjornu
Copy link
Contributor

asbjornu commented Aug 9, 2020

Thanks to --keep-tmp I've now inspected the contents of /private/tmp/dotnet-20200808-51698-1ahymh4/artifacts/x64/Release, which is:

drwxr-xr-x  10 aul  admin        320 Aug  9 01:21 .
drwxr-xr-x   3 aul  admin         96 Aug  8 21:22 ..
-rw-r--r--   1 aul  admin  206313141 Aug  9 01:21 Private.SourceBuilt.Artifacts.0.1.0-dev.tar.gz
-rw-r--r--   1 aul  admin      36621 Aug  8 21:23 SourceBuild.MSBuildSdkResolver.deps.json
-rw-r--r--   1 aul  staff      10752 Aug  8 21:23 SourceBuild.MSBuildSdkResolver.dll
-rw-r--r--   1 aul  staff       2024 Aug  8 21:23 SourceBuild.MSBuildSdkResolver.pdb
-rw-r--r--   1 aul  admin  102868642 Aug  9 01:21 dotnet-sdk-3.1.106-osx-x64.tar.gz
-rw-r--r--   1 aul  admin   54720227 Aug  9 01:21 dotnet-sdk-internal-3.1.106-osx-x64.tar.gz
drwxr-xr-x   2 aul  admin         64 Aug  9 00:35 netcorecli-fsc
drwxr-xr-x  15 aul  admin        480 Aug  9 01:01 runtime

Also, if I do find ./artifacts -iname '*.tar.gz', I get the following list of .tar.gz files:

./artifacts/obj/x64/Release/blob-feed/assets/dotnet-runtime-3.1.6-osx-x64.tar.gz
./artifacts/obj/x64/Release/blob-feed/assets/dotnet-nethost-3.1.6-osx-x64.tar.gz
./artifacts/obj/x64/Release/blob-feed/assets/dotnet-runtime-internal-3.1.6-osx-x64.tar.gz
./artifacts/obj/x64/Release/blob-feed/assets/dotnet-hostfxr-internal-osx-x64.3.1.6.tar.gz
./artifacts/obj/x64/Release/blob-feed/assets/dotnet-runtime-symbols-3.1.6-osx-x64.tar.gz
./artifacts/obj/x64/Release/blobs/aspnetcore/Runtime/3.1.6/aspnetcore-runtime-internal-3.1.6-osx-x64.tar.gz
./artifacts/obj/x64/Release/blobs/Runtime/3.1.6/dotnet-runtime-3.1.6-osx-x64.tar.gz
./artifacts/obj/x64/Release/blobs/Runtime/3.1.6/dotnet-runtime-internal-3.1.6-osx-x64.tar.gz
./artifacts/obj/x64/Release/blobs/Runtime/3.1.6/dotnet-hostfxr-internal-osx-x64.3.1.6.tar.gz
./artifacts/obj/x64/Release/blobs/Runtime/3.1.6/dotnet-runtime-symbols-3.1.6-osx-x64.tar.gz
./artifacts/obj/x64/Release/external-tarballs/Private.SourceBuild.ReferencePackages.1.0.0-beta.20278.2.tar.gz
./artifacts/x64/Release/dotnet-sdk-internal-3.1.106-osx-x64.tar.gz
./artifacts/x64/Release/runtime/dotnet-runtime-3.1.6-osx-x64.tar.gz
./artifacts/x64/Release/runtime/dotnet-nethost-3.1.6-osx-x64.tar.gz
./artifacts/x64/Release/runtime/dotnet-runtime-internal-3.1.6-osx-x64.tar.gz
./artifacts/x64/Release/runtime/dotnet-hostfxr-internal-osx-x64.3.1.6.tar.gz
./artifacts/x64/Release/runtime/dotnet-runtime-symbols-3.1.6-osx-x64.tar.gz
./artifacts/x64/Release/Private.SourceBuilt.Artifacts.0.1.0-dev.tar.gz
./artifacts/x64/Release/dotnet-sdk-3.1.106-osx-x64.tar.gz
./artifacts/src/installer.0f94483edc7cae71ffc34a2c8e8f0a54534e331f/artifacts/obj/redist/Release/downloads/dotnet-runtime-3.1.6-osx-x64.tar.gz
./artifacts/src/installer.0f94483edc7cae71ffc34a2c8e8f0a54534e331f/artifacts/obj/redist/Release/downloads/aspnetcore-runtime-internal-3.1.6-osx-x64.tar.gz
./artifacts/src/installer.0f94483edc7cae71ffc34a2c8e8f0a54534e331f/artifacts/packages/Release/Shipping/dotnet-sdk-internal-3.1.106-osx-x64.tar.gz
./artifacts/src/installer.0f94483edc7cae71ffc34a2c8e8f0a54534e331f/artifacts/packages/Release/Shipping/dotnet-sdk-3.1.106-osx-x64.tar.gz
./artifacts/src/aspnetcore.62c098bc170f50feca15916e81cb7f321ffc52ff/artifacts/installers/Release/aspnetcore-runtime-internal-3.1.6-osx-x64.tar.gz

So, unfortunately, there isn't just one .tar.gz file. Do you have any good ideas on how to dig out the needle ./artifacts/x64/Release/dotnet-sdk-3.1.106-osx-x64.tar.gz in this haystack somehow, without knowing the exact path and filename?

@gromgit
Copy link
Member

gromgit commented Aug 9, 2020

Do you have any good ideas on how to dig out the needle ./artifacts/x64/Release/dotnet-sdk-3.1.106-osx-x64.tar.gz in this haystack somehow, without knowing the exact path and filename?

Dir["artifacts/*/Release/dotnet-sdk-*.tar.gz"] should do it.

@gromgit
Copy link
Member

gromgit commented Aug 9, 2020

Disclaimer: I'm not a Homebrew maintainer. Everything below is based on my own continuing observations of how Homebrew pull requests are resolved, and my own experiences in dealing with software upgrades and breakages.

since it's not possible to declare version dependencies, isn't this the case whenever a formula is upgraded already? Or will a formula upgrade be rejected if any dependent formulae break in the CI tests?

The current CI testing process for a formula includes testing all dependents of said formula against the new build, and all test failures must be addressed before the upgrade goes through. This is why version bumps of foundational formulae like openjdk can be very involved, as it often exposes fragile assumptions in the dependent formulae.

But once those are addressed, the overall state of "evergreen" Homebrew becomes that much more robust. For instance, Go's recent version bump (#59242) is relatively quiet, likely because the major dependent formulae issues were ironed out in earlier bumps (#55639 and especially #51909).

This is likely why the preferred dependency declaration for Java-based formulae (I count 170 at this writing) is openjdk, while I'd expect java: "1.8" (61) to be gradually phased out, as dependent formulae are either updated to compatibility with openjdk (5 in the last month), or deprecated out of existence.

This is also why I doubt a dotnet: "x.y" declaration will be accepted at this stage. There would have to be a show-stopping reason to introduce any broad dependency stanza at this late stage of Homebrew evolution.

@asbjornu
Copy link
Contributor

asbjornu commented Aug 9, 2020

Thanks for your thorough explanation, @gromgit. It makes perfectly sense.

@MikeMcQuaid
Copy link
Member Author

Sorry for being unclear. What I meant was that it would perhaps be a good idea to declare the dotnet formula I'm working on the same way :java is available as a symbol formula, which as far as I can understand, means Java just needs to exist on the PATH and doesn't have to be installed by Homebrew.

We used to do this more in Homebrew but it was a bad idea because we have no way of testing/verifying what formulae work with what versions of dependencies. I'm afraid we won't be going back to this approach.

Or will a formula upgrade be rejected if any dependent formulae break in the CI tests?

This, exactly.

So, unfortunately, there isn't just one .tar.gz file. Do you have any good ideas on how to dig out the needle ./artifacts/x64/Release/dotnet-sdk-3.1.106-osx-x64.tar.gz in this haystack somehow, without knowing the exact path and filename?

I'd suggest that the filename can probably be inferred instead? Something like "./artifacts/x64/Release/dotnet-sdk-#{version}-osx-x64.tar.gz"? It's probably preferable to be hardcoded (somewhat) based on the version of the formula so that it fails if this naming scheme changes on a version bump.

@asbjornu
Copy link
Contributor

We used to do this more in Homebrew but it was a bad idea because we have no way of testing/verifying what formulae work with what versions of dependencies. I'm afraid we won't be going back to this approach.

I see. Thanks for explaining.

I'd suggest that the filename can probably be inferred instead? Something like "./artifacts/x64/Release/dotnet-sdk-#{version}-osx-x64.tar.gz"?

Yep, I came to the same conclusion by looking at a few other formulae and now have this:

tarball = Dir["artifacts/*/Release/dotnet-sdk-#{version}-*.tar.gz"].first
system "tar", "-xzf", tarball, "--directory", lib

There's a problem, though. The command fails with:

tar: could not chdir to '/usr/local/Cellar/dotnet/3.1.106/lib'

Is this because sudo is required, or that the folder doesn't exist? I understand the recommended way to move files into the lib directory would be to do lib.install, but since the files I want to move are inside a tarball, I don't think I can use lib.install directly without first extracting the tarball.

I see other formulae extracting first, but they also seem to contain much less than the tarball I'm working with here. It would be awesome if the various .install methods optionally could extract an archive into the target directory so I could just write:

lib.install Dir["artifacts/*/Release/dotnet-sdk-#{version}-*.tar.gz"].first, extract: true

Until something like that is available, I suppose I will have to extract it into another folder first and then installing from there? Not the most effective way to install this many files, but whatever works, I suppose.

@gromgit
Copy link
Member

gromgit commented Aug 11, 2020

tar: could not chdir to '/usr/local/Cellar/dotnet/3.1.106/lib'

tar expects its target directory to exist, so you'd have to mkdir lib.to_s first.

@asbjornu
Copy link
Contributor

tar expects its target directory to exist, so you'd have to mkdir lib.to_s first.

Ah, of course. I'll do that. Thanks!

@MikeMcQuaid
Copy link
Member Author

tar expects its target directory to exist, so you'd have to mkdir lib.to_s first.

lib.mkpath preferably.

@asbjornu
Copy link
Contributor

Thanks for all help! I'm now very close to a working formula. install works, but as .NET has a few environmental requirements I'm struggling to accommodate, post_install and test fails. The requirements are:

  1. The file /etc/dotnet/install_location needs to be created containing the path to the lib directory.
  2. The environment variable DOTNET_ROOT must exist and point to the same lib directory path.
  3. Dependencies such as icu4c needs to be made available to .NET through the LD_LIBRARY_PATH environment variable, for instance.

Point 1 is impossible since writing to /etc requires sudo, afaict. Point 2 and 3 also seems impossible since a formula can't declare environment variables.

Should I just write up instructions for how to do this in a caveats section, or can we accommodate these requirements in any way within the formula? Can a formula conditionally ask for sudo for certain actions, or can it define a custom post_install that can be run with sudo from the command line?

@SMillerDev
Copy link
Member

I think all of this should be a caveat. We definitely don't want to ask for sudo from users.

Additionally, I think an issue should be created to notify upstream of the /etc problem.

@asbjornu
Copy link
Contributor

Thanks, @SMillerDev. I noticed, however, that with icu4c installed, its .dylibs aren't symlinked from /usr/local/bin. Perhaps with them linked, the dotnet binary may execute successfully. I don't know, but it would be interesting to know why the symlinks are missing and whether their precense would help.

@MikeMcQuaid
Copy link
Member Author

Well done @asbjornu, thanks for all your work on this!

Should I just write up instructions for how to do this in a caveats section, or can we accommodate these requirements in any way within the formula?

I think we should patch out the /etc requirement and submit that patch upstream.

  • The environment variable DOTNET_ROOT must exist and point to the same lib directory path.

We can use wrapper scripts if needed to set these. We don't want users to have to do so manually.

3. Dependencies such as icu4c needs to be made available to .NET through the LD_LIBRARY_PATH environment variable, for instance.

It won't be LD_LIBRARY_PATH on macOS. I'd think rpath can probably handle this for us (perhaps automatically/as-is, perhaps manually) on Linux.

Perhaps with them linked, the dotnet binary may execute successfully. I don't know, but it would be interesting to know why the symlinks are missing and whether their precense would help.

This should be able to be worked around by using rpath. Even having them linked won't help because the installation won't always be /usr/local (and won't be on Linux).

@asbjornu asbjornu mentioned this pull request Sep 10, 2020
5 tasks
@asbjornu
Copy link
Contributor

Thanks for all the help! #60929 is hereby submitted.

@MikeMcQuaid
Copy link
Member Author

And: it shipped!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ready to merge PR can be merged once CI is green
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants