spqr 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,64 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # Constants for SQPR
4
+ #
5
+ # Copyright (c) 2009 Red Hat, Inc.
6
+ #
7
+ # Author: William Benton (willb@redhat.com)
8
+ #
9
+ # Licensed under the Apache License, Version 2.0 (the "License");
10
+ # you may not use this file except in compliance with the License.
11
+ # You may obtain a copy of the License at
12
+ #
13
+ # http://www.apache.org/licenses/LICENSE-2.0
14
+
15
+ module SPQR
16
+
17
+ module XmlConstants
18
+ Type = {
19
+ 'absTime' => 'Qmf::TYPE_ABSTIME',
20
+ 'array' => 'Qmf::TYPE_ARRAY', # XXX: is this right?
21
+ 'bool' => 'Qmf::TYPE_BOOL',
22
+ 'deltaTime' => 'Qmf::TYPE_DELTATIME',
23
+ 'double' => 'Qmf::TYPE_DOUBLE',
24
+ 'float' => 'Qmf::TYPE_FLOAT',
25
+ 'int16' => 'Qmf::TYPE_INT16',
26
+ 'int32' => 'Qmf::TYPE_INT32',
27
+ 'int64' => 'Qmf::TYPE_INT64',
28
+ 'int' => 'Qmf::TYPE_INT64',
29
+ 'int8' => 'Qmf::TYPE_INT8',
30
+ 'list' => 'Qmf::TYPE_LIST', # XXX: is this right?
31
+ 'lstr' => 'Qmf::TYPE_LSTR',
32
+ 'string' => 'Qmf::TYPE_LSTR',
33
+ 'map' => 'Qmf::TYPE_MAP',
34
+ 'objId' => 'Qmf::TYPE_REF',
35
+ 'sstr' => 'Qmf::TYPE_SSTR',
36
+ 'uint16' => 'Qmf::TYPE_UINT16',
37
+ 'uint32' => 'Qmf::TYPE_UINT32',
38
+ 'uint64' => 'Qmf::TYPE_UINT64',
39
+ 'uint' => 'Qmf::TYPE_UINT64',
40
+ 'uint8' => 'Qmf::TYPE_UINT8',
41
+ 'uuid' => 'Qmf::TYPE_UUID'
42
+ }
43
+
44
+ Access = {
45
+ "RC" => 'Qmf::ACCESS_READ_CREATE',
46
+ "RW" => 'Qmf::ACCESS_READ_WRITE',
47
+ "RO" => 'Qmf::ACCESS_READ_ONLY',
48
+ "R" => 'Qmf::ACCESS_READ_ONLY'
49
+ }
50
+
51
+ Direction = {
52
+ "I" => 'Qmf::DIR_IN',
53
+ "O" => 'Qmf::DIR_OUT',
54
+ "IO" => 'Qmf::DIR_IN_OUT',
55
+ "i" => 'Qmf::DIR_IN',
56
+ "o" => 'Qmf::DIR_OUT',
57
+ "io" => 'Qmf::DIR_IN_OUT',
58
+ "in" => 'Qmf::DIR_IN',
59
+ "out" => 'Qmf::DIR_OUT',
60
+ "inout" => 'Qmf::DIR_IN_OUT'
61
+ }
62
+ end
63
+
64
+ end
@@ -0,0 +1,222 @@
1
+ # SPQR: Schema Processor for QMF/Ruby agents
2
+ #
3
+ # Manageable object mixin and support classes.
4
+ #
5
+ # Copyright (c) 2009 Red Hat, Inc.
6
+ #
7
+ # Author: William Benton (willb@redhat.com)
8
+ #
9
+ # Licensed under the Apache License, Version 2.0 (the "License");
10
+ # you may not use this file except in compliance with the License.
11
+ # You may obtain a copy of the License at
12
+ #
13
+ # http://www.apache.org/licenses/LICENSE-2.0
14
+
15
+ module SPQR
16
+ class ManageableMeta < Struct.new(:classname, :package, :description, :mmethods, :options, :statistics, :properties)
17
+ def initialize(*a)
18
+ super *a
19
+ self.options = (({} unless self.options) or self.options.dup)
20
+ self.statistics = [] unless self.statistics
21
+ self.properties = [] unless self.properties
22
+ self.mmethods ||= []
23
+ end
24
+
25
+ def declare_method(name, desc, options, blk=nil)
26
+ result = MethodMeta.new name, desc, options
27
+ blk.call(result.args) if blk
28
+ self.mmethods << result
29
+ self.mmethods[-1]
30
+ end
31
+
32
+ def declare_statistic(name, kind, options)
33
+ declare_basic(:statistic, name, kind, options)
34
+ end
35
+
36
+ def declare_property(name, kind, options)
37
+ declare_basic(:property, name, kind, options)
38
+ end
39
+
40
+ private
41
+ def declare_basic(what, name, kind, options)
42
+ what_plural = "#{what.to_s.gsub(/y$/, 'ie')}s"
43
+ w_get = what_plural.to_sym
44
+ w_set = "#{what_plural}=".to_sym
45
+
46
+ self.send(w_set, (self.send(w_get) or []))
47
+
48
+ w_class = "#{what.to_s.capitalize}Meta"
49
+ self.send(w_get) << SPQR.const_get(w_class).new(name, kind, options)
50
+ end
51
+ end
52
+
53
+ class MethodMeta < Struct.new(:name, :description, :args, :options)
54
+ def initialize(*a)
55
+ super *a
56
+ self.options = (({} unless self.options) or self.options.dup)
57
+ self.args = gen_args
58
+ end
59
+
60
+ private
61
+ def gen_args
62
+ result = []
63
+
64
+ def result.declare(name, kind, direction, description=nil, options=nil)
65
+ options ||= {}
66
+ arg = ::SPQR::ArgMeta.new name, kind, direction, description, options.dup
67
+ self << arg
68
+ end
69
+
70
+ result
71
+ end
72
+ end
73
+
74
+ class ArgMeta < Struct.new(:name, :kind, :direction, :description, :options)
75
+ def initialize(*a)
76
+ super *a
77
+ self.options = (({} unless self.options) or self.options.dup)
78
+ end
79
+ end
80
+
81
+ class PropertyMeta < Struct.new(:name, :kind, :options)
82
+ def initialize(*a)
83
+ super *a
84
+ self.options = (({} unless self.options) or self.options.dup)
85
+ end
86
+ end
87
+
88
+ class StatisticMeta < Struct.new(:name, :kind, :options)
89
+ def initialize(*a)
90
+ super *a
91
+ self.options = (({} unless self.options) or self.options.dup)
92
+ end
93
+ end
94
+
95
+ module ManageableClassMixins
96
+ def spqr_meta
97
+ @spqr_meta ||= ::SPQR::ManageableMeta.new
98
+ end
99
+
100
+ def spqr_logger=(logger)
101
+ @spqr_log = logger
102
+ end
103
+
104
+ def spqr_logger
105
+ @spqr_log || ::SPQR::Sink.new
106
+ end
107
+
108
+ # Exposes a method to QMF
109
+ def spqr_expose(name, description=nil, options=nil, &blk)
110
+ spqr_meta.declare_method(name, description, options, blk)
111
+ end
112
+
113
+ def spqr_package(nm)
114
+ spqr_meta.package = nm
115
+ end
116
+
117
+ def spqr_class(nm)
118
+ spqr_meta.classname = nm
119
+ end
120
+
121
+ def spqr_description(d)
122
+ spqr_meta.description = d
123
+ end
124
+
125
+ def spqr_options(opts)
126
+ spqr_meta.options = opts.dup
127
+ end
128
+
129
+ def spqr_statistic(name, kind, options=nil)
130
+ spqr_meta.declare_statistic(name, kind, options)
131
+
132
+ self.class_eval do
133
+ # XXX: are we only interested in declaring a reader for
134
+ # statistics? Doesn't it really makes more sense for the managed
135
+ # class to declare a method with the same name as the
136
+ # statistic so we aren't declaring anything at all here?
137
+
138
+ # XXX: should cons up a "safe_attr_reader" method that works
139
+ # like this:
140
+ attr_reader name.to_sym unless instance_methods.include? "#{name}"
141
+ attr_writer name.to_sym unless instance_methods.include? "#{name}="
142
+ end
143
+ end
144
+
145
+ def spqr_property(name, kind, options=nil)
146
+ spqr_meta.declare_property(name, kind, options)
147
+
148
+ # add a property accessor to instances of other
149
+ self.class_eval do
150
+ # XXX: should cons up a "safe_attr_accessor" method that works like this:
151
+ attr_reader name.to_sym unless instance_methods.include? "#{name}"
152
+ attr_writer name.to_sym unless instance_methods.include? "#{name}="
153
+ end
154
+
155
+ if options and options[:index]
156
+ # if this is an index property, add a find-by method if one
157
+ # does not already exist
158
+ spqr_define_index_find(name)
159
+ end
160
+ end
161
+
162
+ private
163
+ def spqr_define_index_find(name)
164
+ find_by_prop = "find_by_#{name}".to_sym
165
+
166
+ return if self.respond_to? find_by_prop
167
+
168
+ define_method find_by_prop do |arg|
169
+ raise "#{self} must define find_by_#{name}(arg)"
170
+ end
171
+ end
172
+ end
173
+
174
+ module Manageable
175
+ def qmf_oid
176
+ result = 0
177
+ if self.respond_to? :spqr_object_id
178
+ result = spqr_object_id
179
+ else
180
+ result = object_id
181
+ end
182
+
183
+ result & 0x7fffffff
184
+ end
185
+
186
+ def qmf_id
187
+ [qmf_oid, self.class.class_id]
188
+ end
189
+
190
+ def log
191
+ self.class.spqr_logger
192
+ end
193
+
194
+ def self.included(other)
195
+ class << other
196
+ include ManageableClassMixins
197
+ end
198
+
199
+ unless other.respond_to? :find_by_id
200
+ def other.find_by_id(id)
201
+ raise "#{self} must define find_by_id(id)"
202
+ end
203
+ end
204
+
205
+ unless other.respond_to? :find_all
206
+ def other.find_all
207
+ raise "#{self} must define find_all"
208
+ end
209
+ end
210
+
211
+ unless other.respond_to? :class_id
212
+ def other.class_id
213
+ package_list = spqr_meta.package.to_s.split(".")
214
+ cls = spqr_meta.classname.to_s or self.name.to_s
215
+ ((package_list.map {|pkg| pkg.capitalize} << cls).join("::")).hash & 0x7fffffff
216
+ end
217
+ end
218
+
219
+ other.spqr_class other.name.to_sym
220
+ end
221
+ end
222
+ end
data/lib/spqr/spqr.rb ADDED
@@ -0,0 +1,16 @@
1
+ # SPQR: Schema Processor for QMF/Ruby agents
2
+ #
3
+ # Copyright (c) 2009 Red Hat, Inc.
4
+ #
5
+ # Author: William Benton (willb@redhat.com)
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+
13
+ require 'spqr/utils'
14
+ require 'spqr/constants'
15
+ require 'spqr/codegen'
16
+ require 'spqr/manageable'
data/lib/spqr/utils.rb ADDED
@@ -0,0 +1,88 @@
1
+ # Utility functions and modules for SPQR
2
+ #
3
+ # Copyright (c) 2009 Red Hat, Inc.
4
+ #
5
+ # Author: William Benton (willb@redhat.com)
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+
13
+ module SPQR
14
+ class Sink
15
+ def method_missing(*args)
16
+ yield if block_given?
17
+ nil
18
+ end
19
+ end
20
+
21
+ module PrettyPrinter
22
+ def writemode
23
+ $PP_WRITEMODE ||= File::WRONLY|File::CREAT|File::TRUNC
24
+ end
25
+
26
+ def stack
27
+ @fstack ||= [STDOUT]
28
+ end
29
+
30
+ def inc_indent
31
+ @indent = indent + 2
32
+ end
33
+
34
+ def dec_indent
35
+ @indent = indent - 2
36
+ end
37
+
38
+ def indent
39
+ @indent ||= 0
40
+ end
41
+
42
+ def outfile
43
+ @fstack[-1] or STDOUT
44
+ end
45
+
46
+ def pp(s)
47
+ outfile.puts "#{' ' * indent}#{s}\n"
48
+ end
49
+
50
+ def pp_decl(kind, name, etc=nil)
51
+ pp "#{kind} #{name}#{etc}"
52
+ inc_indent
53
+ yield if block_given?
54
+ dec_indent
55
+ pp "end"
56
+ end
57
+
58
+ def pp_call(callable, args)
59
+ arg_repr = args.map {|arg| (arg.inspect if arg.kind_of? Hash) or arg}.join(', ')
60
+ pp "#{callable}(#{arg_repr})"
61
+ end
62
+
63
+ def pp_invoke(receiver, method, args)
64
+ pp_call "#{receiver}.#{method}", args
65
+ end
66
+
67
+ def with_output_to(filename, &action)
68
+ File::open(filename, writemode) do |of|
69
+ stack << of
70
+ action.call
71
+ stack.pop
72
+ end
73
+ end
74
+ end
75
+
76
+ module MiscUtil
77
+ def symbolize_dict(k, kz=nil)
78
+ k2 = {}
79
+ kz ||= k.keys
80
+
81
+ k.keys.each do |key|
82
+ k2[key.to_sym] = k[key] if (kz.include?(key) or kz.include?(key.to_sym))
83
+ end
84
+
85
+ k2
86
+ end
87
+ end
88
+ end
data/spec/spec.opts ADDED
@@ -0,0 +1 @@
1
+ --color
@@ -0,0 +1,9 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
+ require 'spqr/spqr'
4
+ require 'spec'
5
+ require 'spec/autorun'
6
+
7
+ Spec::Runner.configure do |config|
8
+
9
+ end
data/spec/spqr_spec.rb ADDED
@@ -0,0 +1,5 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ module SPQR
4
+
5
+ end
data/spqr.spec.in ADDED
@@ -0,0 +1,95 @@
1
+ # Generated from <%= File::basename(format.gem_path) %> by gem2rpm -*- rpm-spec -*-
2
+ %define ruby_sitelib %(ruby -rrbconfig -e "puts Config::CONFIG['sitelibdir']")
3
+ %define gemdir %(ruby -rubygems -e 'puts Gem::dir' 2>/dev/null)
4
+ %define gemname <%= spec.name %>
5
+ %define geminstdir %{gemdir}/gems/%{gemname}-%{version}
6
+
7
+ Summary: <%= spec.summary.gsub(/\.$/, "") %>
8
+ Name: rubygem-%{gemname}
9
+ Version: <%= spec.version %>
10
+ Release: 1%{?dist}
11
+ Group: Development/Languages
12
+ License: ASL 2.0
13
+ URL: <%= spec.homepage %>
14
+ Source0: <%= download_path %>%{gemname}-%{version}.gem
15
+ BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
16
+ Requires: rubygems
17
+ Requires: ruby(abi) = 1.8
18
+ Requires: ruby-qmf
19
+ <% for d in spec.dependencies %>
20
+ <% for req in d.version_requirements.to_rpm %>
21
+ Requires: rubygem(<%= d.name %>) <%= req %>
22
+ <% end %>
23
+ <% end %>
24
+ BuildRequires: ruby > 1.8
25
+ BuildRequires: rubygems
26
+ <% if spec.extensions.empty? %>
27
+ BuildArch: noarch
28
+ <% end %>
29
+ Provides: rubygem(%{gemname}) = %{version}
30
+
31
+ %description
32
+ <%= spec.description.to_s.chomp.word_wrap(78) + "\n" %>
33
+
34
+ <% if nongem %>
35
+ %package -n ruby-%{gemname}
36
+ Summary: <%= spec.summary.gsub(/\.$/, "") %>
37
+ Group: Development/Languages
38
+ Requires: rubygem(%{gemname}) = %{version}
39
+ <% spec.files.select{ |f| spec.require_paths.include?(File::dirname(f)) }.reject { |f| f =~ /\.rb$/ }.collect { |f| File::basename(f) }.each do |p| %>
40
+ Provides: ruby(<%= p %>) = %{version}
41
+ <% end %>
42
+ %description -n ruby-%{gemname}
43
+ <%= spec.description.to_s.chomp.word_wrap(78) + "\n" %>
44
+ <% end # if nongem %>
45
+
46
+ %prep
47
+
48
+ %build
49
+
50
+ %install
51
+ rm -rf %{buildroot}
52
+ mkdir -p %{buildroot}%{gemdir}
53
+ <% rdoc_opt = spec.has_rdoc ? "--rdoc " : "" %>
54
+ gem install --local --install-dir %{buildroot}%{gemdir} \
55
+ --force <%= rdoc_opt %>%{SOURCE0}
56
+ <% unless spec.executables.empty? %>
57
+ mkdir -p %{buildroot}/%{_bindir}
58
+ mv %{buildroot}%{gemdir}/bin/* %{buildroot}/%{_bindir}
59
+ rmdir %{buildroot}%{gemdir}/bin
60
+ find %{buildroot}%{geminstdir}/bin -type f | xargs chmod a+x
61
+ <% end %>
62
+ <% if nongem %>
63
+ mkdir -p %{buildroot}%{ruby_sitelib}
64
+ <% spec.files.select{ |f| spec.require_paths.include?(File::dirname(f)) }.each do |p| %>
65
+ ln -s %{gemdir}/gems/%{gemname}-%{version}/<%= p %> %{buildroot}%{ruby_sitelib}
66
+ <% end %>
67
+ <% end # if nongem %>
68
+
69
+ %clean
70
+ rm -rf %{buildroot}
71
+
72
+ %files
73
+ %defattr(-, root, root, -)
74
+ <% for f in spec.executables %>
75
+ %{_bindir}/<%= f %>
76
+ <% end %>
77
+ %{gemdir}/gems/%{gemname}-%{version}/
78
+ <% if spec.has_rdoc %>
79
+ %doc %{gemdir}/doc/%{gemname}-%{version}
80
+ <% end %>
81
+ <% for f in spec.extra_rdoc_files %>
82
+ %doc %{geminstdir}/<%= f %>
83
+ <% end %>
84
+ %{gemdir}/cache/%{gemname}-%{version}.gem
85
+ %{gemdir}/specifications/%{gemname}-%{version}.gemspec
86
+
87
+ <% if nongem %>
88
+ %files -n ruby-%{gemname}
89
+ %defattr(-, root, root, -)
90
+ %{ruby_sitelib}/*
91
+ <% end # if nongem %>
92
+
93
+ %changelog
94
+ * <%= Time.now.strftime("%a %b %d %Y") %> <%= packager %> - <%= spec.version %>-1
95
+ - Initial package