squared 0.1.3 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -5,21 +5,29 @@ module Squared
5
5
  module Project
6
6
  class Python < Git
7
7
  REQUIREMENTS = %w[requirements.txt pyproject.toml setup.py].freeze
8
- OPT_USER = %w[pre dry-run].freeze
9
- OPT_FORCE = (OPT_USER + ['user']).freeze
10
- OPT_GENERAL = %w{venv isolated no-cache-dir [v]erbose}.freeze
11
- private_constant :REQUIREMENTS, :OPT_USER, :OPT_FORCE, :OPT_GENERAL
8
+ OPT_INSTALL = %w[I U break-system-packages check-build-dependencies compile dry-run force-reinstall
9
+ ignore-installed ignore-requires-python no-build-isolation no-clean no-compile no-deps
10
+ no-index no-warn-conflicts no-warn-script-location pre prefer-binary require-hashes upgrade
11
+ use-pep517 user abi=s config-settings=s c=s constraint=s e=s editable=s extra-index-url=s
12
+ f=s find-links=s global-option=s implementation=s i=s index-url=s no-binary=s only-binary=s
13
+ platform=s prefix=s progress-bar=s python-version=s report=s r=s requirement=s
14
+ root-user-action=s root=s src=s t=s target=s upgrade-strategy=s].freeze
15
+ OPT_GENERAL = %w[debug disable-pip-version-check isolated q quiet require-virtualenv v verbose
16
+ no-cache-dir no-color no-input no-python-version-warning
17
+ cache-dir=s cert=s client-cert=s exists-action=s log=s proxy=s python=s retries=i timeout=i
18
+ trusted-host=s use-deprecated=s use-feature=s].freeze
19
+ private_constant :REQUIREMENTS, :OPT_INSTALL, :OPT_GENERAL
12
20
 
13
21
  class << self
14
22
  def populate(*); end
15
23
  def batchargs(*); end
16
24
 
17
25
  def tasks
18
- %i[outdated].freeze
26
+ [:outdated].freeze
19
27
  end
20
28
 
21
29
  def bannerargs
22
- %i[dependfile].freeze
30
+ [:dependfile].freeze
23
31
  end
24
32
 
25
33
  def venv?
@@ -47,40 +55,38 @@ module Squared
47
55
  end
48
56
 
49
57
  @@tasks[ref] = {
50
- install: %i[user target upgrade force].freeze
58
+ 'install' => %i[user upgrade force target].freeze
51
59
  }.freeze
52
60
 
53
61
  def ref
54
62
  Python.ref
55
63
  end
56
64
 
57
- def populate(*)
65
+ def populate(*, **)
58
66
  super
59
67
  return unless outdated? && ref?(Python.ref)
60
68
 
61
69
  namespace name do
62
70
  @@tasks[Python.ref].each do |action, flags|
71
+ next if @pass.include?(action)
72
+
63
73
  namespace action do
64
74
  flags.each do |flag|
65
75
  case action
66
- when :install
67
- list = case flag
68
- when :target
69
- req = 'dir'
70
- OPT_USER + %w[upgrade eager]
71
- when :upgrade
72
- OPT_FORCE + ['eager']
73
- when :force
74
- OPT_FORCE
75
- else
76
- OPT_USER
77
- end
78
- list += OPT_GENERAL
79
- desc format_desc(action, flag, list, req: req)
80
- if flag == :target
81
- task flag, [:dir, :opts] do |_, args|
82
- dir = guard_params(action, flag, args: args, key: :dir)
83
- depend(flag, dir: dir, opts: args.to_a.drop(1))
76
+ when 'install'
77
+ if @@task_desc
78
+ format_desc(action, flag, OPT_INSTALL + OPT_GENERAL, before: case flag
79
+ when :target
80
+ 'dir'
81
+ when :upgrade
82
+ 'strategy'
83
+ end)
84
+ end
85
+ case flag
86
+ when :target, :upgrade
87
+ task flag, [:param] do |_, args|
88
+ param = param_guard(action, flag, args: args, key: :param)
89
+ depend(flag, param: param, opts: args.extras)
84
90
  end
85
91
  else
86
92
  task flag do |_, args|
@@ -94,7 +100,7 @@ module Squared
94
100
  end
95
101
  end
96
102
 
97
- def depend(flag = nil, dir: nil, opts: [], sync: invoked_sync?('depend', flag))
103
+ def depend(flag = nil, sync: invoked_sync?('depend', flag), param: nil, opts: [])
98
104
  if @depend && !flag
99
105
  super
100
106
  elsif outdated?
@@ -104,33 +110,117 @@ module Squared
104
110
  case flag
105
111
  when :user
106
112
  cmd << '--user'
107
- append_pip opts, OPT_USER
108
- when :target
109
- cmd << shell_option('target', basepath(dir), quote: true)
110
- append_pip opts, OPT_USER + ['upgrade']
111
- append_eager opts
112
113
  when :upgrade
113
114
  cmd << '--upgrade'
114
- append_pip opts, OPT_FORCE
115
- append_eager opts
115
+ case param
116
+ when 'eager', 'only-if-needed'
117
+ cmd << basic_option('upgrade-strategy', param)
118
+ else
119
+ opts << param
120
+ end
116
121
  when :force
117
122
  cmd << '--force-reinstall'
118
- append_pip opts, OPT_FORCE
123
+ when :target
124
+ cmd << shell_option('target', basepath(param), quote: true)
119
125
  else
120
- append_pip
126
+ append_global
127
+ end
128
+ append_pip opts if flag
129
+ if type == 2
130
+ cmd << '.'
131
+ elsif !cmd.find { |val| val =~ /^(?:-r|--requirement)/ }
132
+ cmd << '-r requirements.txt'
121
133
  end
122
- cmd << (type == 1 ? '-r requirements.txt' : '.')
123
- run(sync: sync)
124
134
  when 3
125
- run_s('python setup.py install', sync: sync)
135
+ cmd = python_session 'setup.py', 'install'
136
+ case flag
137
+ when :user
138
+ cmd << '--user'
139
+ when :target
140
+ cmd << quote_option('build-base', basepath(dir))
141
+ end
142
+ if option('user')
143
+ cmd << '--user'
144
+ else
145
+ append_first(%w[home prefix], equals: true, escape: false, quote: true, ignore: false)
146
+ end
147
+ cmd.delete('--user') if workspace.windows?
126
148
  end
149
+ run(from: :depend, sync: sync)
127
150
  end
128
151
  end
129
152
 
130
153
  def outdated(*, sync: invoked_sync?('outdated'))
131
- pip_session 'list', '--outdated'
132
- append_pip
133
- run(sync: sync)
154
+ cmd = pip_session 'list', '--outdated'
155
+ append_global
156
+ cmd = session_done(cmd)
157
+ log.info cmd
158
+ on :first, :outdated
159
+ banner = format_banner(cmd)
160
+ print_item banner if sync
161
+ start = 0
162
+ found = 0
163
+ major = 0
164
+ pwd_set(from: :outdated) do
165
+ buffer = []
166
+ out = ->(val) { sync ? puts(val) : buffer << val }
167
+ IO.popen(cmd).each do |line|
168
+ next if line =~ /^[\s-]+$/
169
+
170
+ if start > 0
171
+ unless stdin?
172
+ data = line.scan(SEM_VER)
173
+ next unless (cur = data.shift) && (lat = data.shift)
174
+
175
+ latest = lat.join
176
+ current = cur.join
177
+ semver(cur)
178
+ semver(lat)
179
+ if semmajor?(cur, lat)
180
+ type = 2
181
+ major += 1
182
+ else
183
+ type = cur[2] == lat[2] ? 0 : 1
184
+ end
185
+ if type == 0
186
+ styles = color(:yellow)
187
+ else
188
+ styles = color(:green)
189
+ line = sub_style(line, pat: /^(\S+)(.+)$/, styles: if type == 2
190
+ styles << :bold
191
+ theme[:major]
192
+ else
193
+ theme[:active]
194
+ end)
195
+ end
196
+ if theme[:current]
197
+ line = sub_style(line, pat: /^(.+)(#{Regexp.escape(current)})(.+)$/, styles: theme[:current],
198
+ index: 2)
199
+ end
200
+ line = sub_style(line, pat: /^(.+)(#{Regexp.escape(latest)})(.+)$/, styles: styles, index: 2)
201
+ found += 1
202
+ end
203
+ out.("#{start.to_s.rjust(2)}. #{line}")
204
+ start += 1
205
+ elsif line =~ /^Package /
206
+ unless stdin?
207
+ sub = { pat: /^(.*)(?<!\dm)(Package|Latest)(.+)$/, styles: theme[:header], index: 2 }
208
+ out.(print_footer(" # #{line.chomp}", reverse: true, sub: [sub, sub]))
209
+ end
210
+ start += 1
211
+ end
212
+ end
213
+ unless sync
214
+ print_item banner
215
+ puts buffer
216
+ end
217
+ if found > 0
218
+ puts print_footer empty_status('Updates are available', 'major', major)
219
+ elsif start == 0
220
+ puts 'No updates were found'
221
+ end
222
+ end
223
+ on :last, :outdated
134
224
  end
135
225
 
136
226
  def variable_set(key, *val, **)
@@ -162,29 +252,54 @@ module Squared
162
252
  session('pip', *cmd)
163
253
  end
164
254
 
165
- def append_pip(opts = [], list = [])
255
+ def python_session(*cmd)
256
+ session('python', *cmd)
257
+ end
258
+
259
+ def append_pip(opts, list = nil, target: @session)
260
+ append_nocolor(target: target)
261
+ return if opts.empty?
262
+
263
+ out = []
264
+ opts, pat = option_partition(opts, list || (OPT_INSTALL + OPT_GENERAL), target: target)
166
265
  opts.each do |opt|
167
- data = nil
168
- next unless list.include?(opt) || OPT_GENERAL.include?(opt) || (data = opt.match(/^verbose|(v+)$/))
169
-
170
- @session << case opt
171
- when 'venv'
172
- '--require-virtualenv'
173
- else
174
- (data && data[1] ? "-#{data[1]}" : "--#{opt}")
175
- end
266
+ if opt =~ /^(v+|q+)$/
267
+ cmd << "-#{$1}"
268
+ elsif opt =~ pat
269
+ case $1
270
+ when 'root', 'prefix', 'src', 'cert', 'client-cert', 'cache-dir', 'log', 'report',
271
+ 'r', 'requirement', 'c', 'constraint', 't', 'target'
272
+ target << quote_option($1, basepath($2))
273
+ when 'e', 'editable'
274
+ val = $2
275
+ target << quote_option($1, val =~ %r{^[a-z]+\+[a-z]+://} ? val : basepath(val))
276
+ when 'proxy', 'config-settings', 'global-option', 'extra-index-url',
277
+ 'f', 'find-links', 'i', 'index-url'
278
+ target << shell_option($1, $2, quote: true)
279
+ when 'retries', 'timeout'
280
+ target << basic_option($1, $2) if $2.to_i > 0
281
+ else
282
+ target << shell_option($1, $2)
283
+ end
284
+ else
285
+ out << opt
286
+ end
176
287
  end
177
- val = nil
178
- @session << shell_option('proxy', val, quote: true) if (val = option('proxy'))
179
- @session << shell_option('python', basepath(val), quote: true) if (val = option('python'))
180
- @session << shell_option('log', basepath(val), quote: true) if (val = option('log', ignore: false))
181
- @session << '--user' if !list.empty? && option('user')
182
- @session << '--no-input' if option('no-input')
183
- append_nocolor option('no-color')
288
+ option_clear(out, target: target)
184
289
  end
185
290
 
186
- def append_eager(opts)
187
- @session << '--upgrade-strategy=eager' if opts.include?('eager')
291
+ def append_global
292
+ if (val = option('cache-dir'))
293
+ cmd << case val
294
+ when '0', 'false'
295
+ '--no-cache-dir'
296
+ else
297
+ quote_option('cache-dir', basepath(val))
298
+ end
299
+ end
300
+ cmd << shell_option('proxy', val, quote: true) if (val = option('proxy'))
301
+ cmd << quote_option('python', basepath(val)) if (val = option('python'))
302
+ append_nocolor
188
303
  end
189
304
  end
190
305