workEnv 0.1.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.
@@ -0,0 +1,206 @@
1
+ # coding: utf-8
2
+ module WorkEnvs
3
+ # Class to store all the dependencies of an env
4
+ #
5
+ # It provides helpers to convert between version names and sha1
6
+ #
7
+ # Dependencies can come from multiple sources
8
+ # - rev_files
9
+ # - --sha1, --sub-sha1 options
10
+ # - --version option
11
+ # - Package (RPM, Deb) dependencies
12
+ #
13
+ # Dependencies from env to its version (and its subEnv versions) are stored
14
+ # as depInfo hash:
15
+ #
16
+ # { :sha1 => <sha1>, :version => <version> }
17
+ class Dependencies
18
+ # Mark the environment as partial. (default = false)
19
+ #
20
+ # It means that it is OK for some environment class
21
+ # from the env dependency tree to not have any dep_info to them
22
+ attr_accessor :partialEnv
23
+
24
+ # Flag enable by setting WENV_IGNORE_CONFLICTS (default = nil)
25
+ #
26
+ # Ignore if a dep_info is pushed to an envClass is different from
27
+ # a previous dep_info pushed for the same envClass
28
+ # In this case, the first on is kept.
29
+ #
30
+ # SEROUSLY DANGEROUS ! DON'T USE IT UNLESS YOU KNOW WHAT YOU'RE DOING !!!
31
+ attr_reader :ignore_conflicts
32
+
33
+ # Pointer to a PackageDownloader used to convert version and SHA1 (default = nil)
34
+ attr_accessor :downloader
35
+
36
+ # Hash of dep_infos (default = {})
37
+ attr_reader :deps
38
+
39
+ # Array of fields to query in the package DB
40
+ FIELDS = [ :sha1, :version ]
41
+
42
+ # Default constructor
43
+ def initialize
44
+ @deps = {}
45
+ @partialEnv = false
46
+ @ignore_conflicts = nil
47
+ @ignore_conflicts = true if ENV["WENV_IGNORE_CONFLICTS"].to_s != ""
48
+ @downloader = nil
49
+ end
50
+
51
+ # Internal function to add a dependency to deps
52
+ #
53
+ # - env is either the envType or an envClass
54
+ # - dInfos is a dep_info hash generated by PackageDownloader
55
+ #
56
+ # Returns:
57
+ # - true on success
58
+ # - false on failure if @ignore_conflicts == true
59
+ # Throws an exception on failure if @ignore_conflicts != true
60
+ def _push(env, dInfos)
61
+ name = (env.kind_of? Symbol) ? env : WorkEnvs::getEnvType(env)
62
+
63
+ WorkEnvs::dputs("Deps[#{name}] <= (#{dInfos.to_s})")
64
+
65
+ FIELDS.each(){|f|
66
+ raise("Incomplete dependency #{dInfos}. '#{f.to_s}' field is missing") if dInfos[f] == nil
67
+ }
68
+
69
+ if @deps[name] != nil then
70
+ if @deps[name] != dInfos then
71
+ return false if @ignore_conflicts == true
72
+
73
+ raise("Invalid dependencies for #{name}.\nRequire for #{name.to_s} both:\n"+
74
+ "\t* '#{@deps[name].to_s}'\n\t* '#{dInfos.to_s}' ")
75
+ end
76
+ end
77
+ @deps[name] = dInfos
78
+ return true
79
+ end
80
+ private :_push
81
+
82
+ # Convert an (envType, sha1) couple to a dep_info and add it to deps using #_push
83
+ #
84
+ # env is either the envType or an envClass
85
+ #
86
+ # Return _push result or false if required == false and no matching SHA1 was found
87
+ # in the DB
88
+ #
89
+ # Throws EmptyQueryException if required == true and no match was found
90
+ def push_sha1(env, sha1, required = true)
91
+ return false if sha1.to_s == ""
92
+ #SHA1 but no version
93
+ dInfos = @downloader.queryDepInfosFromSHA1(env, sha1, required)
94
+ return false if dInfos == nil
95
+ return _push(env, dInfos)
96
+ end
97
+
98
+ # Convert an (envType, version) couple to a dep_info and add it to deps using #_push
99
+ #
100
+ # env is either the envType or an envClass
101
+ #
102
+ # Return _push result or false if required == false and no matching version was found
103
+ # in the DB
104
+ #
105
+ # Throws EmptyQueryException if required == true and no match was found
106
+ def push_version(env, version, required = true)
107
+ return false if version.to_s == ""
108
+
109
+ #SHA1 but no version
110
+ dInfos = @downloader.queryDepInfosFromVersion(env, version, required)
111
+ return false if dInfos == nil
112
+ return _push(env, dInfos)
113
+ end
114
+
115
+ # Convert an (envType, package full name) couple to a dep_info and add it to deps using #_push
116
+ #
117
+ # env is either the envType or an envClass
118
+ #
119
+ # Return _push result or false if required == false and no matching package was found
120
+ # in the DB
121
+ #
122
+ # Throws EmptyQueryException if required == true and no match was found
123
+ def push_name(env, pName, required = true)
124
+ dInfos = @downloader.queryDepInfosFromName(env, pName, required)
125
+ return false if dInfos == nil
126
+ return _push(env, dInfos)
127
+ end
128
+
129
+ # Return if there is a dep_into to the envType name
130
+ def exists?(name)
131
+ return @deps[name] != nil
132
+ end
133
+
134
+ # Remove (if any) the dep_into to the envType name
135
+ def del(name)
136
+ return @deps[name] = nil
137
+ end
138
+
139
+ # Get the required version string for envType name
140
+ def get_version(name)
141
+ return nil if @deps[name] == nil
142
+ return @deps[name][:version]
143
+ end
144
+
145
+ # Get the required SHA1 string for envType name
146
+ def get_sha1(name)
147
+ return nil if @deps[name] == nil
148
+ return @deps[name][:sha1]
149
+ end
150
+
151
+ # Iterator on dep_infos
152
+ #
153
+ # Block args are (envType, dep_info)
154
+ def each()
155
+ @deps.each(){|name, h|
156
+ yield name, h
157
+ }
158
+ end
159
+
160
+ # Generates a string with a human reable list of all dep_infos
161
+ def to_s
162
+ str = ""
163
+ @deps.each(){|name, h|
164
+ str+= "\t" + name.to_s.ljust(20) + "=> " + h[:version].to_s + " (" + h[:sha1].to_s + ")\n"
165
+ }
166
+ return str
167
+ end
168
+
169
+ # Returns true if there is no dep_info
170
+ def empty?
171
+ return @deps.empty?
172
+ end
173
+
174
+ # Compare two Dependencies
175
+ #
176
+ # This make sure all dep_infos are the sames in the two
177
+ def ==(another)
178
+ begin
179
+ @deps.each(){|name, h|
180
+ return false if another.deps[name] != h
181
+ }
182
+ another.each(){|name, h|
183
+ return false if @deps[name] != h
184
+ }
185
+ return true
186
+ rescue => e
187
+ return false
188
+ end
189
+ end
190
+
191
+ # Concat another Dependencies object into this one
192
+ #
193
+ # Throws exception if both are incompatible
194
+ def concat(another)
195
+ if another != nil then
196
+ another.each(){|name, h|
197
+ _push(name, h)
198
+ }
199
+ if another.partialEnv == true
200
+ @partialEnv = true
201
+ end
202
+ end
203
+ return self
204
+ end
205
+ end
206
+ end
@@ -0,0 +1,129 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ module WorkEnvs
4
+
5
+ # Name of the no dkms options
6
+ WENV_OPTS_NODKMS = "nodkms"
7
+ # Help string for the no dkms options
8
+ WENV_OPTS_NODKMS_STRING =
9
+ "\t#{WENV_OPTS_NODKMS}=false Build DKMS modules"
10
+
11
+ # Name of the no eclipse options
12
+ WENV_OPTS_NOECLIPSE = "noeclipse"
13
+ # Help string for the no eclipse options
14
+ WENV_OPTS_NOECLIPSE_STRING =
15
+ "\t#{WENV_OPTS_NOECLIPSE}=true Do not install eclipse plugins"
16
+
17
+ # Name of the external options
18
+ WENV_OPTS_EXTERNAL = "external"
19
+ # Help string for the external options
20
+ WENV_OPTS_EXTERNAL_STRING =
21
+ "\t#{WENV_OPTS_EXTERNAL}=true Do not install internal packages "
22
+
23
+ # Name of the partial options
24
+ WENV_OPTS_PARTIAL = "partial"
25
+ # Help string for the partial options
26
+ WENV_OPTS_PARTIAL_STRING =
27
+ "\t#{WENV_OPTS_PARTIAL}=true Support partially checked out environment "
28
+
29
+ # Name of the remote install options
30
+ WENV_OPTS_REMOTE_INSTALL = "remote-install"
31
+ # Help string for the remote install options
32
+ WENV_OPTS_REMOTE_INSTALL_STRING =
33
+ "\t#{WENV_OPTS_REMOTE_INSTALL}=false Disable install of packages on remote "
34
+
35
+ # Name of the remote host options
36
+ WENV_OPTS_REMOTE_HOST_INSTALL = "remote-host"
37
+ # Help string for the remote host options
38
+ WENV_OPTS_REMOTE_HOST_INSTALL_STRING =
39
+ "\t#{WENV_OPTS_REMOTE_HOST_INSTALL}=<host> Install of packages on the specified remote host "
40
+
41
+ # Name of the const options
42
+ WENV_OPTS_CONST = "const"
43
+ # Help string for the const options
44
+ WENV_OPTS_CONST_STRING =
45
+ "\t#{WENV_OPTS_CONST}=true Remove all write rights to environment so it cannot be modified"
46
+
47
+ # Name of the sparse options
48
+ WENV_OPTS_SPARSE = "sparse"
49
+ # Help string for the sparse options
50
+ WENV_OPTS_SPARSE_STRING =
51
+ "\t#{WENV_OPTS_SPARSE}=true Sparse update of the env (skip some unneeded packages"
52
+
53
+ # Class to store envClass options
54
+ class EnvOpts
55
+ # Default constructor
56
+ def initialize
57
+ @opts = {}
58
+ end
59
+
60
+ # Iterates on all options set
61
+ #
62
+ # Block args are (option name, option val)
63
+ def each()
64
+ @opts.each(){|name, val|
65
+ yield name, val
66
+ }
67
+ end
68
+
69
+ # Returns true if there are no options set
70
+ def empty?
71
+ return @opts.empty?
72
+ end
73
+
74
+ # Returns the value of the option "name"
75
+ #
76
+ # Returns "" if the option was not set
77
+ def [](name)
78
+ return "" if @opts[name] == nil
79
+ return @opts[name]
80
+ end
81
+
82
+
83
+ # Set the value of the option "name"
84
+ #
85
+ # Returns its value
86
+ def []=(name, val)
87
+ @opts[name] = val
88
+ return val
89
+ end
90
+
91
+ # Parse an option string and add it to self
92
+ #
93
+ # String format is name=val
94
+ #
95
+ # val cannot contain an "=" symbol
96
+ def <<(string)
97
+ args = string.split("=")
98
+ raise("Unsupported option #{string}") if args.length != 2
99
+ @opts[args[0]] = args[1];
100
+ end
101
+
102
+ # Compare two EnvOpts
103
+ def ==(another)
104
+ begin
105
+ @opts.each(){|name, val|
106
+ return false if another[name] != val
107
+ }
108
+ another.each(){|name, val|
109
+ return false if @opts[name] != val
110
+ }
111
+ return true
112
+ rescue
113
+ return false
114
+ end
115
+ end
116
+
117
+ # Concat another EnvOpts into this one
118
+ #
119
+ # Value set in this one are NOT overwritten by the other one
120
+ def concat(another)
121
+ if another != nil then
122
+ another.each(){|name, val|
123
+ @opts[name] = val if @opts[name] == nil || @opts[name] == ""
124
+ }
125
+ end
126
+ return self
127
+ end
128
+ end
129
+ end
@@ -0,0 +1,116 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ module WorkEnvs
4
+ # Class to briefly describe a MAIN_PACKAGE of an envClass
5
+ #
6
+ # This is only used to get a list of possible MAIN_PACKAGE version
7
+ # of a given class to provide a human readable list of accessible package
8
+ class EnvPackage
9
+ # Full name of the package
10
+ attr_reader :name
11
+ # SHA1 that generated the package
12
+ attr_reader :sha1
13
+ # Package the branch was generated on
14
+ attr_reader :branch
15
+ # Additional info (timestamp usually) on the package
16
+ attr_reader :info
17
+
18
+ # Default Constructor
19
+ def initialize(name, sha1, branch, info)
20
+ @name = name
21
+ @sha1 = sha1
22
+ @branch = branch
23
+ @info = info
24
+ end
25
+
26
+ # Returns a human readable string of the package data
27
+ def to_s()
28
+ return "\t" + @name.to_s.ljust(65) + "\t" +
29
+ @sha1.to_s + "\t" +
30
+ @branch.to_s.ljust(40) +
31
+ @info.to_s
32
+ end
33
+ end
34
+
35
+ # Class to describe a package
36
+ class Package
37
+
38
+ # Package name (without version/release/etc)
39
+ #
40
+ # Also known as "project" in de DB
41
+ attr_accessor :name
42
+ # Package attributes (default = {}
43
+ #
44
+ # Currently supported attributes:
45
+ # - :install
46
+ # - :dkms : Packet is installed during an env update when --install-dkms is set
47
+ # - :install: Packet is always installed during an env update. SHOULD NOT BE SET
48
+ # - :keep : Package is kept after download/extraction event if keep-packages is not set
49
+ attr_accessor :attributes
50
+ # Full package name (ie name-version-release.rpm)
51
+ attr_accessor :pack
52
+ # Full path to the package
53
+ attr_accessor :path
54
+
55
+ # Default constructor
56
+ def initialize(name, attributes = {}, pack=nil)
57
+ @name = name
58
+ @attributes = attributes
59
+ @pack = pack
60
+ @path = nil
61
+ end
62
+
63
+ # Returns the package name
64
+ def to_s()
65
+ return @name
66
+ end
67
+
68
+ # Compare two Package objects themselves (not the content)
69
+ #
70
+ # Used for sorting
71
+ def eql?(other)
72
+ return self == other
73
+ end
74
+
75
+ # Compare two Package objects values
76
+ def ==(other)
77
+ return false if other == nil
78
+ return self.hash() == other.hash()
79
+ end
80
+
81
+ # Spaceship operation
82
+ #
83
+ # Calls <=> on full package names
84
+ #
85
+ # Used for sorting
86
+ def <=>(other)
87
+ return @pack <=> other.pack()
88
+ end
89
+
90
+ # Returns a Package hash
91
+ #
92
+ # Used for sorting
93
+ def hash()
94
+ return { :name => @name, :attributes => @attributes, :pack => @pack, :path => @path }.hash()
95
+ end
96
+
97
+ # Returns true if the package should be installed
98
+ #
99
+ # A package should be installed if:
100
+ # - it has the attribute :install == true
101
+ # - it has the attribute :install == :dkms and :installDKMS options is set
102
+ def shouldInstall(opts)
103
+ return @attributes[:install] == true ||
104
+ ( @attributes[:install] == :dkms && opts[:installDKMS] == true)
105
+ end
106
+
107
+ # Returns true if the package should be kept after download/extraction
108
+ #
109
+ # A package should be kept if:
110
+ # - it has the attribute :keep == true
111
+ # - it the :keepPackages options is set
112
+ def shouldKeep(opts)
113
+ return @attributes[:keep] == true || opts[:keepPackages] == true
114
+ end
115
+ end
116
+ end