ruby-bugzilla 0.3.3 → 0.4.0

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.
data/lib/bugzilla.rb DELETED
@@ -1,826 +0,0 @@
1
- # bugzilla.rb
2
- # Copyright (C) 2010-2012 Red Hat, Inc.
3
- #
4
- # Authors:
5
- # Akira TAGOH <tagoh@redhat.com>
6
- #
7
- # This program is free software; you can redistribute it and/or modify
8
- # it under the terms of the GNU General Public License as published by
9
- # the Free Software Foundation; either version 2 of the License, or
10
- # (at your option) any later version.
11
- #
12
- # This program is distributed in the hope that it will be useful,
13
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
- # GNU General Public License for more details.
16
- #
17
- # You should have received a copy of the GNU General Public License
18
- # along with this program; if not, write to the Free Software
19
- # Foundation, Inc., 59 Temple Place - Suite 330,
20
- # Boston, MA 02111-1307, USA.
21
-
22
- require 'xmlrpc/client'
23
-
24
-
25
- =begin rdoc
26
-
27
- == Bugzilla
28
-
29
- =end
30
-
31
- module Bugzilla
32
-
33
- VERSION = "0.3.3"
34
-
35
- =begin rdoc
36
-
37
- === Bugzilla::Plugin
38
-
39
- =end
40
-
41
- module Plugin
42
-
43
- =begin rdoc
44
-
45
- ==== Bugzilla::Plugin::Template
46
-
47
- =end
48
-
49
- class Template
50
- @@plugins = []
51
-
52
- def initialize
53
- @hostname = nil
54
- end # def initialize
55
-
56
- attr_reader :hostname
57
-
58
- def Template.inherited(subclass)
59
- @@plugins << subclass
60
- end # def inherited
61
-
62
- def run(hook, host, *args)
63
- @@plugins.each do |k|
64
- i = k.new
65
- if i.hostname == host || host.nil? then
66
- case hook
67
- when :parser
68
- i.parserhook(*args)
69
- when :pre
70
- i.prehook(*args)
71
- when :post
72
- i.posthook(*args)
73
- else
74
- end
75
- end
76
- end
77
- end # def run
78
-
79
- def parserhook(parser, argv, opts)
80
- end # def parserhook
81
-
82
- def prehook(cmd, opts)
83
- end # def prehook
84
-
85
- def posthook(cmd, opts)
86
- end # def posthook
87
-
88
- end # class Template
89
-
90
- end # module Plugin
91
-
92
- =begin rdoc
93
-
94
- === Bugzilla::XMLRPC
95
-
96
- =end
97
-
98
- class XMLRPC
99
-
100
- =begin rdoc
101
-
102
- ==== Bugzilla::XMLRPC#new(host, port = 443, path = '/xmlrpc.cgi', proxy_host = nil, proxy_port = nil)
103
-
104
- =end
105
-
106
- def initialize(host, port = 443, path = '/xmlrpc.cgi', proxy_host = nil, proxy_port = nil)
107
- path ||= '/xmlrpc.cgi'
108
- use_ssl = port == 443 ? true : false
109
- @xmlrpc = ::XMLRPC::Client.new(host, path, port, proxy_host, proxy_port, nil, nil, use_ssl, 60)
110
- end # def initialize
111
-
112
- =begin rdoc
113
-
114
- ==== Bugzilla::XMLRPC#call(cmd, params, user = nil, password = nil)
115
-
116
- =end
117
-
118
- def call(cmd, params = {}, user = nil, password = nil)
119
- params = {} if params.nil?
120
- params['Bugzilla_login'] = user unless user.nil? || password.nil?
121
- params['Bugzilla_password'] = password unless user.nil? || password.nil?
122
- @xmlrpc.call(cmd, params)
123
- end # def call
124
-
125
- =begin rdoc
126
-
127
- ==== Bugzilla::XMLRPC#cookie
128
-
129
- =end
130
-
131
- def cookie
132
- @xmlrpc.cookie
133
- end # def cookie
134
-
135
- =begin rdoc
136
-
137
- ==== Bugzilla::XMLRPC#cookie=(val)
138
-
139
- =end
140
-
141
- def cookie=(val)
142
- @xmlrpc.cookie = val
143
- end # def cookie
144
-
145
- end # class XMLRPC
146
-
147
- =begin rdoc
148
-
149
- === Bugzilla::Skeleton
150
-
151
- =end
152
-
153
- class Skeleton
154
-
155
- def initialize(iface)
156
- @iface = iface
157
- end # def initialize
158
-
159
- def method_missing(symbol, *args)
160
- m = "_#{symbol}"
161
- klass = self.class.to_s.sub(/\ABugzilla::/, '')
162
- fm = "#{klass}.#{symbol}"
163
- if self.respond_to?(m) then
164
- __send__(m, fm, *args)
165
- else
166
- raise NoMethodError, sprintf("No such Bugzilla APIs: %s.%s", klass, symbol)
167
- end
168
- end # def method_missing
169
-
170
- end # class Skeleton
171
-
172
- =begin rdoc
173
-
174
- === Bugzilla::Bugzilla
175
-
176
- Bugzilla::Bugzilla class is to access the
177
- Bugzilla::WebService::Bugzilla API that provides functions
178
- tell you about Bugzilla in general.
179
-
180
- =end
181
-
182
- class Bugzilla < Skeleton
183
-
184
- =begin rdoc
185
-
186
- ==== Bugzilla::Bugzilla#check_version(version_)
187
-
188
- Returns Array contains the result of the version check and
189
- Bugzilla version that is running on.
190
-
191
- =end
192
-
193
- def check_version(version_)
194
- v = version
195
- f = false
196
- if v.kind_of?(Hash) && v.include?("version") &&
197
- v['version'] >= "#{version_}" then
198
- f = true
199
- end
200
-
201
- [f, v['version']]
202
- end # def check_version
203
-
204
- =begin rdoc
205
-
206
- ==== Bugzilla::Bugzilla#requires_version(cmd, version_)
207
-
208
- Raise an exception if the Bugzilla doesn't satisfy
209
- the requirement of the _version_.
210
-
211
- =end
212
-
213
- def requires_version(cmd, version_)
214
- v = check_version(version_)
215
- raise NoMethodError, sprintf("%s is not supported in Bugzilla %s", cmd, v[1]) unless v[0]
216
- end # def requires_version
217
-
218
- =begin rdoc
219
-
220
- ==== Bugzilla::Bugzilla#version
221
-
222
- Raw Bugzilla API to obtain the Bugzilla version.
223
-
224
- See http://www.bugzilla.org/docs/tip/en/html/api/Bugzilla/WebService/Bugzilla.html
225
-
226
- =end
227
-
228
- =begin rdoc
229
-
230
- ==== Bugzilla::Bugzilla#extensions
231
-
232
- Raw Bugzilla API to obtain the information about
233
- the extensions that are currently installed and enabled in
234
- the Bugzilla.
235
-
236
- See http://www.bugzilla.org/docs/tip/en/html/api/Bugzilla/WebService/Bugzilla.html
237
-
238
- =end
239
-
240
- =begin rdoc
241
-
242
- ==== Bugzilla::Bugzilla#timezone
243
-
244
- Raw Bugzilla API to obtain the timezone that Bugzilla
245
- expects dates and times in.
246
-
247
- See http://www.bugzilla.org/docs/tip/en/html/api/Bugzilla/WebService/Bugzilla.html
248
-
249
- =end
250
-
251
- =begin rdoc
252
-
253
- ==== Bugzilla::Bugzilla#time
254
-
255
- Raw Bugzilla API to obtain the information about what time
256
- the bugzilla server thinks it is, and what timezone it's
257
- running on.
258
-
259
- See http://www.bugzilla.org/docs/tip/en/html/api/Bugzilla/WebService/Bugzilla.html
260
-
261
- =end
262
-
263
- protected
264
-
265
- def _version(cmd, *args)
266
- @iface.call(cmd)
267
- end # def _version
268
-
269
- def _extensions(cmd, *args)
270
- requires_version(cmd, 3.2)
271
-
272
- @iface.call(cmd)
273
- end # def _extensions
274
-
275
- def _timezone(cmd, *args)
276
- @iface.call(cmd)
277
- end # def _timezone
278
-
279
- def _time(cmd, *args)
280
- requires_version(cmd, 3.4)
281
-
282
- @iface.call(cmd)
283
- end # def _time
284
-
285
- end # class Bugzilla
286
-
287
- =begin rdoc
288
-
289
- === Bugzilla::APITemplate
290
-
291
- =end
292
-
293
- class APITemplate < Skeleton
294
-
295
- def initialize(iface)
296
- super
297
-
298
- @bz = Bugzilla.new(iface)
299
- end # def initialize
300
-
301
- def method_missing(symbol, *args)
302
- if @bz.respond_to?(symbol) then
303
- @bz.__send__(symbol, *args)
304
- else
305
- super
306
- end
307
- end # def method_missing
308
-
309
- end # class APITemplate
310
-
311
- =begin rdoc
312
-
313
- === Bugzilla::Product
314
-
315
- Bugzilla::Product class is to access
316
- the Bugzilla::WebService::Product API that allows you to
317
- list the available Products and get information about them.
318
-
319
- =end
320
-
321
- class Product < APITemplate
322
-
323
- =begin rdoc
324
-
325
- ==== Bugzilla::Product#selectable_products
326
-
327
- Returns the products that the user can search on as Hash
328
- contains the product name as the Hash key and Array as the
329
- value. Array contains the list of _id_, _name_,
330
- _description_ and _internals_ according to API documentation
331
- though, actually the component, the version and the target
332
- milestone.
333
-
334
- =end
335
-
336
- def selectable_products
337
- ids = get_selectable_products
338
- get(ids)
339
- end # def selectable_products
340
-
341
- =begin rdoc
342
-
343
- ==== Bugzilla::Product#enterable_products
344
-
345
- Returns the products that the user can enter bugs against
346
- as Hash contains the product name as the Hash key and Array
347
- as the value. Array contains the list of _id_, _name_,
348
- _description_ and _internals_ according to API documentation
349
- though, actually the component, the version and the target
350
- milestone.
351
-
352
- =end
353
-
354
- def enterable_products
355
- ids = get_enterable_products
356
- get(ids)
357
- end # def enterable_products
358
-
359
- =begin rdoc
360
-
361
- ==== Bugzilla::Product#accessible_products
362
-
363
- Returns the products that the user can search or enter bugs
364
- against as Hash contains the product name as the Hash key
365
- and Array as the value. Array contains the list of _id_,
366
- _name_, _description_ and _internals_ according to API
367
- documentation though, actually the component, the version
368
- and the target milestone.
369
-
370
- =end
371
-
372
- def accessible_products
373
- ids = get_accessible_products
374
- get(ids)
375
- end # def accessible_products
376
-
377
- =begin rdoc
378
-
379
- ==== Bugzilla::Product#get_selectable_products
380
-
381
- Raw Bugzilla API to obtain the products that the user can
382
- search on.
383
-
384
- See http://www.bugzilla.org/docs/tip/en/html/api/Bugzilla/WebService/Product.html
385
-
386
- =end
387
-
388
- =begin rdoc
389
-
390
- ==== Bugzilla::Product#get_enterable_products
391
-
392
- Raw Bugzilla API to obtain the products that the user can
393
- enter bugs against.
394
-
395
- See http://www.bugzilla.org/docs/tip/en/html/api/Bugzilla/WebService/Product.html
396
-
397
- =end
398
-
399
- =begin rdoc
400
-
401
- ==== Bugzilla::Product#get_accessible_products
402
-
403
- Raw Bugzilla API to obtain the products that the user can
404
- search or enter bugs against.
405
-
406
- See http://www.bugzilla.org/docs/tip/en/html/api/Bugzilla/WebService/Product.html
407
-
408
- =end
409
-
410
- protected
411
-
412
- def _get_selectable_products(cmd, *args)
413
- @iface.call(cmd)
414
- end # def _get_selectable_products
415
-
416
- def _get_enterable_products(cmd, *args)
417
- @iface.call(cmd)
418
- end # def _get_entrable_products
419
-
420
- def _get_accessible_products(cmd, *args)
421
- @iface.call(cmd)
422
- end # def _get_accessible_products
423
-
424
- def _get(cmd, ids, *args)
425
- params = {}
426
-
427
- if ids.kind_of?(Hash) then
428
- raise ArgumentError, sprintf("Invalid parameter: %s", ids.inspect) unless ids.include?('ids')
429
- params[:ids] = ids['ids']
430
- elsif ids.kind_of?(Array) then
431
- params[:ids] = ids
432
- else
433
- params[:ids] = [ids]
434
- end
435
-
436
- @iface.call(cmd, params)
437
- end # def _get
438
-
439
- end # class Product
440
-
441
- =begin rdoc
442
-
443
- === Bugzilla::Bug
444
-
445
- Bugzilla::Bug class is to access
446
- the Bugzilla::WebService::Bug API that allows you to file
447
- a new bug in Bugzilla or get information about bugs that
448
- have already been filed.
449
-
450
- =end
451
-
452
- class Bug < APITemplate
453
-
454
- FIELDS_SUMMARY = ["id", "product", "component", "status", "severity", "summary"]
455
- FIELDS_DETAILS = FIELDS_SUMMARY + ["assigned_to", "internals", "priority", "resolution"]
456
- FIELDS_ALL = ["alias", "assigned_to", "blocks", "cc", "classification",
457
- "component", "creation_time", "creator", "deadline",
458
- "depends_on", "dupe_of", "estimated_time", "groups",
459
- "id", "is_cc_accessible", "is_confirmed", "is_open",
460
- "is_creator_accessible", "keywords", "last_change_time",
461
- "op_sys", "platform", "priority", "product", "qa_contact",
462
- "remaining_time", "resolution", "see_also", "severity",
463
- "status", "summary", "target_milestone", "update_token",
464
- "url", "version", "whiteboard",
465
- "external_bugs", "internals"]
466
-
467
- =begin rdoc
468
-
469
- ==== Bugzilla::Bug#get_bugs(bugs, fields = Bugzilla::Bug::FIELDS_SUMMARY)
470
-
471
- Get the _bugs_ information from Bugzilla. either of String
472
- or Numeric or Array would be acceptable for _bugs_. you can
473
- specify the fields you want to look up with _fields_.
474
-
475
- FWIW this name conflicts to Bugzilla API but this isn's a
476
- primitive method since get_bugs method in WebService API is
477
- actually deprecated.
478
-
479
- =end
480
-
481
- def get_bugs(bugs, fields = ::Bugzilla::Bug::FIELDS_SUMMARY)
482
- params = {}
483
-
484
- if bugs.kind_of?(Array) then
485
- params['ids'] = bugs
486
- elsif bugs.kind_of?(Integer) ||
487
- bugs.kind_of?(String) then
488
- params['ids'] = [bugs]
489
- else
490
- raise ArgumentError, sprintf("Unknown type of arguments: %s", bugs.class)
491
- end
492
- unless fields.nil? then
493
- unless (fields - ::Bugzilla::Bug::FIELDS_ALL).empty? then
494
- raise ArgumentError, sprintf("Invalid fields: %s", (::Bugzilla::Bug::FIELDS_ALL - fields).join(' '))
495
- end
496
- params['include_fields'] = fields
497
- end
498
-
499
- result = get(params)
500
-
501
- if fields.nil? || fields == ::Bugzilla::Bug::FIELDS_ALL then
502
- get_comments(bugs).each do |id, c|
503
- result['bugs'].each do |r|
504
- if r['id'].to_s == id then
505
- r['comments'] = c['comments']
506
- r['comments'] = [] if r['comments'].nil?
507
- break
508
- end
509
- end
510
- end
511
- end
512
-
513
- # 'bugs' is only in interests.
514
- # XXX: need to deal with 'faults' ?
515
- result['bugs']
516
- end # def get_bugs
517
-
518
- =begin rdoc
519
-
520
- ==== Bugzilla::Bug#get_comments(bugs)
521
-
522
- =end
523
-
524
- def get_comments(bugs)
525
- params = {}
526
-
527
- if bugs.kind_of?(Array) then
528
- params['ids'] = bugs
529
- elsif bugs.kind_of?(Integer) ||
530
- bugs.kind_of?(String) then
531
- params['ids'] = [bugs]
532
- else
533
- raise ArgumentError, sprintf("Unknown type of arguments: %s", bugs.class)
534
- end
535
-
536
- result = comments(params)
537
-
538
- # not supporting comment_ids. so drop "comments".
539
- result['bugs']
540
- end # def get_comments
541
-
542
- =begin rdoc
543
-
544
- ==== Bugzilla::Bug#fields(params)
545
-
546
- Raw Bugzilla API to obtain the information about valid bug
547
- fields, including the lists of legal values for each field.
548
-
549
- See http://www.bugzilla.org/docs/tip/en/html/api/Bugzilla/WebService/Bug.html
550
-
551
- =end
552
-
553
- =begin rdoc
554
-
555
- ==== Bugzilla::Bug#legal_values(params)
556
-
557
- Raw Bugzilla API to obtain the information what values are
558
- allowed for a particular field.
559
-
560
- See http://www.bugzilla.org/docs/tip/en/html/api/Bugzilla/WebService/Bug.html
561
-
562
- =end
563
-
564
- =begin rdoc
565
-
566
- ==== Bugzilla::Bug#attachments(params)
567
-
568
- Raw Bugzilla API to obtain the information about
569
- attachments, given a list of bugs and/or attachment ids.
570
-
571
- See http://www.bugzilla.org/docs/tip/en/html/api/Bugzilla/WebService/Bug.html
572
-
573
- =end
574
-
575
- =begin rdoc
576
-
577
- ==== Bugzilla::Bug#comments(params)
578
-
579
- Raw Bugzilla API to obtain the information about comments,
580
- given a list of bugs and/or comment ids.
581
-
582
- See http://www.bugzilla.org/docs/tip/en/html/api/Bugzilla/WebService/Bug.html
583
-
584
- =end
585
-
586
- =begin rdoc
587
-
588
- ==== Bugzilla::Bug#get(params)
589
-
590
- Raw Bugzilla API to obtain the information about particular
591
- bugs in the database.
592
-
593
- =end
594
-
595
- =begin rdoc
596
-
597
- ==== Bugzilla::Bug#history(params)
598
-
599
- Raw Bugzilla API to obtain the history of changes for
600
- particular bugs in the database.
601
-
602
- =end
603
-
604
- =begin rdoc
605
-
606
- ==== Bugzilla::Bug#search(params)
607
-
608
- Raw Bugzilla API to search for bugs based on particular
609
- criteria.
610
-
611
- =end
612
-
613
- protected
614
-
615
- def _fields(cmd, *args)
616
- requires_version(cmd, 3.6)
617
- params = {}
618
-
619
- if args[0].kind_of?(Array) then
620
- x = args[0].map {|x| x.kind_of?(Integer)}.uniq
621
- if x.length == 1 && x[0] then
622
- params['ids'] = args[0]
623
- else
624
- x = args[0].map {|x| x.kind_of?(String)}.uniq
625
- if x.length == 1 && x[0] then
626
- params['names'] = args[0]
627
- end
628
- end
629
- elsif args[0].kind_of?(Hash) then
630
- params = args[0]
631
- elsif args[0].kind_of?(Integer) then
632
- params['ids'] = [args[0]]
633
- elsif args[0].kind_of?(String) then
634
- params['names'] = [args[0]]
635
- elsif args[0].nil? then
636
- else
637
- raise ArgumentError, "Invalid parameters"
638
- end
639
-
640
- @iface.call(cmd, params)
641
- end # def _fields
642
-
643
- def _legal_values(cmd, *args)
644
- raise ArgumentError, "Invalid parameters" unless args[0].kind_of?(Hash)
645
-
646
- @iface.call(cmd, args[0])
647
- end # def _legal_values
648
-
649
- def _attachments(cmd, *args)
650
- requires_version(cmd, 3.6)
651
-
652
- raise ArgumentError, "Invalid parameters" unless args[0].kind_of?(Hash)
653
-
654
- @iface.call(cmd, args[0])
655
- end # def _attachments
656
-
657
- def _comments(cmd, *args)
658
- requires_version(cmd, 3.4)
659
-
660
- raise ArgumentError, "Invalid parameters" unless args[0].kind_of?(Hash)
661
-
662
- @iface.call(cmd, args[0])
663
- end # def _comments
664
-
665
- def _get(cmd, *args)
666
- params = {}
667
-
668
- if args[0].kind_of?(Hash) then
669
- params = args[0]
670
- elsif args[0].kind_of?(Array) then
671
- params['ids'] = args[0]
672
- elsif args[0].kind_of?(Integer) ||
673
- args[0].kind_of?(String) then
674
- params['ids'] = [args[0]]
675
- else
676
- raise ArgumentError, "Invalid parameters"
677
- end
678
- if check_version(3.4)[0] then
679
- params['permissive'] = true
680
- end
681
-
682
- @iface.call(cmd, params)
683
- end # def _get
684
-
685
- def _history(cmd, *args)
686
- requires_version(cmd, 3.4)
687
-
688
- params = {}
689
-
690
- if args[0].kind_of?(Hash) then
691
- params = args[0]
692
- elsif args[0].kind_of?(Array) then
693
- params['ids'] = args[0]
694
- elsif args[0].kind_of?(Integer) ||
695
- args[0].kind_of?(String) then
696
- params['ids'] = [args[0]]
697
- else
698
- raise ArgumentError, "Invalid parameters"
699
- end
700
-
701
- @iface.call(cmd, params)
702
- end # def _history
703
-
704
- def _search(cmd, *args)
705
- requires_version(cmd, 3.4)
706
-
707
- raise ArgumentError, "Invalid parameters" unless args[0].kind_of?(Hash)
708
-
709
- @iface.call(cmd, args[0])
710
- end # def _search
711
-
712
- def __create(cmd, *args)
713
- # FIXME
714
- end # def _create
715
-
716
- def __add_attachment(cmd, *args)
717
- requires_version(cmd, 4.0)
718
- # FIXME
719
- end # def _add_attachment
720
-
721
- def __add_comment(cmd, *args)
722
- requires_version(cmd, 3.2)
723
- # FIXME
724
- end # def _add_comment
725
-
726
- def __update(cmd, *args)
727
- requires_version(cmd, 4.0)
728
- # FIXME
729
- end # def _update
730
-
731
- def __update_see_also(cmd, *args)
732
- requires_version(cmd, 3.4)
733
- # FIXME
734
- end # def _update_see_also
735
-
736
- end # class Bug
737
-
738
- =begin rdoc
739
-
740
- === Bugzilla::User
741
-
742
- Bugzilla::User class is to access the
743
- Bugzilla::WebService::User API that allows you to create
744
- User Accounts and log in/out using an existing account.
745
-
746
- =end
747
-
748
- class User < APITemplate
749
-
750
- =begin rdoc
751
-
752
- ==== Bugzilla::User#session(user, password)
753
-
754
- Keeps the bugzilla session during doing something in the block.
755
-
756
- =end
757
-
758
- def session(user, password)
759
- fname = File.join(ENV['HOME'], '.ruby-bugzilla-cookie.yml')
760
- if File.exist?(fname) && File.lstat(fname).mode & 0600 == 0600 then
761
- conf = YAML.load(File.open(fname).read)
762
- host = @iface.instance_variable_get(:@xmlrpc).instance_variable_get(:@host)
763
- cookie = conf[host]
764
- unless cookie.nil? then
765
- @iface.cookie = cookie
766
- print "Using cookie\n"
767
- yield
768
- conf[host] = @iface.cookie
769
- File.open(fname, 'w') {|f| f.chmod(0600); f.write(conf.to_yaml)}
770
- return
771
- end
772
- end
773
- if user.nil? || password.nil? then
774
- yield
775
- else
776
- login({'login'=>user, 'password'=>password, 'remember'=>true})
777
- yield
778
- logout
779
- end
780
-
781
- end # def session
782
-
783
- =begin rdoc
784
-
785
- ==== Bugzilla::User#login(params)
786
-
787
- Raw Bugzilla API to log into Bugzilla.
788
-
789
- =end
790
-
791
- =begin rdoc
792
-
793
- ==== Bugzilla::User#logout
794
-
795
- Raw Bugzilla API to log out the user.
796
-
797
- =end
798
-
799
- protected
800
-
801
- def _login(cmd, *args)
802
- raise ArgumentError, "Invalid parameters" unless args[0].kind_of?(Hash)
803
-
804
- @iface.call(cmd,args[0])
805
- end # def _login
806
-
807
- def _logout(cmd, *args)
808
- @iface.call(cmd)
809
- end # def _logout
810
-
811
- def __offer_account_by_email(cmd, *args)
812
- # FIXME
813
- end # def _offer_account_by_email
814
-
815
- def __create(cmd, *args)
816
- # FIXME
817
- end # def _create
818
-
819
- def __get(cmd, *args)
820
- requires_version(cmd, 3.4)
821
- # FIXME
822
- end # def _get
823
-
824
- end # class User
825
-
826
- end # module Bugzilla