brew 0.1.0 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,138 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'brew/utils/string_utils'
4
+ require 'brew/utils/system_runner'
5
+
6
+ module Brew
7
+ module Commands
8
+ class Install
9
+ attr_reader :brew_path, :formulae, :options, :system_runner
10
+
11
+ def initialize(brew_path, *formulae, **kwargs)
12
+ @brew_path = brew_path
13
+ @formulae = formulae.join(' ')
14
+ @options = parse_args(kwargs)
15
+ @system_runner = SystemRunner.new
16
+ end
17
+
18
+ def execute!
19
+ install_command = "#{brew_path} install #{options} #{formulae}".squish
20
+ system_runner.print_output(install_command)
21
+ rescue StandardError => e
22
+ raise Brew::ExecutionError, e
23
+ end
24
+
25
+ private
26
+
27
+ BOOLEAN_OPTIONS = %i[
28
+ ignore_dependencies build_from_source force_bottle
29
+ include_test devel HEAD fetch_HEAD keep_tmp
30
+ build_bottle force verbose display_times git
31
+ ].freeze
32
+
33
+ ARGUMENT_OPTIONS = %i[
34
+ env only_dependencies cc bottle_arch
35
+ ].freeze
36
+
37
+ def parse_args(args)
38
+ option_list = []
39
+
40
+ BOOLEAN_OPTIONS.each do |option|
41
+ str_option = option.to_s
42
+ kebab_option = str_option.snake_to_kebab
43
+ option_list << "--#{kebab_option}" if args[option] || args[str_option] || args[kebab_option]
44
+ end
45
+
46
+ ARGUMENT_OPTIONS.each do |option|
47
+ str_option = option.to_s
48
+ kebab_option = str_option.snake_to_kebab
49
+ if (value = args[option] || args[str_option] || args[kebab_option])
50
+ option_list << "--#{kebab_option} #{value}"
51
+ end
52
+ end
53
+
54
+ option_list.join(' ')
55
+ end
56
+ end
57
+ end
58
+ end
59
+
60
+ # Usage: brew install [options] formula
61
+
62
+ # Install formula. Additional options specific to formula may be appended to
63
+ # the command.
64
+
65
+ # Unless HOMEBREW_NO_INSTALL_CLEANUP is set, brew cleanup will then be run for
66
+ # the installed formulae or, every 30 days, for all formulae.
67
+
68
+ # -d, --debug If brewing fails, open an interactive
69
+ # debugging session with access to IRB or a
70
+ # shell inside the temporary build directory.
71
+ # --env If std is passed, use the standard build
72
+ # environment instead of superenv. If super
73
+ # is passed, use superenv even if the formula
74
+ # specifies the standard build environment.
75
+ # --ignore-dependencies An unsupported Homebrew development flag to
76
+ # skip installing any dependencies of any
77
+ # kind. If the dependencies are not already
78
+ # present, the formula will have issues. If
79
+ # you're not developing Homebrew, consider
80
+ # adjusting your PATH rather than using this
81
+ # flag.
82
+ # --only-dependencies Install the dependencies with specified
83
+ # options but do not install the formula
84
+ # itself.
85
+ # --cc Attempt to compile using the specified
86
+ # compiler, which should be the name of the
87
+ # compiler's executable, e.g. gcc-7 for GCC
88
+ # 7. In order to use LLVM's clang, specify
89
+ # llvm_clang. To use the Apple-provided
90
+ # clang, specify clang. This option will
91
+ # only accept compilers that are provided by
92
+ # Homebrew or bundled with macOS. Please do
93
+ # not file issues if you encounter errors
94
+ # while using this option.
95
+ # -s, --build-from-source Compile formula from source even if a
96
+ # bottle is provided. Dependencies will still
97
+ # be installed from bottles if they are
98
+ # available.
99
+ # --force-bottle Install from a bottle if it exists for the
100
+ # current or newest version of macOS, even if
101
+ # it would not normally be used for
102
+ # installation.
103
+ # --include-test Install testing dependencies required to
104
+ # run brew test formula.
105
+ # --devel If formula defines it, install the
106
+ # development version.
107
+ # --HEAD If formula defines it, install the HEAD
108
+ # version, aka. master, trunk, unstable.
109
+ # --fetch-HEAD Fetch the upstream repository to detect if
110
+ # the HEAD installation of the formula is
111
+ # outdated. Otherwise, the repository's HEAD
112
+ # will only be checked for updates when a new
113
+ # stable or development version has been
114
+ # released.
115
+ # --keep-tmp Retain the temporary files created during
116
+ # installation.
117
+ # --build-bottle Prepare the formula for eventual bottling
118
+ # during installation, skipping any
119
+ # post-install steps.
120
+ # --bottle-arch Optimise bottles for the specified
121
+ # architecture rather than the oldest
122
+ # architecture supported by the version of
123
+ # macOS the bottles are built on.
124
+ # -f, --force Install without checking for previously
125
+ # installed keg-only or non-migrated
126
+ # versions.
127
+ # -v, --verbose Print the verification and postinstall
128
+ # steps.
129
+ # --display-times Print install times for each formula at the
130
+ # end of the run.
131
+ # -i, --interactive Download and patch formula, then open a
132
+ # shell. This allows the user to run
133
+ # ./configure --help and otherwise
134
+ # determine how to turn the software package
135
+ # into a Homebrew package.
136
+ # -g, --git Create a Git repository, useful for
137
+ # creating patches to the software.
138
+ # -h, --help Show this message.
@@ -0,0 +1,82 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'brew/utils/string_utils'
4
+ require 'brew/utils/system_runner'
5
+
6
+ module Brew
7
+ module Commands
8
+ class List
9
+ attr_reader :brew_path, :formulae, :options, :system_runner
10
+
11
+ def initialize(brew_path, *formulae, **kwargs)
12
+ @brew_path = brew_path
13
+ @formulae = formulae.join(' ')
14
+ @options = parse_args(kwargs)
15
+ @system_runner = SystemRunner.new
16
+ end
17
+
18
+ def execute!
19
+ list_command = "#{brew_path} list #{options} #{formulae}".squish
20
+ system_runner.print_output(list_command)
21
+ rescue StandardError => e
22
+ raise ExecutionError, e
23
+ end
24
+
25
+ private
26
+
27
+ BOOLEAN_OPTIONS = %i[
28
+ full_name unbrewed versions multiple
29
+ pinned cask 1 l r t verbose debug
30
+ ].freeze
31
+
32
+ def parse_args(args)
33
+ option_list = []
34
+
35
+ BOOLEAN_OPTIONS.each do |option|
36
+ str_option = option.to_s
37
+ kebab_option = str_option.snake_to_kebab
38
+ option_list << "--#{kebab_option}" if args[option] || args[str_option] || args[kebab_option]
39
+ end
40
+
41
+ option_list.join(' ')
42
+ end
43
+ end
44
+ end
45
+ end
46
+
47
+ # Usage: brew list, ls [options] [formula]
48
+
49
+ # List all installed formulae.
50
+
51
+ # If formula is provided, summarise the paths within its current keg.
52
+
53
+ # --full-name Print formulae with fully-qualified names.
54
+ # If --full-name is not passed, other
55
+ # options (i.e. -1, -l, -r and -t)
56
+ # are passed to ls(1) which produces the
57
+ # actual output.
58
+ # --unbrewed List files in Homebrew's prefix not
59
+ # installed by Homebrew.
60
+ # --versions Show the version number for installed
61
+ # formulae, or only the specified formulae if
62
+ # formula are provided.
63
+ # --multiple Only show formulae with multiple versions
64
+ # installed.
65
+ # --pinned Show the versions of pinned formulae, or
66
+ # only the specified (pinned) formulae if
67
+ # formula are provided. See also pin,
68
+ # unpin.
69
+ # --cask List casks
70
+ # -1 Force output to be one entry per line. This
71
+ # is the default when output is not to a
72
+ # terminal.
73
+ # -l List in long format. If the output is to a
74
+ # terminal, a total sum for all the file
75
+ # sizes is printed before the long listing.
76
+ # -r Reverse the order of the sort to list the
77
+ # oldest entries first.
78
+ # -t Sort by time modified, listing most
79
+ # recently modified first.
80
+ # -v, --verbose Make some output more verbose.
81
+ # -d, --debug Display any debugging information.
82
+ # -h, --help Show this message.
@@ -0,0 +1,101 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'brew/utils/string_utils'
4
+ require 'brew/utils/system_runner'
5
+
6
+ module Brew
7
+ module Commands
8
+ class Search
9
+ attr_reader :brew_path, :search_text, :options, :system_runner
10
+
11
+ def initialize(brew_path, search_text = nil, **kwargs)
12
+ @brew_path = brew_path
13
+ @search_text = search_text
14
+ @options = parse_args(kwargs)
15
+ @system_runner = SystemRunner.new
16
+ end
17
+
18
+ def execute!
19
+ search_command = "#{brew_path} search #{options} #{search_text}".squish
20
+ search_output = system_runner.get_output_lines(search_command)
21
+
22
+ organize_search_output(search_output)
23
+ rescue StandardError => e
24
+ raise Brew::ExecutionError, e
25
+ end
26
+
27
+ private
28
+
29
+ BOOLEAN_OPTIONS = %i[
30
+ formulae casks desc macports fink opensuse
31
+ fedora debian ubuntu verbose debug
32
+ ].freeze
33
+
34
+ def parse_args(args)
35
+ option_list = []
36
+
37
+ BOOLEAN_OPTIONS.each do |option|
38
+ str_option = option.to_s
39
+ kebab_option = str_option.snake_to_kebab
40
+ option_list << "--#{kebab_option}" if args[option] || args[str_option] || args[kebab_option]
41
+ end
42
+
43
+ option_list.join(' ')
44
+ end
45
+
46
+ def organize_search_output(output)
47
+ organized = {}
48
+ key = options.include?('casks') ? 'Casks' : 'Formulae'
49
+
50
+ output.each do |val|
51
+ val.strip!
52
+ if val.start_with?('==>')
53
+ key = val.split.last.squish
54
+ organized[key] ||= []
55
+ else
56
+ organized[key] ||= []
57
+ organized[key] << val.squish
58
+ end
59
+ end
60
+
61
+ organized
62
+ end
63
+ end
64
+ end
65
+ end
66
+
67
+ # Usage: brew search [options] [text|/text/]
68
+
69
+ # Perform a substring search of cask tokens and formula names for text. If
70
+ # text is flanked by slashes, it is interpreted as a regular expression. The
71
+ # search for text is extended online to homebrew/core and homebrew/cask.
72
+
73
+ # If no text is provided, list all locally available formulae (including tapped
74
+ # ones). No online search is performed.
75
+
76
+ # --formulae Without text, list all locally available
77
+ # formulae (no online search is performed).
78
+ # With text, search online and locally for
79
+ # formulae.
80
+ # --casks Without text, list all locally available
81
+ # casks (including tapped ones, no online
82
+ # search is performed). With text, search
83
+ # online and locally for casks.
84
+ # --desc Search for formulae with a description
85
+ # matching text and casks with a name
86
+ # matching text.
87
+ # --macports Search for text in the given package
88
+ # manager's list.
89
+ # --fink Search for text in the given package
90
+ # manager's list.
91
+ # --opensuse Search for text in the given package
92
+ # manager's list.
93
+ # --fedora Search for text in the given package
94
+ # manager's list.
95
+ # --debian Search for text in the given package
96
+ # manager's list.
97
+ # --ubuntu Search for text in the given package
98
+ # manager's list.
99
+ # -v, --verbose Make some output more verbose.
100
+ # -d, --debug Display any debugging information.
101
+ # -h, --help Show this message.
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'brew/utils/string_utils'
4
+ require 'brew/utils/system_runner'
5
+
6
+ module Brew
7
+ module Commands
8
+ class Uninstall
9
+ attr_reader :brew_path, :formulae, :options, :system_runner
10
+
11
+ def initialize(brew_path, *formulae, **kwargs)
12
+ @brew_path = brew_path
13
+ @formulae = formulae.join(' ')
14
+ @options = parse_args(kwargs)
15
+ @system_runner = SystemRunner.new
16
+ end
17
+
18
+ def execute!
19
+ uninstall_command = "#{brew_path} uninstall #{options} #{formulae}".squish
20
+ system_runner.print_output(uninstall_command)
21
+ rescue StandardError => e
22
+ raise Brew::ExecutionError, e
23
+ end
24
+
25
+ private
26
+
27
+ BOOLEAN_OPTIONS = %i[force ignore_dependencies debug].freeze
28
+
29
+ def parse_args(args)
30
+ option_list = []
31
+
32
+ BOOLEAN_OPTIONS.each do |option|
33
+ str_option = option.to_s
34
+ kebab_option = str_option.snake_to_kebab
35
+ option_list << "--#{kebab_option}" if args[option] || args[str_option] || args[kebab_option]
36
+ end
37
+
38
+ option_list.join(' ')
39
+ end
40
+ end
41
+ end
42
+ end
43
+
44
+ # Usage: brew uninstall, rm, remove [options] formula
45
+
46
+ # Uninstall formula.
47
+
48
+ # -f, --force Delete all installed versions of formula.
49
+ # --ignore-dependencies Don't fail uninstall, even if formula is
50
+ # a dependency of any installed formulae.
51
+ # -d, --debug Display any debugging information.
52
+ # -h, --help Show this message.
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'brew/utils/string_utils'
4
+ require 'brew/utils/system_runner'
5
+
6
+ module Brew
7
+ module Commands
8
+ class Update
9
+ attr_reader :brew_path, :options, :system_runner
10
+
11
+ def initialize(brew_path, **kwargs)
12
+ @brew_path = brew_path
13
+ @options = parse_args(kwargs)
14
+ @system_runner = SystemRunner.new
15
+ end
16
+
17
+ def execute!
18
+ update_command = "#{brew_path} update #{options}".squish
19
+ system_runner.print_output(update_command)
20
+ rescue StandardError => e
21
+ raise Brew::ExecutionError, e
22
+ end
23
+
24
+ private
25
+
26
+ BOOLEAN_OPTIONS = %i[merge force verbose debug].freeze
27
+
28
+ def parse_args(args)
29
+ option_list = []
30
+
31
+ BOOLEAN_OPTIONS.each do |option|
32
+ str_option = option.to_s
33
+ kebab_option = str_option.snake_to_kebab
34
+ option_list << "--#{kebab_option}" if args[option] || args[str_option] || args[kebab_option]
35
+ end
36
+
37
+ option_list.join(' ')
38
+ end
39
+ end
40
+ end
41
+ end
42
+
43
+ # Usage: brew update, up [options]
44
+
45
+ # Fetch the newest version of Homebrew and all formulae from GitHub using git(1)
46
+ # and perform any necessary migrations.
47
+
48
+ # --merge Use git merge to apply updates (rather
49
+ # than git rebase).
50
+ # -f, --force Always do a slower, full update check (even
51
+ # if unnecessary).
52
+ # -v, --verbose Print the directories checked and git
53
+ # operations performed.
54
+ # -d, --debug Display a trace of all shell commands as
55
+ # they are executed.
56
+ # -h, --help Show this message.
@@ -0,0 +1,93 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'brew/utils/string_utils'
4
+ require 'brew/utils/system_runner'
5
+
6
+ module Brew
7
+ module Commands
8
+ class Upgrade
9
+ attr_reader :brew_path, :formulae, :options, :system_runner
10
+
11
+ def initialize(brew_path, *formulae, **kwargs)
12
+ @brew_path = brew_path
13
+ @formulae = formulae.join(' ')
14
+ @options = parse_args(kwargs)
15
+ @system_runner = SystemRunner.new
16
+ end
17
+
18
+ def execute!
19
+ upgrade_command = "#{brew_path} upgrade #{options} #{formulae}".squish
20
+ system_runner.print_output(upgrade_command)
21
+ rescue StandardError => e
22
+ raise Brew::ExecutionError, e
23
+ end
24
+
25
+ private
26
+
27
+ BOOLEAN_OPTIONS = %i[
28
+ build_from_source force_bottle fetch_HEAD
29
+ ignore_pinned keep_tmp force verbose
30
+ display_times dry_run greedy
31
+ ].freeze
32
+
33
+ def parse_args(args)
34
+ option_list = []
35
+
36
+ BOOLEAN_OPTIONS.each do |option|
37
+ str_option = option.to_s
38
+ kebab_option = str_option.snake_to_kebab
39
+ option_list << "--#{kebab_option}" if args[option] || args[str_option] || args[kebab_option]
40
+ end
41
+
42
+ option_list.join(' ')
43
+ end
44
+ end
45
+ end
46
+ end
47
+
48
+ # Usage: brew upgrade [options] [formula]
49
+
50
+ # Upgrade outdated, unpinned formulae using the same options they were originally
51
+ # installed with, plus any appended brew formula options. If formula are
52
+ # specified, upgrade only the given formula kegs (unless they are pinned; see
53
+ # pin, unpin).
54
+
55
+ # Unless HOMEBREW_NO_INSTALL_CLEANUP is set, brew cleanup will then be run for
56
+ # the upgraded formulae or, every 30 days, for all formulae.
57
+
58
+ # -d, --debug If brewing fails, open an interactive
59
+ # debugging session with access to IRB or a
60
+ # shell inside the temporary build directory.
61
+ # -s, --build-from-source Compile formula from source even if a
62
+ # bottle is available.
63
+ # -i, --interactive Download and patch formula, then open a
64
+ # shell. This allows the user to run
65
+ # ./configure --help and otherwise
66
+ # determine how to turn the software package
67
+ # into a Homebrew package.
68
+ # --force-bottle Install from a bottle if it exists for the
69
+ # current or newest version of macOS, even if
70
+ # it would not normally be used for
71
+ # installation.
72
+ # --fetch-HEAD Fetch the upstream repository to detect if
73
+ # the HEAD installation of the formula is
74
+ # outdated. Otherwise, the repository's HEAD
75
+ # will only be checked for updates when a new
76
+ # stable or development version has been
77
+ # released.
78
+ # --ignore-pinned Set a successful exit status even if pinned
79
+ # formulae are not upgraded.
80
+ # --keep-tmp Retain the temporary files created during
81
+ # installation.
82
+ # -f, --force Install without checking for previously
83
+ # installed keg-only or non-migrated
84
+ # versions.
85
+ # -v, --verbose Print the verification and postinstall
86
+ # steps.
87
+ # --display-times Print install times for each formula at the
88
+ # end of the run.
89
+ # -n, --dry-run Show what would be upgraded, but do not
90
+ # actually upgrade anything.
91
+ # --greedy Upgrade casks with auto_updates or
92
+ # version :latest
93
+ # -h, --help Show this message.
@@ -1,58 +1,55 @@
1
- module Brew
2
- class HomeBrewError < StandardError; end
3
- class HomeBrewNotInstalled < HomeBrewError; end
1
+ # frozen_string_literal: true
2
+
3
+ require 'brew/commands/info'
4
+ require 'brew/commands/install'
5
+ require 'brew/commands/list'
6
+ require 'brew/commands/search'
7
+ require 'brew/commands/uninstall'
8
+ require 'brew/commands/update'
9
+ require 'brew/commands/upgrade'
4
10
 
11
+ module Brew
5
12
  class HomeBrew
6
-
7
- DEFAULT_BREW_PATH = '/usr/local/bin/brew'.freeze
13
+ DEFAULT_BREW_PATH = '/usr/local/bin/brew'
8
14
 
9
15
  attr_reader :brew_path
10
16
  private :brew_path
11
17
 
12
- def initialize(brew_path: DEFAULT_BREW_PATH)
13
- @brew_path = brew_path
14
- raise HomeBrewNotInstalled unless File.executable?(brew_path)
18
+ def initialize(brew_path: nil)
19
+ @brew_path = brew_path || DEFAULT_BREW_PATH
20
+ raise HomeBrewNotInstalled unless File.executable?(@brew_path)
21
+ end
22
+
23
+ def info(formula = [], **kwargs)
24
+ Commands::Info.new(brew_path, formula, **kwargs).execute!
25
+ end
26
+
27
+ def install(formula, **kwargs)
28
+ Commands::Install.new(brew_path, formula, **kwargs).execute!
15
29
  end
16
30
 
17
- def install(formula)
18
- install_command = "#{brew_path} install '#{formula}'"
19
- run_command(install_command)
20
- rescue => e
21
- raise HomeBrewError, e
31
+ def list(formulae = [], **kwargs)
32
+ Commands::List.new(brew_path, formulae, **kwargs).execute!
22
33
  end
34
+ alias ls list
23
35
 
24
- def update
25
- update_command = "#{brew_path} update"
26
- run_command(update_command)
27
- rescue => e
28
- raise HomeBrewError, e
36
+ def search(text = nil, **kwargs)
37
+ Commands::Search.new(brew_path, text, **kwargs).execute!
29
38
  end
30
39
 
31
- def upgrade(formula)
32
- update_command = "#{brew_path} upgrade '#{formula}'"
33
- run_command(update_command)
34
- rescue => e
35
- raise HomeBrewError, e
40
+ def uninstall(formula, **kwargs)
41
+ Commands::Uninstall.new(brew_path, formula, **kwargs).execute!
36
42
  end
43
+ alias rm uninstall
44
+ alias remove uninstall
37
45
 
38
- def uninstall(formula)
39
- update_command = "#{brew_path} uninstall '#{formula}'"
40
- run_command(update_command)
41
- rescue => e
42
- raise HomeBrewError, e
46
+ def update(**kwargs)
47
+ Commands::Update.new(brew_path, **kwargs).execute!
43
48
  end
49
+ alias up update
44
50
 
45
- private
46
-
47
- def run_command(command)
48
- IO.popen(command, 'r+') do |io|
49
- while line = io.gets
50
- $stdout.puts line
51
- end
52
- io.close
53
- end
54
-
55
- raise HomeBrewError unless $?.success?
51
+ def upgrade(formula = [], **kwargs)
52
+ Commands::Upgrade.new(brew_path, formula, **kwargs).execute!
56
53
  end
57
54
  end
58
- end
55
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: false
2
+
3
+ class String
4
+ def snake_to_kebab
5
+ gsub('_', '-')
6
+ end
7
+
8
+ def squish
9
+ strip.gsub(/\s+/, ' ')
10
+ end
11
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'English'
4
+
5
+ module Brew
6
+ class SystemRunner
7
+ def print_output(command)
8
+ lines = run_with_output(command) do |line|
9
+ $stdout.puts line
10
+ end
11
+ lines.join
12
+ end
13
+
14
+ def get_output_lines(command)
15
+ run_with_output(command)
16
+ end
17
+
18
+ private
19
+
20
+ def run_with_output(command)
21
+ lines = []
22
+ IO.popen(command, 'r+') do |io|
23
+ while (line = io.gets)
24
+ yield line if block_given?
25
+ lines << line
26
+ end
27
+ io.close
28
+ end
29
+
30
+ raise "Exited with code #{$CHILD_STATUS.exitstatus}" unless $CHILD_STATUS.success?
31
+
32
+ lines
33
+ end
34
+ end
35
+ end
data/lib/brew/version.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Brew
2
- VERSION = "0.1.0"
4
+ VERSION = '0.2.2'
3
5
  end