Module: Shadwire::Binstub

Defined in:
lib/shadwire/binstub.rb

Overview

The canonical entry point a consuming app uses to run the CLI: bin/shadwire.

The template is the shape Rails 8 generates for bin/rubocop and bin/brakeman, so the file reads as native to the app it lands in. Being a bundler binstub, it only works once gem "shadwire" is declared in the app's Gemfile — Commands::Init gates the write on that, because a binstub written without it raises Gem::LoadError on first run.

Deliberately not routed through Installer: that writes published registry entries tracked in shadwire.json, and it never sets an execute bit.

Constant Summary collapse

PATH =
"bin/shadwire"
MODE =
0o755
TEMPLATE =
<<~RUBY
  #!/usr/bin/env ruby
  # frozen_string_literal: true
  require "rubygems"
  require "bundler/setup"
  load Gem.bin_path("shadwire", "shadwire")
RUBY
GEM =

The gem that backs the binstub. init adds it, status reports it.

"shadwire"

Class Method Summary collapse

Class Method Details

.exist?(root) ⇒ Boolean

Returns:

  • (Boolean)


32
33
34
# File 'lib/shadwire/binstub.rb', line 32

def self.exist?(root)
  File.exist?(File.join(root.to_s, PATH))
end

.write(root, force: false) ⇒ Hash

Writes bin/shadwire unless it already exists.

An existing binstub is left alone: bundle binstubs shadwire produces a different, working file, and it is not tracked in shadwire.json, so shadwire diff could never report that we replaced it.

Parameters:

  • root (String, Pathname)

    the consuming app root

  • force (Boolean) (defaults to: false)

    rewrite an existing binstub

Returns:

  • (Hash)

    { written: Boolean, skipped: Boolean }



45
46
47
48
49
50
51
52
53
# File 'lib/shadwire/binstub.rb', line 45

def self.write(root, force: false)
  path = Pathname(root).join(PATH)
  return { written: false, skipped: true } if path.exist? && !force

  FileUtils.mkdir_p(path.dirname)
  path.write(TEMPLATE)
  path.chmod(MODE)
  { written: true, skipped: false }
end