homebrew_automation 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 1681a8e776c3eddbccd8381b97ae24b7b2a65299
4
+ data.tar.gz: 20e552f26f2757c826977b460d4e85728dbefd90
5
+ SHA512:
6
+ metadata.gz: ddb763670a14252198112f6704a8fee80a739e5bdb864ea8cd283ee32fdf71b8283d6b5ccc71a45e328d69a885a8c3006b9bc8e372ce9286844a36220c7e561e
7
+ data.tar.gz: ff6e96770ba8b20387260da4568df2a8ef94ed4c06c4e299f023b0fdd5c45ea0c9634bb8c4af2f6e395ca20558296a8df7d08ce73fcb46035ce53b563231c324
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'thor'
4
+
5
+ require 'homebrew_automation'
6
+
7
+ class MyCliApp < Thor
8
+
9
+ desc 'put-sdist', 'update the URL and sha256 checksum of the source tarball'
10
+ option :url, :required => true
11
+ option :sha256, :required => true
12
+ def put_sdist
13
+ before = HomebrewAutomation::Formula.parse_string($stdin.read)
14
+ after = before.
15
+ update_field("url", options[:url]).
16
+ update_field("sha256", options[:sha256])
17
+ $stdout.write after
18
+ end
19
+
20
+ desc 'put-bottle', 'insert or update a bottle reference for a given OS'
21
+ option :os, :required => true
22
+ option :sha256, :required => true
23
+ def put_bottle
24
+ before = HomebrewAutomation::Formula.parse_string($stdin.read)
25
+ after = before.put_bottle(options[:os], options[:sha256])
26
+ $stdout.write after
27
+ end
28
+
29
+ end
30
+
31
+ MyCliApp.start(ARGV)
32
+
33
+
@@ -0,0 +1,172 @@
1
+
2
+ require 'parser/current'
3
+ require 'unparser'
4
+
5
+ Parser::Builders::Default.emit_lambda = true
6
+ Parser::Builders::Default.emit_procarg0 = true
7
+
8
+ module HomebrewAutomation
9
+
10
+ class Formula
11
+
12
+ # Formula::parse_string :: String -> Formula
13
+ def self.parse_string s
14
+ Formula.new (Parser::CurrentRuby.parse s)
15
+ end
16
+
17
+ # Formula::new :: Parser::AST::Node -> Formula
18
+ def initialize ast
19
+ @ast = ast
20
+ end
21
+
22
+ def to_s
23
+ Unparser.unparse @ast
24
+ end
25
+
26
+ # update_field :: String -> String -> Formula
27
+ def update_field field, value
28
+ Formula.new update(
29
+ @ast,
30
+ [ by_type('begin'),
31
+ by_both(
32
+ by_type('send'),
33
+ by_msg(field)),
34
+ by_type('str')],
35
+ -> (n) { n.updated(nil, [value]) })
36
+ end
37
+
38
+ # Insert or replace the bottle for a given OS
39
+ # put_bottle :: String -> String -> Node -> Node
40
+ def put_bottle os, sha256
41
+ Formula.new update(
42
+ @ast,
43
+ bot_begin_path,
44
+ put_bottle_version(os, sha256))
45
+ end
46
+
47
+ private
48
+
49
+ # Path to the :begin node
50
+ # bot_begin_path :: [Choice]
51
+ # type Choice = Proc (Node -> Bool)
52
+ def bot_begin_path
53
+ [ by_type('begin'),
54
+ by_both(
55
+ by_type('block'),
56
+ by_child(
57
+ by_both(
58
+ by_type('send'),
59
+ by_msg('bottle')))),
60
+ by_type('begin')]
61
+ end
62
+
63
+ # Tricky: this is an insert-or-update
64
+ # put_bottle_version :: String -> String -> Proc (Node -> Node)
65
+ def put_bottle_version os, sha256
66
+ -> (bot_begin) {
67
+ bot_begin.updated(
68
+ nil, # keep the node type the unchanged
69
+ bot_begin.children.reject(
70
+ # Get rid of any existing matching ones
71
+ &by_both(
72
+ by_msg('sha256'),
73
+ by_os(os))
74
+ # Then add the one we want
75
+ ).push(new_sha256(sha256, os)))
76
+ }
77
+ end
78
+
79
+ # Build a new AST Node
80
+ # String -> String -> Node
81
+ def new_sha256 sha256, os
82
+ # Unparser doesn't like Sexp, so let's bring
83
+ # own own bit of "source code" inline.
84
+ sha256_send = Parser::CurrentRuby.parse(
85
+ 'sha256 "checksum-here" => :some_os')
86
+ with_sha256 = update(
87
+ sha256_send,
88
+ [ by_type('hash'),
89
+ by_type('pair'),
90
+ by_type('str') ],
91
+ -> (n) { n.updated(nil, [sha256]) })
92
+ with_sha256_and_os = update(
93
+ with_sha256,
94
+ [ by_type('hash'),
95
+ by_type('pair'),
96
+ by_type('sym') ],
97
+ -> (n) { n.updated(nil, [os.to_sym]) })
98
+ with_sha256_and_os
99
+ end
100
+
101
+ # update :: Node -> [Choice] -> Proc (Node -> Node) -> Node
102
+ def update node, path, fn
103
+ if path.length == 0 then
104
+ fn.(node)
105
+ else
106
+ choose, *rest = path
107
+ node.updated(
108
+ nil, # Don't change node type
109
+ node.children.map do |c|
110
+ choose.(c) ? update(c, rest, fn) : c
111
+ end)
112
+ end
113
+ end
114
+
115
+ # zoom_in :: Node -> [Choice] -> Node
116
+ def zoom_in node, path
117
+ if path.length == 0 then
118
+ node
119
+ else
120
+ choose, *rest = path
121
+ chosen = node.children.select(&choose).first
122
+ zoom_in chosen, rest
123
+ end
124
+ end
125
+
126
+ # by_both
127
+ # :: Proc (Node -> Bool)
128
+ # -> Proc (Node -> Bool)
129
+ # -> Proc (Node -> Bool)
130
+ def by_both p, q
131
+ -> (n) { p.(n) && q.(n) }
132
+ end
133
+
134
+ # by_msg :: String -> Proc (Node -> Bool)
135
+ def by_msg msg
136
+ -> (n) { n.children[1] == msg.to_sym }
137
+ end
138
+
139
+ # by_type :: String -> Proc (Node -> Bool)
140
+ def by_type type
141
+ -> (n) {
142
+ n &&
143
+ n.is_a?(AST::Node) &&
144
+ n.type == type.to_sym
145
+ }
146
+ end
147
+
148
+ # Matches if one of the node's children matches the given p
149
+ # by_child :: Proc (Node -> Bool) -> Proc (Node -> Bool)
150
+ def by_child p
151
+ -> (n) {
152
+ n &&
153
+ n.is_a?(AST::Node) &&
154
+ n.children.select(&p).size > 0
155
+ }
156
+ end
157
+
158
+ # Matches if this :send node expresses the give sha256 sum
159
+ # by_os :: String -> Proc (Node -> Bool)
160
+ def by_os os
161
+ -> (n) {
162
+ zoom_in(n, [
163
+ by_type('hash'),
164
+ by_type('pair'),
165
+ by_type('sym')])
166
+ .children[0] == os.to_sym
167
+ }
168
+ end
169
+
170
+ end
171
+
172
+ end
@@ -0,0 +1,4 @@
1
+
2
+ module HomebrewAutomation
3
+ VERSION = '0.0.1'
4
+ end
metadata ADDED
@@ -0,0 +1,90 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: homebrew_automation
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - easoncxz
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-12-30 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: thor
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.20'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.20'
27
+ - !ruby/object:Gem::Dependency
28
+ name: parser
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '2.4'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '2.4'
41
+ - !ruby/object:Gem::Dependency
42
+ name: unparser
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0.2'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '0.2'
55
+ description: '["If", "you''re", "thinking", "of", "manipulating", "Homebrew", "Formula",
56
+ "files", "during", "e.g.", "continuous", "integration,", "this", "is", "for", "you"]'
57
+ email: me@easoncxz.com
58
+ executables:
59
+ - homebrew_automation.rb
60
+ extensions: []
61
+ extra_rdoc_files: []
62
+ files:
63
+ - bin/homebrew_automation.rb
64
+ - lib/homebrew_automation.rb
65
+ - lib/homebrew_automation/version.rb
66
+ homepage: https://github.com/easoncxz/homebrew-automation
67
+ licenses:
68
+ - GPL-3.0
69
+ metadata: {}
70
+ post_install_message:
71
+ rdoc_options: []
72
+ require_paths:
73
+ - lib
74
+ required_ruby_version: !ruby/object:Gem::Requirement
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
79
+ required_rubygems_version: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ requirements: []
85
+ rubyforge_project:
86
+ rubygems_version: 2.2.5
87
+ signing_key:
88
+ specification_version: 4
89
+ summary: Automate editing of Homebrew Formula files
90
+ test_files: []