travis-yaml 0.1.0 → 0.2.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.
- checksums.yaml +4 -4
- data/.travis.yml +3 -8
- data/Gemfile +3 -6
- data/Gemfile.lock +20 -50
- data/README.md +97 -2
- data/SPEC.md +116 -33
- data/lib/travis/yaml.rb +6 -3
- data/lib/travis/yaml/matrix.rb +12 -17
- data/lib/travis/yaml/nodes.rb +4 -0
- data/lib/travis/yaml/nodes/addons.rb +44 -0
- data/lib/travis/yaml/nodes/android.rb +7 -0
- data/lib/travis/yaml/nodes/cache.rb +5 -3
- data/lib/travis/yaml/nodes/deploy_conditions.rb +2 -1
- data/lib/travis/yaml/nodes/deploy_entry.rb +46 -0
- data/lib/travis/yaml/nodes/dist.rb +6 -0
- data/lib/travis/yaml/nodes/env.rb +1 -1
- data/lib/travis/yaml/nodes/group.rb +6 -0
- data/lib/travis/yaml/nodes/language.rb +3 -2
- data/lib/travis/yaml/nodes/language_specific.rb +2 -2
- data/lib/travis/yaml/nodes/mapping.rb +39 -10
- data/lib/travis/yaml/nodes/node.rb +58 -1
- data/lib/travis/yaml/nodes/notifications.rb +10 -6
- data/lib/travis/yaml/nodes/open_mapping.rb +1 -1
- data/lib/travis/yaml/nodes/os.rb +1 -1
- data/lib/travis/yaml/nodes/os_entry.rb +7 -5
- data/lib/travis/yaml/nodes/root.rb +28 -4
- data/lib/travis/yaml/nodes/scalar.rb +16 -1
- data/lib/travis/yaml/nodes/sequence.rb +38 -0
- data/lib/travis/yaml/nodes/version.rb +13 -0
- data/lib/travis/yaml/nodes/version_list.rb +4 -0
- data/lib/travis/yaml/parser/psych.rb +11 -5
- data/lib/travis/yaml/secure_string.rb +35 -2
- data/lib/travis/yaml/serializer.rb +17 -0
- data/lib/travis/yaml/serializer/generic.rb +114 -0
- data/lib/travis/yaml/serializer/json.rb +72 -0
- data/lib/travis/yaml/serializer/legacy.rb +32 -0
- data/lib/travis/yaml/serializer/ruby.rb +13 -0
- data/lib/travis/yaml/serializer/yaml.rb +41 -0
- data/lib/travis/yaml/version.rb +1 -1
- data/play/spec.rb +24 -17
- data/spec/matrix_spec.rb +57 -0
- data/spec/nodes/addons_spec.rb +63 -0
- data/spec/nodes/cache_spec.rb +4 -4
- data/spec/nodes/deploy_spec.rb +12 -0
- data/spec/nodes/dist_spec.rb +11 -0
- data/spec/nodes/env_spec.rb +48 -0
- data/spec/nodes/git_spec.rb +1 -1
- data/spec/nodes/group_spec.rb +11 -0
- data/spec/nodes/node_js_spec.rb +14 -0
- data/spec/nodes/notifications_spec.rb +7 -0
- data/spec/nodes/os_spec.rb +13 -0
- data/spec/nodes/root_spec.rb +36 -0
- data/spec/nodes/secure_spec.rb +145 -0
- data/spec/parser/psych_spec.rb +6 -0
- data/spec/parser/ruby_spec.rb +1 -1
- data/spec/serializer/json_spec.rb +30 -0
- data/spec/serializer/legacy_spec.rb +47 -0
- data/spec/serializer/ruby_spec.rb +21 -0
- data/spec/serializer/yaml_spec.rb +47 -0
- data/spec/support/coverage.rb +9 -9
- data/spec/yaml_spec.rb +23 -0
- data/travis-yaml.gemspec +2 -3
- metadata +42 -22
- data/config.ru +0 -2
- data/play/weblint.rb +0 -296
data/lib/travis/yaml.rb
CHANGED
@@ -7,17 +7,20 @@ module Travis
|
|
7
7
|
require 'travis/yaml/nodes'
|
8
8
|
require 'travis/yaml/matrix'
|
9
9
|
require 'travis/yaml/parser'
|
10
|
+
require 'travis/yaml/serializer'
|
10
11
|
|
11
12
|
extend self
|
12
13
|
|
13
14
|
def parse(value)
|
14
|
-
Parser.parse(value)
|
15
|
+
result = Parser.parse(value)
|
16
|
+
yield result if block_given?
|
17
|
+
result
|
15
18
|
end
|
16
19
|
|
17
20
|
alias_method :load, :parse
|
18
21
|
|
19
|
-
def parse!(value, file_name = '.travis.yml')
|
20
|
-
result = parse(value)
|
22
|
+
def parse!(value, file_name = '.travis.yml', &block)
|
23
|
+
result = parse(value, &block)
|
21
24
|
result.nested_warnings.each do |key, message|
|
22
25
|
warn key.empty? ? "#{file_name}: #{message}" :
|
23
26
|
"#{file_name}: #{key.join(?.)} section - #{message}"
|
data/lib/travis/yaml/matrix.rb
CHANGED
@@ -10,23 +10,18 @@ module Travis::Yaml
|
|
10
10
|
KEYS = EXPAND_KEYS + [:env]
|
11
11
|
|
12
12
|
class Entry < DelegateClass(Nodes::Root)
|
13
|
-
attr_reader :
|
14
|
-
|
13
|
+
attr_reader :matrix_attributes
|
15
14
|
def initialize(root, matrix_attributes)
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
end
|
27
|
-
|
28
|
-
def inspect
|
29
|
-
"#<#{self.class}: #{matrix_attributes}>"
|
15
|
+
@matrix_attributes = matrix_attributes
|
16
|
+
normal_attributes = matrix_attributes.select { |key| key != :env }
|
17
|
+
generated_root = root.with_value(normal_attributes)
|
18
|
+
if matrix_attributes[:env]
|
19
|
+
generated_root.env.global = Travis::Yaml::Nodes::Env::List.new(generated_root.env)
|
20
|
+
generated_root.env.global.add_value! root.env.global if root.env.global
|
21
|
+
generated_root.env.global.add_value! matrix_attributes[:env]
|
22
|
+
generated_root.env.mapping.delete "matrix"
|
23
|
+
end
|
24
|
+
super(generated_root)
|
30
25
|
end
|
31
26
|
end
|
32
27
|
|
@@ -53,7 +48,7 @@ module Travis::Yaml
|
|
53
48
|
m.include.each { |i| entries << Hash[axes.map { |k| [k, i[k]] }] } if m.include
|
54
49
|
end
|
55
50
|
entries.map! { |attributes| Entry.new(root, attributes) }
|
56
|
-
entries.any? ? entries : [root]
|
51
|
+
entries.any? ? entries : [Entry.new(root, {})]
|
57
52
|
end
|
58
53
|
end
|
59
54
|
|
data/lib/travis/yaml/nodes.rb
CHANGED
@@ -35,6 +35,10 @@ module Travis::Yaml
|
|
35
35
|
require 'travis/yaml/nodes/notifications'
|
36
36
|
require 'travis/yaml/nodes/branches'
|
37
37
|
require 'travis/yaml/nodes/cache'
|
38
|
+
require 'travis/yaml/nodes/addons'
|
39
|
+
require 'travis/yaml/nodes/android'
|
40
|
+
require 'travis/yaml/nodes/dist'
|
41
|
+
require 'travis/yaml/nodes/group'
|
38
42
|
require 'travis/yaml/nodes/root'
|
39
43
|
end
|
40
44
|
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Travis::Yaml
|
2
|
+
module Nodes
|
3
|
+
class Addons < Mapping
|
4
|
+
class Addon < Mapping
|
5
|
+
def self.[](*keys)
|
6
|
+
Class.new(self) { map(*keys, to: Scalar[:str, :secure])}
|
7
|
+
end
|
8
|
+
|
9
|
+
def visit_scalar(visitor, type, value, implicit = true)
|
10
|
+
return super unless type == :bool
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class CoverityScan < Addon
|
15
|
+
class Project < Mapping
|
16
|
+
map :name, to: Scalar[:str, :secure], required: true
|
17
|
+
end
|
18
|
+
|
19
|
+
map :project, to: Project
|
20
|
+
map :build_script_url, :branch_pattern, :notification_email, :build_command,
|
21
|
+
:build_command_prepend, to: Scalar[:str, :secure]
|
22
|
+
end
|
23
|
+
|
24
|
+
class Artifacts < Addon
|
25
|
+
map :bucket, to: Scalar[:str, :secure], required: true
|
26
|
+
map :key, to: Scalar[:str, :secure], required: true
|
27
|
+
map :paths, to: Sequence
|
28
|
+
map :secret, to: Scalar[:str, :secure], required: true
|
29
|
+
|
30
|
+
map :branch, :log_format, :target_paths, to: Scalar[:str, :secure]
|
31
|
+
map :debug, :concurrency, :max_size, to: Scalar[:str, :int, :secure]
|
32
|
+
end
|
33
|
+
|
34
|
+
map :artifacts, to: Artifacts, drop_empty: false
|
35
|
+
map :code_climate, to: Addon[:repo_token], drop_empty: false
|
36
|
+
map :coverity_scan, to: CoverityScan
|
37
|
+
map :firefox, to: Version
|
38
|
+
map :hosts, to: Sequence
|
39
|
+
map :postgresql, to: Version
|
40
|
+
map :sauce_connect, to: Addon[:username, :access_key], drop_empty: false
|
41
|
+
map :ssh_known_hosts, to: Sequence
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -1,14 +1,16 @@
|
|
1
1
|
module Travis::Yaml
|
2
2
|
module Nodes
|
3
3
|
class Cache < Mapping
|
4
|
-
map :apt, :bundler, to: Scalar[:bool]
|
4
|
+
map :apt, :bundler, :cocoapods, to: Scalar[:bool]
|
5
|
+
map :edge, to: Scalar[:bool], experimental: true
|
5
6
|
map :directories, to: Sequence
|
6
7
|
|
7
8
|
def visit_scalar(visitor, type, value, implicit = true)
|
8
9
|
case type
|
9
10
|
when :bool
|
10
|
-
visit_key_value(visitor, :bundler,
|
11
|
-
visit_key_value(visitor, :apt,
|
11
|
+
visit_key_value(visitor, :bundler, value)
|
12
|
+
visit_key_value(visitor, :apt, value)
|
13
|
+
visit_key_value(visitor, :cocoapods, value)
|
12
14
|
when :str
|
13
15
|
key = visitor.generate_key(self, value)
|
14
16
|
self[key] = true
|
@@ -4,7 +4,8 @@ module Travis::Yaml
|
|
4
4
|
include LanguageSpecific
|
5
5
|
map :jdk, :node, :perl, :php, :python, :ruby, :scala, :node, to: Version
|
6
6
|
map :rvm, to: :ruby
|
7
|
-
map :repo,
|
7
|
+
map :repo, to: Scalar[:str]
|
8
|
+
map :branch, :condition, to: Sequence[:str]
|
8
9
|
map :all_branches, :tags, to: Scalar[:bool]
|
9
10
|
prefix_scalar :branch
|
10
11
|
end
|
@@ -1,10 +1,56 @@
|
|
1
1
|
module Travis::Yaml
|
2
2
|
module Nodes
|
3
3
|
class DeployEntry < OpenMapping
|
4
|
+
class Setting < OpenMapping
|
5
|
+
KEY = ''
|
6
|
+
prefix_scalar KEY
|
7
|
+
default_type Scalar[:str, :secure]
|
8
|
+
|
9
|
+
def ==(other)
|
10
|
+
return true if super
|
11
|
+
return false unless branch_specific?
|
12
|
+
generic == other
|
13
|
+
end
|
14
|
+
|
15
|
+
def __getobj__
|
16
|
+
branch_specific? ? generic : super
|
17
|
+
end
|
18
|
+
|
19
|
+
def inspect
|
20
|
+
branch_specific? ? generic.inspect : super
|
21
|
+
end
|
22
|
+
|
23
|
+
def branch_specific?
|
24
|
+
@mapping.size == 1 and @mapping.include? KEY
|
25
|
+
end
|
26
|
+
|
27
|
+
def branches
|
28
|
+
@mapping.keys - [KEY]
|
29
|
+
end
|
30
|
+
|
31
|
+
def generic
|
32
|
+
@mapping[KEY]
|
33
|
+
end
|
34
|
+
|
35
|
+
def verify_branch(name)
|
36
|
+
branches.each do |branch|
|
37
|
+
next if branch.to_s == name.to_s
|
38
|
+
warning "branch %p not permitted by deploy condition, dropping", branch
|
39
|
+
@mapping.delete(branch)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
default_type Setting
|
4
45
|
prefix_scalar :provider
|
5
46
|
map :provider, to: Scalar, required: true
|
6
47
|
map :edge, to: Scalar[:bool], experimental: true
|
7
48
|
map :on, to: DeployConditions
|
49
|
+
|
50
|
+
def verify
|
51
|
+
@mapping.each_value { |v| v.verify_branch(on.branch) if v.respond_to? :verify_branch } if on and on.branch
|
52
|
+
super
|
53
|
+
end
|
8
54
|
end
|
9
55
|
end
|
10
56
|
end
|
@@ -9,10 +9,11 @@ module Travis::Yaml
|
|
9
9
|
value jvm: :java, javascript: :node_js, node: :node_js, nodejs: :node_js, golang: :go,
|
10
10
|
objective_c: :"objective-c", obj_c: :"objective-c", objc: :"objective-c"
|
11
11
|
value "c++" => :cpp, "node.js" => :node_js, "obj-c" => :"objective-c"
|
12
|
+
value :generic, bash: :generic, sh: :generic, shell: :generic
|
12
13
|
|
13
14
|
def default_os
|
14
|
-
value == "objective-c" ?
|
15
|
+
value == "objective-c" ? "osx" : OSEntry.default
|
15
16
|
end
|
16
17
|
end
|
17
18
|
end
|
18
|
-
end
|
19
|
+
end
|
@@ -24,12 +24,12 @@ module Travis::Yaml
|
|
24
24
|
gemfile: %w[ruby objective-c],
|
25
25
|
composer_args: %w[php],
|
26
26
|
npm_args: %w[node_js],
|
27
|
-
|
27
|
+
android: %w[android]
|
28
28
|
}
|
29
29
|
|
30
30
|
def verify_language(language)
|
31
31
|
LANGUAGE_SPECIFIC.each do |key, languages|
|
32
|
-
next unless include? key and not languages.include? language
|
32
|
+
next unless include? key and not languages.include? language.value
|
33
33
|
mapping.delete mapped_key(key)
|
34
34
|
warning "specified %p, but setting is not relevant for %p", key.to_s, language
|
35
35
|
end
|
@@ -42,17 +42,27 @@ module Travis::Yaml
|
|
42
42
|
prefix_scalar(key)
|
43
43
|
end
|
44
44
|
|
45
|
-
def self.prefix_sequence(key)
|
46
|
-
|
47
|
-
|
45
|
+
def self.prefix_sequence(key = nil)
|
46
|
+
@prefix_sequence ||= superclass.respond_to?(:prefix_sequence) ? superclass.prefix_sequence : nil
|
47
|
+
if key
|
48
|
+
@prefix_sequence = key.to_s
|
49
|
+
define_method(:visit_sequence) do |visitor, value|
|
50
|
+
visit_key_value(visitor, key, value)
|
51
|
+
end
|
48
52
|
end
|
53
|
+
@prefix_sequence
|
49
54
|
end
|
50
55
|
|
51
|
-
def self.prefix_scalar(key, *types)
|
52
|
-
|
53
|
-
|
54
|
-
|
56
|
+
def self.prefix_scalar(key = nil, *types)
|
57
|
+
@prefix_scalar ||= superclass.respond_to?(:prefix_scalar) ? superclass.prefix_scalar : nil
|
58
|
+
if key
|
59
|
+
@prefix_scalar = key.to_s
|
60
|
+
define_method(:visit_scalar) do |visitor, type, value, implicit = true|
|
61
|
+
return super(visitor, type, value, implicit = true) if types.any? and not types.include?(type)
|
62
|
+
visit_key_value(visitor, key, value)
|
63
|
+
end
|
55
64
|
end
|
65
|
+
@prefix_scalar
|
56
66
|
end
|
57
67
|
|
58
68
|
def self.define_map_accessor(key)
|
@@ -84,6 +94,7 @@ module Travis::Yaml
|
|
84
94
|
|
85
95
|
def visit_key_value(visitor, key, value)
|
86
96
|
return warning("unexpected key %p, dropping", key) unless node = subnode_for(key)
|
97
|
+
warning("has multiple %p entries, keeping last entry", key) if self[key]
|
87
98
|
self[key] = node
|
88
99
|
visitor.accept(node, value)
|
89
100
|
end
|
@@ -93,12 +104,12 @@ module Travis::Yaml
|
|
93
104
|
end
|
94
105
|
|
95
106
|
def []=(key, value)
|
96
|
-
if
|
107
|
+
if mapped_key = mapped_key(key)
|
97
108
|
unless value.is_a? Node
|
98
|
-
node = subnode_for(
|
109
|
+
node = subnode_for(mapped_key)
|
99
110
|
value = node if Parser::Ruby.new(value).parse(node)
|
100
111
|
end
|
101
|
-
@mapping[
|
112
|
+
@mapping[mapped_key] = value
|
102
113
|
else
|
103
114
|
warning("unexpected key %p, dropping", key)
|
104
115
|
end
|
@@ -199,6 +210,24 @@ module Travis::Yaml
|
|
199
210
|
list = value.nested_warnings(*prefix, key) + list
|
200
211
|
end
|
201
212
|
end
|
213
|
+
|
214
|
+
def with_value!(value)
|
215
|
+
value = value.mapping while value.is_a? Mapping
|
216
|
+
value.each { |key, value| self[key] = value }
|
217
|
+
end
|
218
|
+
|
219
|
+
def each_scalar(type = nil, &block)
|
220
|
+
return enum_for(:each_scalar, type) unless block
|
221
|
+
@mapping.each_value { |v| v.each_scalar(type, &block) }
|
222
|
+
end
|
223
|
+
|
224
|
+
protected
|
225
|
+
|
226
|
+
def dup_values
|
227
|
+
duped_mapping = @mapping.map { |key, value| [key.dup, value.dup] }
|
228
|
+
@mapping = Hash[duped_mapping]
|
229
|
+
self
|
230
|
+
end
|
202
231
|
end
|
203
232
|
end
|
204
233
|
end
|
@@ -5,7 +5,7 @@ module Travis::Yaml
|
|
5
5
|
false
|
6
6
|
end
|
7
7
|
|
8
|
-
attr_accessor :
|
8
|
+
attr_accessor :parent
|
9
9
|
def initialize(parent)
|
10
10
|
@nested_warnings = []
|
11
11
|
@parent = parent
|
@@ -97,6 +97,63 @@ module Travis::Yaml
|
|
97
97
|
def to_s
|
98
98
|
__getobj__.to_s
|
99
99
|
end
|
100
|
+
|
101
|
+
def decrypt(&block)
|
102
|
+
each_scalar(SecureString) { |v| v.decrypt(&block) }
|
103
|
+
end
|
104
|
+
|
105
|
+
def encrypt(&block)
|
106
|
+
each_scalar(SecureString) { |v| v.encrypt(&block) }
|
107
|
+
end
|
108
|
+
|
109
|
+
def decrypted?
|
110
|
+
each_scalar(SecureString).all? { |v| v.decrypted? }
|
111
|
+
end
|
112
|
+
|
113
|
+
def encrypted?
|
114
|
+
each_scalar(SecureString).all? { |v| v.encrypted? }
|
115
|
+
end
|
116
|
+
|
117
|
+
def serialize(serializer, options = nil)
|
118
|
+
Serializer[serializer].serialize(self, options)
|
119
|
+
end
|
120
|
+
|
121
|
+
def to_yaml(options = nil)
|
122
|
+
serialize(:yaml, options)
|
123
|
+
end
|
124
|
+
|
125
|
+
def to_json(options = nil)
|
126
|
+
serialize(:json, options)
|
127
|
+
end
|
128
|
+
|
129
|
+
def to_ruby(options = nil)
|
130
|
+
serialize(:ruby, options)
|
131
|
+
end
|
132
|
+
|
133
|
+
def to_legacy_ruby(options = nil)
|
134
|
+
serialize(:legacy, options)
|
135
|
+
end
|
136
|
+
|
137
|
+
def with_value(value)
|
138
|
+
node = dup
|
139
|
+
node.with_value!(value)
|
140
|
+
node
|
141
|
+
end
|
142
|
+
|
143
|
+
def dup
|
144
|
+
super.dup_values
|
145
|
+
end
|
146
|
+
|
147
|
+
protected
|
148
|
+
|
149
|
+
def dup_values
|
150
|
+
self
|
151
|
+
end
|
152
|
+
|
153
|
+
def dup_ivar(name)
|
154
|
+
instance_variable_set(name, instance_variable_get(name).dup)
|
155
|
+
rescue TypeError
|
156
|
+
end
|
100
157
|
end
|
101
158
|
end
|
102
159
|
end
|
@@ -3,6 +3,10 @@ module Travis::Yaml
|
|
3
3
|
class Notifications < Mapping
|
4
4
|
Callbacks ||= FixedValue[:always, :never, :change]
|
5
5
|
|
6
|
+
class List < Sequence
|
7
|
+
type Scalar[:str, :secure]
|
8
|
+
end
|
9
|
+
|
6
10
|
class Notification < Mapping
|
7
11
|
map :enabled, :disabled, to: Scalar[:bool]
|
8
12
|
map :on_success, :on_failure, :on_start, to: Callbacks
|
@@ -12,7 +16,7 @@ module Travis::Yaml
|
|
12
16
|
end
|
13
17
|
|
14
18
|
def self.list(name)
|
15
|
-
map name, to:
|
19
|
+
map name, to: List
|
16
20
|
prefix_sequence name
|
17
21
|
prefix_scalar name, :str, :secure
|
18
22
|
end
|
@@ -32,7 +36,7 @@ module Travis::Yaml
|
|
32
36
|
end
|
33
37
|
|
34
38
|
class Template < Sequence
|
35
|
-
VARIABLES = %w[repository_slug repository_name repository build_number branch commit author message duration compare_url build_url]
|
39
|
+
VARIABLES = %w[repository_slug repository_name repository build_number branch commit author message duration compare_url build_url commit_message]
|
36
40
|
|
37
41
|
def verify
|
38
42
|
super
|
@@ -60,18 +64,18 @@ module Travis::Yaml
|
|
60
64
|
list :rooms
|
61
65
|
end
|
62
66
|
|
63
|
-
class
|
67
|
+
class Flowdock < Notification
|
64
68
|
map :api_token, to: Scalar[:str, :secure]
|
65
|
-
prefix_scalar
|
69
|
+
prefix_scalar :api_token, :str, :secure
|
66
70
|
end
|
67
71
|
|
68
72
|
map :webhooks, to: Notification[:urls]
|
69
73
|
map :email, to: Notification[:recipients]
|
70
74
|
map :sqwiggle, :slack, :campfire, to: WithTemplate[:rooms]
|
71
|
-
map :
|
75
|
+
map :flowdock, to: Flowdock
|
72
76
|
map :hipchat, to: Hipchat
|
73
77
|
map :irc, to: IRC
|
74
78
|
map :webhook, to: :webhooks
|
75
79
|
end
|
76
80
|
end
|
77
|
-
end
|
81
|
+
end
|