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

Add support for VSCodium #1560

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ Bundler for non-Ruby dependencies from Homebrew, Homebrew Cask, Mac App Store, W

[Visual Studio Code](https://code.visualstudio.com/) is optional and used for installing Visual Studio Code extensions.

[VSCodium](https://vscodium.com/) is optional and used for installing VSCodium extensions.

## Installation

`brew bundle` is automatically installed when first run.
Expand Down Expand Up @@ -69,6 +71,9 @@ whalebrew "whalebrew/wget"

# 'vscode --install-extension'
vscode "GitHub.codespaces"

# 'codium --install-extension'
vscodium "GitHub.codespaces"
Copy link
Member

Choose a reason for hiding this comment

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

Can this not just use the existing vscode? If not: why not?

```

## Versions and lockfiles
Expand All @@ -78,7 +83,7 @@ If your software needs specific pinned versions, consider [`whalebrew`](https://

## New Installers/Checkers/Dumpers

`brew bundle` currently supports Homebrew, Homebrew Cask, Mac App Store, Whalebrew and Visual Studio Code.
`brew bundle` currently supports Homebrew, Homebrew Cask, Mac App Store, Whalebrew, Visual Studio Code, and VSCodium.

We are interested in contributions for other installers/checkers/dumpers but they must:

Expand Down
10 changes: 9 additions & 1 deletion cmd/bundle.rb
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,12 @@
env: :bundle_dump_no_vscode,
description: "`dump` without VSCode extensions. " \
"This is enabled by default if `HOMEBREW_BUNDLE_DUMP_NO_VSCODE` is set."
switch "--vscodium",
description: "`list` or `dump` VSCodium extensions."

Check failure on line 99 in cmd/bundle.rb

View workflow job for this annotation

GitHub Actions / tests (ubuntu-latest)

Layout/ArgumentAlignment: Align the arguments of a method call if they span more than one line.

Check failure on line 99 in cmd/bundle.rb

View workflow job for this annotation

GitHub Actions / tests (macOS-latest)

Layout/ArgumentAlignment: Align the arguments of a method call if they span more than one line.
switch "--no-vscodium",
env: :bundle_dump_no_vscodium,

Check failure on line 101 in cmd/bundle.rb

View workflow job for this annotation

GitHub Actions / tests (ubuntu-latest)

Layout/ArgumentAlignment: Align the arguments of a method call if they span more than one line.

Check failure on line 101 in cmd/bundle.rb

View workflow job for this annotation

GitHub Actions / tests (macOS-latest)

Layout/ArgumentAlignment: Align the arguments of a method call if they span more than one line.
description: "`dump` without VSCodium extensions. " \
"This is enabled by default if `HOMEBREW_BUNDLE_DUMP_NO_VSCODIUM` is set."

Check failure on line 103 in cmd/bundle.rb

View workflow job for this annotation

GitHub Actions / tests (ubuntu-latest)

Layout/LineEndStringConcatenationIndentation: Align parts of a string concatenated with backslash.

Check failure on line 103 in cmd/bundle.rb

View workflow job for this annotation

GitHub Actions / tests (macOS-latest)

Layout/LineEndStringConcatenationIndentation: Align parts of a string concatenated with backslash.
switch "--describe",
env: :bundle_dump_describe,
description: "`dump` adds a description comment above each line, unless the " \
Expand All @@ -106,7 +112,9 @@
description: "`cleanup` casks using the `zap` command instead of `uninstall`."

conflicts "--all", "--no-vscode"
conflicts "--all", "--no-vscodium"
conflicts "--vscode", "--no-vscode"
conflicts "--vscodium", "--no-vscodium"

named_args %w[install dump cleanup check exec list]
end
Expand All @@ -129,7 +137,7 @@
force = args.force?
zap = args.zap?

no_type_args = !args.brews? && !args.casks? && !args.taps? && !args.mas? && !args.whalebrew? && !args.vscode?
no_type_args = !args.brews? && !args.casks? && !args.taps? && !args.mas? && !args.whalebrew? && !args.vscode? && !args.vscodium?

Check failure on line 140 in cmd/bundle.rb

View workflow job for this annotation

GitHub Actions / tests (ubuntu-latest)

Layout/LineLength: Line is too long. [136/118]

Check failure on line 140 in cmd/bundle.rb

View workflow job for this annotation

GitHub Actions / tests (macOS-latest)

Layout/LineLength: Line is too long. [136/118]

case subcommand
when nil, "install"
Expand Down
3 changes: 3 additions & 0 deletions lib/bundle.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,6 @@
require "bundle/vscode_extension_checker"
require "bundle/vscode_extension_dumper"
require "bundle/vscode_extension_installer"
require "bundle/vscodium_extension_checker"
require "bundle/vscodium_extension_dumper"
require "bundle/vscodium_extension_installer"
4 changes: 4 additions & 0 deletions lib/bundle/bundle.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ def vscode_installed?
@vscode_installed ||= which("code").present?
end

def vscodium_installed?
@vscodium_installed ||= which("codium").present?
end

def whalebrew_installed?
@whalebrew_installed ||= which_formula("whalebrew")
end
Expand Down
20 changes: 14 additions & 6 deletions lib/bundle/checker.rb
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,13 @@ def find_actionable(entries, exit_on_first_error: false, no_upgrade: false, verb
CheckResult = Struct.new :work_to_be_done, :errors

CHECKS = {
taps_to_tap: "Taps",
casks_to_install: "Casks",
extensions_to_install: "VSCode Extensions",
apps_to_install: "Apps",
formulae_to_install: "Formulae",
formulae_to_start: "Services",
taps_to_tap: "Taps",
casks_to_install: "Casks",
extensions_to_install: "VSCode Extensions",
vscodium_extensions_to_install: "VSCodium Extensions",
apps_to_install: "Apps",
formulae_to_install: "Formulae",
formulae_to_start: "Services",
}.freeze

def check(global: false, file: nil, exit_on_first_error: false, no_upgrade: false, verbose: false)
Expand Down Expand Up @@ -122,6 +123,13 @@ def extensions_to_install(exit_on_first_error: false, no_upgrade: false, verbose
)
end

def vscodium_extensions_to_install(exit_on_first_error: false, no_upgrade: false, verbose: false)
Bundle::Checker::VscodiumExtensionChecker.new.find_actionable(
@dsl.entries,
exit_on_first_error:, no_upgrade:, verbose:,
)
end

def formulae_to_start(exit_on_first_error: false, no_upgrade: false, verbose: false)
Bundle::Checker::BrewServiceChecker.new.find_actionable(
@dsl.entries,
Expand Down
25 changes: 25 additions & 0 deletions lib/bundle/commands/cleanup.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ def reset!
Bundle::BrewDumper.reset!
Bundle::TapDumper.reset!
Bundle::VscodeExtensionDumper.reset!
Bundle::VscodiumExtensionDumper.reset!
Bundle::BrewServices.reset!
end

Expand All @@ -26,6 +27,7 @@ def run(global: false, file: nil, force: false, zap: false, dsl: nil)
formulae = formulae_to_uninstall(global:, file:)
taps = taps_to_untap(global:, file:)
vscode_extensions = vscode_extensions_to_uninstall(global:, file:)
vscodium_extensions = vscodium_extensions_to_uninstall(global:, file:)
if force
if casks.any?
args = zap ? ["--zap"] : []
Expand All @@ -44,6 +46,10 @@ def run(global: false, file: nil, force: false, zap: false, dsl: nil)
vscode_extensions.each do |extension|
Kernel.system "code", "--uninstall-extension", extension
end

vscodium_extensions.each do |extension|
Kernel.system "codium", "--uninstall-extension", extension
end
end

cleanup = system_output_no_stderr(HOMEBREW_BREW_FILE, "cleanup")
Expand Down Expand Up @@ -75,6 +81,12 @@ def run(global: false, file: nil, force: false, zap: false, dsl: nil)
would_uninstall = true
end

if vscodium_extensions.any?
puts "Would uninstall VSCodium extensions:"
puts Formatter.columns vscodium_extensions
would_uninstall = true
end

cleanup = system_output_no_stderr(HOMEBREW_BREW_FILE, "cleanup", "--dry-run")
unless cleanup.empty?
puts "Would `brew cleanup`:"
Expand Down Expand Up @@ -180,6 +192,19 @@ def vscode_extensions_to_uninstall(global: false, file: nil)
current_extensions - kept_extensions
end

def vscodium_extensions_to_uninstall(global: false, file: nil)
@dsl ||= Brewfile.read(global:, file:)
kept_extensions = @dsl.entries.select { |e| e.type == :vscodium }.map { |x| x.name.downcase }

# To provide a graceful migration from `Brewfile`s that don't yet or
# don't want to use `vscodium`: don't remove any extensions if we don't
# find any in the `Brewfile`.
return [].freeze if kept_extensions.empty?

current_extensions = Bundle::VscodiumExtensionDumper.extensions
current_extensions - kept_extensions
end

def system_output_no_stderr(cmd, *args)
IO.popen([cmd, *args], err: :close).read
end
Expand Down
4 changes: 2 additions & 2 deletions lib/bundle/commands/dump.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
module Dump
module_function

def run(global:, file:, describe:, force:, no_restart:, taps:, brews:, casks:, mas:, whalebrew:, vscode:)
def run(global:, file:, describe:, force:, no_restart:, taps:, brews:, casks:, mas:, whalebrew:, vscode:, vscodium:)

Check failure on line 8 in lib/bundle/commands/dump.rb

View workflow job for this annotation

GitHub Actions / tests (ubuntu-latest)

Layout/LineLength: Line is too long. [122/118]

Check failure on line 8 in lib/bundle/commands/dump.rb

View workflow job for this annotation

GitHub Actions / tests (macOS-latest)

Layout/LineLength: Line is too long. [122/118]
Bundle::Dumper.dump_brewfile(
global:, file:, describe:, force:, no_restart:, taps:, brews:, casks:, mas:, whalebrew:, vscode:,
global:, file:, describe:, force:, no_restart:, taps:, brews:, casks:, mas:, whalebrew:, vscode:, vscodium:,
)
end
end
Expand Down
4 changes: 2 additions & 2 deletions lib/bundle/commands/list.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ module Commands
module List
module_function

def run(global:, file:, brews:, casks:, taps:, mas:, whalebrew:, vscode:)
def run(global:, file:, brews:, casks:, taps:, mas:, whalebrew:, vscode:, vscodium:)
parsed_entries = Brewfile.read(global:, file:).entries
Bundle::Lister.list(
parsed_entries,
brews:, casks:, taps:, mas:, whalebrew:, vscode:,
brews:, casks:, taps:, mas:, whalebrew:, vscode:, vscodium:,
)
end
end
Expand Down
6 changes: 6 additions & 0 deletions lib/bundle/dsl.rb
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,12 @@ def vscode(name)
@entries << Entry.new(:vscode, name)
end

def vscodium(name)
raise "name(#{name.inspect}) should be a String object" unless name.is_a? String

@entries << Entry.new(:vscodium, name)
end

def tap(name, clone_target = nil, options = {})
raise "name(#{name.inspect}) should be a String object" unless name.is_a? String
if clone_target && !clone_target.is_a?(String)
Expand Down
7 changes: 4 additions & 3 deletions lib/bundle/dumper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,23 @@ def can_write_to_brewfile?(brewfile_path, force: false)
true
end

def build_brewfile(describe:, no_restart:, brews:, taps:, casks:, mas:, whalebrew:, vscode:)
def build_brewfile(describe:, no_restart:, brews:, taps:, casks:, mas:, whalebrew:, vscode:, vscodium:)
content = []
content << TapDumper.dump if taps
content << BrewDumper.dump(describe:, no_restart:) if brews
content << CaskDumper.dump(describe:) if casks
content << MacAppStoreDumper.dump if mas
content << WhalebrewDumper.dump if whalebrew
content << VscodeExtensionDumper.dump if vscode
content << VscodiumExtensionDumper.dump if vscodium
"#{content.reject(&:empty?).join("\n")}\n"
end

def dump_brewfile(global:, file:, describe:, force:, no_restart:, brews:, taps:, casks:, mas:, whalebrew:,
vscode:)
vscode:, vscodium:)
path = brewfile_path(global:, file:)
can_write_to_brewfile?(path, force:)
content = build_brewfile(describe:, no_restart:, taps:, brews:, casks:, mas:, whalebrew:, vscode:)
content = build_brewfile(describe:, no_restart:, taps:, brews:, casks:, mas:, whalebrew:, vscode:, vscodium:)
write_file path, content
end

Expand Down
4 changes: 3 additions & 1 deletion lib/bundle/installer.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# frozen_string_literal: true
1# frozen_string_literal: true

Check failure on line 1 in lib/bundle/installer.rb

View workflow job for this annotation

GitHub Actions / tests (ubuntu-latest)

Lint/Void: Literal `1` used in void context.

Check failure on line 1 in lib/bundle/installer.rb

View workflow job for this annotation

GitHub Actions / tests (ubuntu-latest)

Style/FrozenStringLiteralComment: Missing frozen string literal comment.

Check failure on line 1 in lib/bundle/installer.rb

View workflow job for this annotation

GitHub Actions / tests (ubuntu-latest)

Layout/SpaceBeforeComment: Put a space before an end-of-line comment.

Check failure on line 1 in lib/bundle/installer.rb

View workflow job for this annotation

GitHub Actions / tests (macOS-latest)

Lint/Void: Literal `1` used in void context.

Check failure on line 1 in lib/bundle/installer.rb

View workflow job for this annotation

GitHub Actions / tests (macOS-latest)

Style/FrozenStringLiteralComment: Missing frozen string literal comment.

Check failure on line 1 in lib/bundle/installer.rb

View workflow job for this annotation

GitHub Actions / tests (macOS-latest)

Layout/SpaceBeforeComment: Put a space before an end-of-line comment.

module Bundle
module Installer
Expand Down Expand Up @@ -31,6 +31,8 @@
Bundle::WhalebrewInstaller
when :vscode
Bundle::VscodeExtensionInstaller
when :vscodium
Bundle::VscodiumExtensionInstaller
when :tap
verb = "Tapping"
options = entry.options
Expand Down
7 changes: 4 additions & 3 deletions lib/bundle/lister.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,20 @@ module Bundle
module Lister
module_function

def list(entries, brews:, casks:, taps:, mas:, whalebrew:, vscode:)
def list(entries, brews:, casks:, taps:, mas:, whalebrew:, vscode:, vscodium:)
entries.each do |entry|
puts entry.name if show?(entry.type, brews:, casks:, taps:, mas:, whalebrew:, vscode:)
puts entry.name if show?(entry.type, brews:, casks:, taps:, mas:, whalebrew:, vscode:, vscodium:)
end
end

def self.show?(type, brews:, casks:, taps:, mas:, whalebrew:, vscode:)
def self.show?(type, brews:, casks:, taps:, mas:, whalebrew:, vscode:, vscodium:)
return true if brews && type == :brew
return true if casks && type == :cask
return true if taps && type == :tap
return true if mas && type == :mas
return true if whalebrew && type == :whalebrew
return true if vscode && type == :vscode
return true if vscodium && type == :vscodium

false
end
Expand Down
18 changes: 18 additions & 0 deletions lib/bundle/vscodium_extension_checker.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# frozen_string_literal: true

module Bundle
module Checker
class VscodiumExtensionChecker < Bundle::Checker::Base
PACKAGE_TYPE = :vscodium
PACKAGE_TYPE_NAME = "VSCodium Extension"

def failure_reason(extension, no_upgrade:)
"#{PACKAGE_TYPE_NAME} #{extension} needs to be installed."
end

def installed_and_up_to_date?(extension, no_upgrade: false)
Bundle::VscodiumExtensionInstaller.extension_installed?(extension)
end
end
end
end
25 changes: 25 additions & 0 deletions lib/bundle/vscodium_extension_dumper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# frozen_string_literal: true

module Bundle
module VscodiumExtensionDumper
module_function

def reset!
@extensions = nil
end

def extensions
@extensions ||= if Bundle.vscodium_installed?
Bundle.exchange_uid_if_needed! do
`codium --list-extensions 2>/dev/null`
end.split("\n").map(&:downcase)
else
[]
end
end

def dump
extensions.map { |name| "vscodium \"#{name}\"" }.join("\n")
end
end
end
50 changes: 50 additions & 0 deletions lib/bundle/vscodium_extension_installer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# frozen_string_literal: true

module Bundle
module VscodiumExtensionInstaller
module_function

def reset!
@installed_extensions = nil
end

def preinstall(name, no_upgrade: false, verbose: false)
if !Bundle.vscodium_installed? && Bundle.cask_installed?
puts "Installing vscodium. It is not currently installed." if verbose
Bundle.system HOMEBREW_BREW_FILE, "install", "--cask", "vscodium", verbose:
end

if extension_installed?(name)
puts "Skipping install of #{name} VSCodium extension. It is already installed." if verbose
return false
end

raise "Unable to install #{name} VSCodium extension. VSCodium is not installed." unless Bundle.vscodium_installed?

Check failure on line 22 in lib/bundle/vscodium_extension_installer.rb

View workflow job for this annotation

GitHub Actions / tests (ubuntu-latest)

Style/IfUnlessModifier: Modifier form of `unless` makes the line too long.

Check failure on line 22 in lib/bundle/vscodium_extension_installer.rb

View workflow job for this annotation

GitHub Actions / tests (ubuntu-latest)

Layout/LineLength: Line is too long. [120/118]

Check failure on line 22 in lib/bundle/vscodium_extension_installer.rb

View workflow job for this annotation

GitHub Actions / tests (macOS-latest)

Style/IfUnlessModifier: Modifier form of `unless` makes the line too long.

Check failure on line 22 in lib/bundle/vscodium_extension_installer.rb

View workflow job for this annotation

GitHub Actions / tests (macOS-latest)

Layout/LineLength: Line is too long. [120/118]

true
end

def install(name, preinstall: true, no_upgrade: false, verbose: false, force: false)
return true unless preinstall
return true if extension_installed?(name)

puts "Installing #{name} VSCodium extension. It is not currently installed." if verbose

return false unless Bundle.exchange_uid_if_needed! do
Bundle.system("codium", "--install-extension", name, verbose:)
end

installed_extensions << name

true
end

def extension_installed?(name)
installed_extensions.include? name.downcase
end

def installed_extensions
@installed_extensions ||= Bundle::VscodiumExtensionDumper.extensions
end
end
end
8 changes: 8 additions & 0 deletions spec/bundle/commands/check_command_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,14 @@
receive(:exit_early_check).once.and_call_original
expect { do_check }.to raise_error(SystemExit)
end

it "stops checking after the first VSCodium extension" do
allow_any_instance_of(Pathname).to receive(:read).and_return("vscodium 'abc'\nvscodium 'def'")

expect_any_instance_of(Bundle::Checker::VscodiumExtensionChecker).to \
receive(:exit_early_check).once.and_call_original
expect { do_check }.to raise_error(SystemExit)
end
end

context "when a new checker fails to implement installed_and_up_to_date" do
Expand Down
Loading
Loading