Homebrew / brew

🍺 The missing package manager for macOS (or Linux)
https://brew.sh
BSD 2-Clause "Simplified" License
41.43k stars 9.75k forks source link

Allow OS conditions in formula service block #14352

Closed jfoy closed 1 year ago

jfoy commented 1 year ago

Verification

Provide a detailed description of the proposed feature

Homebrew::Service should support OS conditions such as on_linux, similar to Homebrew::Resource.

class Foo < Formula

  service do
    on_linux do
      run [opt_bin/"foo", "linux-only-subcommand"]
      environment_variables PATH: std_service_path_env
      working_dir HOMEBREW_PREFIX
    end
  end

end

This task may be as simple as adding include OnSystem::MacOSAndLinux to Homebrew::Service.

What is the motivation for the feature?

Some formulae install software that can run as a service on one OS, but not another. For example, podman installs client tools under both macOS and Linux, but also a daemon that can only start under Linux. For details, see https://github.com/Homebrew/homebrew-core/issues/118717. As a result, on macOS brew installs a service that can never start successfully.

How will the feature be relevant to at least 90% of Homebrew users?

Even with Homebrew::Service abstracting away many differences between launchd and systemd services, there is essential variation between platforms that can prevent some software from running as a service. It should be possible to support users on one OS without adding failure noise on another.

What alternatives to the feature have been considered?

Wrapping the entire service block in if OS.linux? works as desired, but fails brew audit. Other options specific to this formula are outlined in https://github.com/Homebrew/homebrew-core/issues/118717, but all run counter to the upstream project's stated intent in https://github.com/containers/podman/issues/15579#issuecomment-1302885937.

gromgit commented 1 year ago

[UNTESTED] Have you tried wrapping the service block with the conditional instead?

  on_linux do
    service do
      run [opt_bin/"foo", "linux-only-subcommand"]
      environment_variables PATH: std_service_path_env
      working_dir HOMEBREW_PREFIX
    end
  end
jfoy commented 1 year ago

Yes: as with if OS.linux?, it does what we intend but fails brew audit.

  on_linux do
    service do
      run [opt_bin/"podman", "system", "service", "--time=0"]
      environment_variables PATH: std_service_path_env
      working_dir HOMEBREW_PREFIX
    end
  end

Wrapping the service block in-place in the formula, brew audit fails with:

podman:
  * 148: col 3: `on_linux` (line 148) should be put before `resource` (line 43)
Error: 1 problem in 1 formula detected

Moving the nested on_linux+service block before the first resource block, brew audit shows:

podman:
  * 47: col 3: there can only be one `on_linux` block in a formula.
Error: 1 problem in 1 formula detected

Then moving the on_linux+service block inside the initial on_linux block:

podman:
  * 42: col 5: `on_linux` cannot include `service`. Only `livecheck`, `keg_only`, `disable!`, `deprecate!`, `depends_on`, `conflicts_with`, `fails_with`, `resource`, `patch`, `ignore_missing_libraries`, `on_intel`, `on_arm`, `on_macos`, `on_linux`, `on_system`, `on_ventura`, `on_monterey`, `on_big_sur`, `on_catalina`, `on_mojave`, `on_high_sierra`, `on_sierra`, and `on_el_capitan` are allowed.
Error: 1 problem in 1 formula detected
MikeMcQuaid commented 1 year ago

I feel like a better fix here might be some sort of :linux_only or :macos_only DSL here. @SMillerDev thoughts?

SMillerDev commented 1 year ago

I was thinking of a similar thing to shasums for casks. run macOS: bin/"php", linux: bin/"gcc" and if the hash is used without a platform that means it's unsupported.

MikeMcQuaid commented 1 year ago

@SMillerDev yeh, that'd work 👍🏻

dawidd6 commented 1 year ago

I'll try to work on that.