cyclid-core 0.1.1 → 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/lib/cyclid/errors.rb +11 -0
- data/lib/cyclid/linter.rb +191 -0
- metadata +17 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 99abddef50adfd4dbf2c21a3bcea9827c1584b18
|
4
|
+
data.tar.gz: 64fc2e722dc9e998cb56031e6b42b51ab200bcf0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2b83fc0f953bc10e807526f05d8a07c1beb2d7768ddaac2b085d1c5a71df71aaf66d428723a03c52dce410eb9fd99a784558c1d89973638911269e1cd0dc10c7
|
7
|
+
data.tar.gz: b6e993004b030f37f1e71926090aecfad292edf55346f53a8b77bde0dc5135b74979ad4de49525e54a2b23580bd3f013c5fd41bd6ec1821715894224a038ac3a
|
data/lib/cyclid/errors.rb
CHANGED
@@ -72,6 +72,17 @@ module Cyclid
|
|
72
72
|
# Base class for all internal Cyclid exceptions
|
73
73
|
class CyclidError < StandardError
|
74
74
|
end
|
75
|
+
|
76
|
+
# Object was not found
|
77
|
+
class NotFoundError < CyclidError
|
78
|
+
end
|
79
|
+
|
80
|
+
# Object is invalid
|
81
|
+
class InvalidObjectError < CyclidError
|
82
|
+
end
|
83
|
+
|
84
|
+
class InternalError < CyclidError
|
85
|
+
end
|
75
86
|
end
|
76
87
|
end
|
77
88
|
end
|
@@ -0,0 +1,191 @@
|
|
1
|
+
# Copyright 2017 Liqwyd Ltd.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
require 'active_support'
|
16
|
+
require 'active_support/core_ext'
|
17
|
+
require 'json'
|
18
|
+
require 'yaml'
|
19
|
+
|
20
|
+
module Cyclid
|
21
|
+
# Module for the Cyclid job linter
|
22
|
+
module Linter
|
23
|
+
# A simple helper to track Warnings & Errors from the Verifier
|
24
|
+
class StatusLogger
|
25
|
+
attr_reader :messages, :warnings, :errors
|
26
|
+
|
27
|
+
module MessageTypes
|
28
|
+
WARNING = 0
|
29
|
+
ERROR = 1
|
30
|
+
end
|
31
|
+
|
32
|
+
def initialize
|
33
|
+
@messages = []
|
34
|
+
@warnings = 0
|
35
|
+
@errors = 0
|
36
|
+
end
|
37
|
+
|
38
|
+
def warning(message)
|
39
|
+
@warnings += 1
|
40
|
+
@messages << { type: MessageTypes::WARNING, text: message }
|
41
|
+
end
|
42
|
+
|
43
|
+
def error(message)
|
44
|
+
@errors += 1
|
45
|
+
@messages << { type: MessageTypes::ERROR, text: message }
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# Verify (lint) a Job for obvious errors and potential problems
|
50
|
+
class Verifier
|
51
|
+
module Bertrand
|
52
|
+
UNKNOWN = 0
|
53
|
+
NOT_EXIST = 1
|
54
|
+
EXISTS = 2
|
55
|
+
end
|
56
|
+
|
57
|
+
attr_reader :status
|
58
|
+
|
59
|
+
def initialize(*_args)
|
60
|
+
@status = StatusLogger.new
|
61
|
+
end
|
62
|
+
|
63
|
+
def verify(definition)
|
64
|
+
job = definition.deep_symbolize_keys
|
65
|
+
|
66
|
+
# Does the data even look like a job?
|
67
|
+
@status.error 'Job is not a hash?' \
|
68
|
+
unless job.is_a? Hash
|
69
|
+
|
70
|
+
@status.error 'Job is empty?' \
|
71
|
+
if job.empty?
|
72
|
+
|
73
|
+
# Lint all of the obvious, top-level stuff that makes up a basic job
|
74
|
+
@status.error 'The Job does not have a name.' \
|
75
|
+
unless job.key? :name
|
76
|
+
|
77
|
+
@status.warning 'No version is defined for the Job. The default of 1.0.0 will be used.' \
|
78
|
+
unless job.key? :version
|
79
|
+
|
80
|
+
@status.warning 'No environment is defined. Defaults will apply.' \
|
81
|
+
unless job.key? :environment
|
82
|
+
|
83
|
+
@status.error 'No sequence is defined.' \
|
84
|
+
unless job.key? :sequence
|
85
|
+
|
86
|
+
# If any Stages are defined, check that each one looks valid
|
87
|
+
verify_stages(job[:stages]) if job.key? :stages
|
88
|
+
|
89
|
+
# Verify that the Sequence is valid, as much as possible
|
90
|
+
verify_sequence(job[:sequence]) if job.key? :sequence
|
91
|
+
rescue StandardError => ex
|
92
|
+
@status.error "An unexpected error occured during the verification: #{ex}"
|
93
|
+
end
|
94
|
+
|
95
|
+
private
|
96
|
+
|
97
|
+
def verify_stages(stages)
|
98
|
+
@status.error 'Stages is not defined as an Array.' \
|
99
|
+
unless stages.is_a? Array
|
100
|
+
|
101
|
+
@status.warning 'Stages is defined but empty?' \
|
102
|
+
if stages.empty?
|
103
|
+
|
104
|
+
# Verify each Stage
|
105
|
+
@ad_hoc_stages = []
|
106
|
+
stages.each do |stage|
|
107
|
+
unless stage.is_a? Hash
|
108
|
+
@status.error 'A Stage is defined but is not an Object?'
|
109
|
+
next
|
110
|
+
end
|
111
|
+
|
112
|
+
unless stage.key? :name
|
113
|
+
@status.error 'A Stage is defined without a name.'
|
114
|
+
next
|
115
|
+
end
|
116
|
+
|
117
|
+
# The Stage is at least a Hash with a name key...
|
118
|
+
name = stage[:name]
|
119
|
+
@ad_hoc_stages << name
|
120
|
+
|
121
|
+
@status.error "The Stage '#{name}' is defined but empty." \
|
122
|
+
if stage.empty?
|
123
|
+
|
124
|
+
unless stage.key? :steps
|
125
|
+
@status.error "The Stage '#{name}' does not define any Steps."
|
126
|
+
next
|
127
|
+
end
|
128
|
+
|
129
|
+
@status.error "The Stage '#{name}' defines an empty set of Steps." \
|
130
|
+
if stage[:steps].empty?
|
131
|
+
|
132
|
+
@status.warning "No version is given for the Stage '#{name}'. " \
|
133
|
+
'The default of 1.0.0 will be used.' \
|
134
|
+
unless stage.key? :version
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
def verify_sequence(sequence)
|
139
|
+
@status.error 'The Sequence is not defined as an Array.' \
|
140
|
+
unless sequence.is_a? Array
|
141
|
+
|
142
|
+
@status.error 'The Sequence is defined but empty?' \
|
143
|
+
if sequence.empty?
|
144
|
+
|
145
|
+
# Verify each Stage and track all dependencies (stage, on_success, on_failure)
|
146
|
+
dependencies = []
|
147
|
+
sequence.each do |stage|
|
148
|
+
unless stage.is_a? Hash
|
149
|
+
@status.error 'A Stage in the Sequence is defined that is not an Object?'
|
150
|
+
next
|
151
|
+
end
|
152
|
+
|
153
|
+
unless stage.key? :stage
|
154
|
+
@status.error 'A Stage in the Sequence does not name a Stage to run.'
|
155
|
+
next
|
156
|
+
end
|
157
|
+
|
158
|
+
name = stage[:stage]
|
159
|
+
@status.warning 'A Stage in the Sequence does not specify a version for the ' \
|
160
|
+
"Stage '#{name}'. The latest will always be used."
|
161
|
+
|
162
|
+
dependencies << name.downcase
|
163
|
+
dependencies << stage[:on_success].downcase if stage.key? :on_success
|
164
|
+
dependencies << stage[:on_failure].downcase if stage.key? :on_failure
|
165
|
+
end
|
166
|
+
dependencies.uniq!
|
167
|
+
|
168
|
+
# Check that every dependency exists
|
169
|
+
dependencies.each do |dep|
|
170
|
+
next if @ad_hoc_stages.include? dep
|
171
|
+
|
172
|
+
# Okay, it's not defined in this job: does it exist on the server?
|
173
|
+
case stage_exists? dep
|
174
|
+
when Bertrand::UNKNOWN
|
175
|
+
@status.warning "The Stage '#{dep}' in the Sequence is not defined in this job and " \
|
176
|
+
'may not exist on the server.'
|
177
|
+
when Bertrand::NOT_EXIST
|
178
|
+
@status.error "The Stage '#{dep}' in the Sequence is not defined in this job and " \
|
179
|
+
'does not exist on the server.'
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
# Find a Stage by it's name; this method will difer between Remote & Local
|
185
|
+
# (server-side) verification, so is just a stub here.
|
186
|
+
def stage_exists?(_name)
|
187
|
+
Bertrand::UNKNOWN
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cyclid-core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kristian Van Der Vliet
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-07-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rack
|
@@ -24,6 +24,20 @@ dependencies:
|
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '1.6'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: activesupport
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '4.2'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '4.2'
|
27
41
|
description: Core files (shared between the Client & Server) for Cyclid
|
28
42
|
email: vanders@liqwyd.com
|
29
43
|
executables: []
|
@@ -35,6 +49,7 @@ files:
|
|
35
49
|
- lib/cyclid/constants.rb
|
36
50
|
- lib/cyclid/errors.rb
|
37
51
|
- lib/cyclid/hmac.rb
|
52
|
+
- lib/cyclid/linter.rb
|
38
53
|
homepage:
|
39
54
|
licenses:
|
40
55
|
- MIT
|