salt-lint 0.1.2 → 0.1.4.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1fe2637de60ccfaa599fdacd992bc4a82a52f9fb
4
- data.tar.gz: a4c720a812c7a64c6f3ada177c1db9ec11e1af15
3
+ metadata.gz: 06b6748f8fb4a05737347e3b730b460e62804f43
4
+ data.tar.gz: 916bad67abd80bc6f01e3ceb4ac0669a7d03e8f4
5
5
  SHA512:
6
- metadata.gz: 04d2acece330ecdae9ae4d7cd677891a5fc1cccf8be3166b7523d2b1f9ec1a5a8b5f017a4405ebfc013df0ddcbc8ec70c29153c123675644db9d47d6f915c459
7
- data.tar.gz: 82c711e2eef7ff31ef8bf39b354a716b11d9f76391e4492ea885496642d8d89746ad2d869329be275a7f960b0848f79b3512b160c9be6ffee374210b665a7e3a
6
+ metadata.gz: 56db23b66967baa8f52f5e0b121c4dbae2a59afcd3c9f45e54bf63bf3b7f449b733605ea07e088f05f949bb4478933e47878b841e49ffcce163a58052196f55e
7
+ data.tar.gz: 6f7b73c95725063538f928039062ede88e123c49abde456627a676221728773781393cb5fdae94ed2b06bce599388d11f6d82f78bb68cfed4c2f387398110cc5
data/README.md CHANGED
@@ -13,4 +13,10 @@ Development: [![Development: Build Status](https://api.shippable.com/projects/55
13
13
  ## Documentation:
14
14
  Please see [documentation](doc/list_tests.md) to interpret any results returned.
15
15
 
16
+ ## Running within git repo with its git files only
17
+
18
+ ```
19
+ git ls-files | grep sls | xargs -I {} salt-lint -f {}
20
+ ```
21
+
16
22
  ## Do not use it until version >= 0.5
data/doc/list_tests.md CHANGED
@@ -1,12 +1,13 @@
1
- # Salt-lint tests
1
+ # Salt-lint tests results.
2
2
 
3
- * [Using double quotes with no variables](#Using double quotes with no variables)
4
- * [Line length above 80 characters](#Line length above 80 characters)
5
- * [Found single line declaration](#Found single line declaration)
6
- * [No newline at the end of the file](#No newline at the end of the file)
7
- * [Trailing whitespace character found](#Trailing whitespace character found)
3
+ * [Using double quotes with no variables](#double-quotes)
4
+ * [Line length above 80 characters](#line-length)
5
+ * [Found single line declaration](#single-declaration)
6
+ * [No newline at the end of the file](#no-newline)
7
+ * [Trailing whitespace character found](#trailing-whitespace)
8
+ * [Found tabs used instead of spaces](#found-tabs)
8
9
 
9
- ### Using double quotes with no variables
10
+ ### <a name="double-quotes"></a>Using double quotes with no variables
10
11
  In general - it's a bad idea. All the strings which does not contain dynamic content ( variables ) should use single quote instead of double.
11
12
 
12
13
  ##### Bad
@@ -21,10 +22,10 @@ dev:
21
22
  '*'
22
23
  ```
23
24
 
24
- ### Line length above 80 characters
25
+ ### <a name="line-length"></a>Line length above 80 characters
25
26
  As a 'standard code width limit' and for historical reasons - [IBM punch card](http://en.wikipedia.org/wiki/Punched_card) had exactly 80 columns.
26
27
 
27
- ### Found single line declaration
28
+ ### <a name="single-declaration"></a>Found single line declaration
28
29
  Avoid extending your code by adding single-line declarations. It makes your code much cleaner and easier to parse / grep while searching for those declarations.
29
30
 
30
31
  ##### Bad
@@ -40,8 +41,17 @@ Avoid extending your code by adding single-line declarations. It makes your code
40
41
  pkg.installed
41
42
  ```
42
43
 
43
- ### No newline at the end of the file
44
+ ### <a name="no-newline"></a>No newline at the end of the file
44
45
  Each line should be terminated in a newline character, including the last one. Some programs have problems processing the last line of a file if it isn't newline terminated. [Stackoverflow thread](http://stackoverflow.com/questions/729692/why-should-files-end-with-a-newline)
45
46
 
46
- ### Trailing whitespace character found
47
- Trailing whitespaces take more spaces than necessary, any regexp based searches won't return lines as a result due to trailing whitespace(s).
47
+ ### <a name="trailing-whitespace"></a>Trailing whitespace character found
48
+ Trailing whitespaces take more spaces than necessary, any regexp based searches won't return lines as a result due to trailing whitespace(s).
49
+
50
+ ### <a name="quoted-booleans"></a>Quoted boolean found
51
+ Boolean values behave differently when quoted as they're interpreted as strings which you obviously don't want.
52
+
53
+ ### <a name="filename-quoted"></a>Unquoted file mode found
54
+ Unquoted file modes are interpreted as integers and evaluated as octal.
55
+
56
+ ### <a name="found-tabs"></a>Found tabs used instead of spaces
57
+ [PEP-8](http://legacy.python.org/dev/peps/pep-0008/#tabs-or-spaces) says "spaces" so we require those instead of tabs as Salt is python-friendly ( said guy who wrote a Salt linter in Ruby ).
@@ -1,3 +1,5 @@
1
+ require 'find'
2
+
1
3
  module SaltLint
2
4
  # Executing appropriate actions
3
5
  # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -13,10 +15,30 @@ module SaltLint
13
15
  test_suite_methods = SaltLint::Tests.methods(false).sort - [ :check_for_regexp ]
14
16
  line_counter = 1
15
17
  File.readlines(f).each do |l|
16
- test_suite_methods.each do |m|
17
- if ! $invalid_yaml[f]
18
- checks_went_fine_tmp = SaltLint::Tests.send(m, line_counter, l, f)
19
- checks_went_fine_tmp == false ? checks_went_fine = false : nil
18
+ skip = false
19
+ tmp_l = l.gsub(/\s+/, '')
20
+ # Comments
21
+ if tmp_l =~ /\{?#(.+)?\}?/
22
+ skip = true
23
+ # Empty lines
24
+ elsif tmp_l =~ /^$/
25
+ skip = true
26
+ # Functions
27
+ elsif tmp_l =~ /\{+.+\(.+\).+\}+/
28
+ skip = true
29
+ # Variables
30
+ elsif tmp_l =~ /\{\{.+\}\}/
31
+ l = l.gsub(/\{\{.+\}\}/, 'random_string')
32
+ # If / Else blocks
33
+ elsif tmp_l =~ /^\{\%.*\%\}$/
34
+ skip = true
35
+ end
36
+ if ! skip
37
+ test_suite_methods.each do |m|
38
+ if ! $invalid_yaml[f]
39
+ checks_went_fine_tmp = SaltLint::Tests.send(m, line_counter, l, f)
40
+ checks_went_fine_tmp == false ? checks_went_fine = false : nil
41
+ end
20
42
  end
21
43
  end
22
44
  line_counter += 1
@@ -27,9 +49,15 @@ module SaltLint
27
49
 
28
50
  # Scans folder specified as argument --scan for SLS files and returns array
29
51
  def self.scan
30
- files = Dir.glob( $arguments.scan + "**/*.sls")
31
- if files and files.count > 0
32
- return files
52
+ # files = Dir.glob( $arguments.scan + "**/*")
53
+ files_to_return = Array.new
54
+ Find.find($arguments.scan).to_a.each do |f|
55
+ if f =~ /.*\.sls$/
56
+ files_to_return.push(f)
57
+ end
58
+ end
59
+ if files_to_return.count > 0
60
+ return files_to_return
33
61
  else
34
62
  Printer.print('error', 'No salt state files found.')
35
63
  exit 1
@@ -14,6 +14,8 @@ module SaltLint
14
14
  SaltLint::Actions.check_rules(f)
15
15
  end
16
16
  end
17
+ elsif $arguments.file_given
18
+ SaltLint::Actions.check_rules($arguments.file)
17
19
  end
18
20
  end
19
21
 
@@ -32,6 +34,16 @@ EOS
32
34
  opt :debug, 'Enable debug mode', default: 0
33
35
  opt :file, 'File to check against', type: :string
34
36
  opt :scan, 'Traversal scan of current directory and sub dirs', type: :string
37
+
38
+ opt :check_newlines, 'Check for newline at the end of the file', default: true, short: :none
39
+ opt :check_double_quotes, 'Check for double quotes without variables', default: true, short: :none
40
+ opt :check_whitespaces, 'Check for whitespaces at the end of the line', default: true, short: :none
41
+ opt :check_line_length, 'Check lines length', default: true, short: :none
42
+ opt :check_single_word, 'Check for single word declaration', default: true, short: :none
43
+ opt :check_quoted_boolean, 'Check for quoted booleans', default: true, short: :none
44
+ opt :check_quoted_file_mode, 'Check for unquoted file modes', default: true, short: :none
45
+ opt :check_tabs, 'Check if tabs used instead of spaces', default: true, short: :none
46
+
35
47
  end
36
48
  $debug = opts.debug.to_i
37
49
  return opts
@@ -6,9 +6,8 @@ module SaltLint
6
6
 
7
7
  # Helper: Checking for whitespaces
8
8
  def self.check_for_regexp(line_number, line, file, regex, debug_msg, warning_msg)
9
- is_ok = true
10
9
  Printer.print('debug', debug_msg, 5)
11
- line.match(regex) ? is_ok = false : nil
10
+ ! (line =~ Regexp.new(regex)).nil? ? is_ok = false : is_ok = true
12
11
  if ! is_ok
13
12
  Printer.print('warning', warning_msg)
14
13
  end
@@ -18,14 +17,16 @@ module SaltLint
18
17
  # Test content: Check context and block all the single-word declarations
19
18
  def self.check_if_single_word_declaration(line_number, line, file)
20
19
  is_ok = true
21
- Printer.print('debug', "Looking for single word declarations in #{file}", 5)
22
- if line =~ /(pkg|file|service):\n/
23
- f = File.readlines(file)[line_number-1..line_number+2]
24
- ( f[2] =~ /^\n$/ && f[1] =~ /- \w+\n$/ ) ? is_ok = true : is_ok = false
25
- if ! $invalid_oneword.has_key?(file) && is_ok == false
26
- Printer.print('warning', "Found single line declaration in #{file}:#{line_number-1}-#{line_number+2}")
27
- $invalid_oneword[file] = is_ok
28
- end
20
+ if $arguments.check_single_word
21
+ Printer.print('debug', "Looking for single word declarations in #{file}", 5)
22
+ if line =~ /(pkg|file|service):\n/
23
+ f = File.readlines(file)[line_number-1..line_number+2]
24
+ ( f[2] =~ /^\n$/ && f[1] =~ /- \w+\n$/ ) ? is_ok = true : is_ok = false
25
+ if ! $invalid_oneword.has_key?(file) && is_ok == false
26
+ Printer.print('warning', "Found single line declaration in #{file}:#{line_number-1}-#{line_number+1}")
27
+ $invalid_oneword[file] = is_ok
28
+ end
29
+ end
29
30
  end
30
31
  return is_ok
31
32
  end
@@ -33,51 +34,76 @@ module SaltLint
33
34
  # Test content: Checking given file for no newline at the end of the file.
34
35
  def self.check_for_no_newline(line_number, line, file)
35
36
  is_ok = true
36
- Printer.print('debug', "Checking for no-newline at the end of the file in file #{file}", 5)
37
- f = File.readlines(file).last
38
- f.match(/^\n$/) ? is_ok = true : is_ok = false
39
- if ! $invalid_newline.has_key?(file) && is_ok == false
40
- Printer.print('warning', "No newline at the end of the file #{file}")
41
- $invalid_newline[file] = is_ok
37
+ if $arguments.check_newlines
38
+ Printer.print('debug', "Checking for no-newline at the end of the file in file #{file}", 5)
39
+ f = File.readlines(file).last
40
+ f.match(/^\n$/) ? is_ok = true : is_ok = false
41
+ if ! $invalid_newline.has_key?(file) && is_ok == false
42
+ Printer.print('warning', "No newline at the end of the file #{file}")
43
+ $invalid_newline[file] = is_ok
44
+ end
42
45
  end
43
46
  return is_ok
44
47
  end
45
48
 
46
- # Test content: Checking if given file is a valid YAML file.
47
- def self.check_if_proper_yaml(line_number, line, file)
49
+ # Test content: Checking if given line isn't longer than 80 characters.
50
+ def self.check_line_length(line_number, line, file)
48
51
  is_ok = true
49
- begin
50
- YAML.load_file(file)
51
- rescue Psych::SyntaxError
52
- is_ok = false
53
- if ! $invalid_yaml.has_key?(file)
54
- Printer.print('warning', "File #{file} is not YAML. Unable to parse.")
55
- $invalid_yaml[file] = true
52
+ if $arguments.check_line_length
53
+ Printer.print('debug', "Checking line length: #{line_number}", 5)
54
+ line.length > 80 ? is_ok = false : nil
55
+ if ! is_ok
56
+ Printer.print('warning', "Line length above 80 characters: #{file}:#{line_number}")
56
57
  end
57
58
  end
58
59
  return is_ok
59
60
  end
60
61
 
61
- # Test content: Checking if given line isn't longer than 80 characters.
62
- def self.check_line_length(line_number, line, file)
63
- is_ok = true
64
- Printer.print('debug', "Checking line length: #{line_number}", 5)
65
- line.length > 80 ? is_ok = false : nil
66
- if ! is_ok
67
- Printer.print('warning', "Line length above 80 characters: #{file}:#{line_number}")
62
+
63
+ # Test content: Check for tabs used instead of spaces.
64
+ def self.check_if_tabs_used(line_number, line, file)
65
+ if $arguments.check_tabs
66
+ check_for_regexp(line_number, line, file, /^[\t]+/, "Checking for tabs presence: #{line_number}", "Found tabs used instead of spaces: #{file}:#{line_number}")
67
+ else
68
+ return true
68
69
  end
69
- return is_ok
70
70
  end
71
71
 
72
72
  # Test content: Checking given line for trailing whitespaces.
73
73
  def self.check_trailing_whitespace(line_number, line, file)
74
- check_for_regexp(line_number, line, file, /[ \t]+$/, "Checking for trailing whitespaces: #{line_number}", "Trailing whitespace character found: #{file}:#{line_number}")
74
+ if $arguments.check_whitespaces
75
+ check_for_regexp(line_number, line, file, /[ \t]+$/, "Checking for trailing whitespaces: #{line_number}", "Trailing whitespace character found: #{file}:#{line_number}")
76
+ else
77
+ return true
78
+ end
75
79
  end
76
80
 
77
81
  # Test content: Checking if given line contains double quoted content without
78
82
  # variable.
79
83
  def self.check_double_quotes(line_number, line, file)
80
- check_for_regexp(line_number, line, file, /\"(?!{+).*(?!}+)\"/, "Checking for double quotes: #{line_number}", "Using double quotes with no variables: #{file}:#{line_number}")
84
+ if $arguments.check_double_quotes
85
+ check_for_regexp(line_number, line, file, /\"(?!{+).*(?!}+)\"/, "Checking for double quotes: #{line_number}", "Using double quotes with no variables: #{file}:#{line_number}")
86
+ else
87
+ return true
88
+ end
89
+ end
90
+
91
+ # Test content: Checking if there's quoted boolean value present.
92
+ def self.check_quoted_boolean(line_number, line, file)
93
+ if $arguments.check_quoted_boolean
94
+ check_for_regexp(line_number, line, file, /\s+(\"|\')(true|false)(\"|\')$/, "Checking for quoted booleans: #{line_number}", "Quoted boolean found: #{file}:#{line_number}")
95
+ else
96
+ return true
97
+ end
98
+ end
99
+
100
+ # Test content: Check if file mode with leading zero is wrapped into single quotes
101
+ def self.check_file_mode_single_quotes(line_number, line, file)
102
+ if $arguments.check_quoted_file_mode
103
+ check_for_regexp(line_number, line, file, /mode\:\s\d{3,4}$/, "Checking if file mode is wrapped in single quotes: #{line_number}", "Unquoted file mode found: #{file}:#{line_number}")
104
+ else
105
+ return true
106
+ end
81
107
  end
82
108
  end
83
109
  end
@@ -1,3 +1,3 @@
1
1
  module SaltLint
2
- VERSION = '0.1.2'
2
+ VERSION = '0.1.4.1'
3
3
  end
data/shippable.yml CHANGED
@@ -1,3 +1,4 @@
1
+ cache: true
1
2
  language: ruby
2
3
  install:
3
4
  - bundle install
data/spec/files_spec.rb CHANGED
@@ -1,22 +1,31 @@
1
1
  require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
2
 
3
+ $arguments = OpenStruct.new({ file: 'tests/file_with_multiple_errors.sls', file_given: true,
4
+ check_newlines: true, check_double_quotes: true, check_whitespaces: true,
5
+ check_line_length: true, check_single_word: true, check_quoted_booleans: true })
6
+
7
+ $debug = 0
8
+
3
9
  describe 'Files operations' do
4
10
 
5
11
  it 'scans all the files within "tests" directory' do
6
- $arguments = OpenStruct.new({ scan: 'tests', scan_given: true })
12
+ $arguments.file_given = false
13
+ $arguments.scan_given = true
14
+ $arguments.scan = 'tests'
7
15
  list_of_sls_files = SaltLint::Actions.scan
8
16
  expect(list_of_sls_files.grep(/well_formatted_top\.sls/).any?).to eq true
9
17
  end
10
18
 
11
19
  it 'checks well formatted file' do
12
- $arguments = OpenStruct.new({ file: 'tests/well_formatted_top.sls', file_given: true })
13
- $debug = 0
20
+ $arguments.file = 'tests/well_formatted_top.sls'
21
+ $arguments.file_given = true
22
+ $arguments.scan_given = false
14
23
  expect(SaltLint::Actions.check_rules($arguments.file)).to eq true
15
24
  end
16
25
 
17
26
  it 'checks file with multiple errors' do
18
- $arguments = OpenStruct.new({ file: 'tests/file_with_multiple_errors.sls', file_given: true })
19
- $debug = 0
27
+ $arguments.scan_given = false
28
+ $arguments.file = 'tests/file_with_multiple_errors.sls'
20
29
  expect(SaltLint::Actions.check_rules($arguments.file)).to eq false
21
30
  end
22
31
  end
data/spec/tests_spec.rb CHANGED
@@ -1,18 +1,15 @@
1
1
  require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
2
 
3
+ $arguments = OpenStruct.new({ file: 'tests/file_with_multiple_errors.sls', file_given: true,
4
+ check_newlines: true, check_double_quotes: true, check_whitespaces: true,
5
+ check_line_length: true, check_single_word: true, check_quoted_boolean: true,
6
+ check_quoted_file_mode: true, check_tabs: true })
7
+
3
8
  test_file_good = 'tests/well_formatted_top.sls'
4
9
  test_file_bad_yaml = 'tests/non_yaml_file.sls'
5
10
  test_file_bad = 'tests/file_with_multiple_errors.sls'
6
11
 
7
12
  describe 'Tests suite checks if' do
8
- it 'file is in YAML format (incorrect)' do
9
- expect(SaltLint::Tests.check_if_proper_yaml(0, 0, test_file_bad_yaml)).to eq false
10
- end
11
-
12
- it 'file is in YAML format (correct)' do
13
- expect(SaltLint::Tests.check_if_proper_yaml(0, 0, test_file_good)).to eq true
14
- end
15
-
16
13
  it 'won\'t allow lines longer than 80 characters' do
17
14
  expect(SaltLint::Tests.check_line_length(0, 'xG9H2z8dOK0n3fTX1g4bWS5a6lRI7t6jCsY58mLJ2pqU9N3k4rBD0woA17iMyP90eEZ2u3cFbQ47uYD5lmM16' , test_file_good)).to eq false
18
15
  end
@@ -37,4 +34,20 @@ describe 'Tests suite checks if' do
37
34
  it 'will allow condensed declarations' do
38
35
  expect(SaltLint::Tests.check_if_single_word_declaration(5, "pkg.installed\n", test_file_good)).to eq true
39
36
  end
40
- end
37
+
38
+ it 'won\'t allow quoted booleans' do
39
+ expect(SaltLint::Tests.check_quoted_boolean(5, 'potato: "true"', test_file_bad)).to eq false
40
+ end
41
+
42
+ it 'won\'t allow unquoted file modes' do
43
+ expect(SaltLint::Tests.check_file_mode_single_quotes(8, 'mode: 0744', test_file_bad)).to eq false
44
+ end
45
+
46
+ it 'won\'t allow using tabs instead of spaces' do
47
+ expect(SaltLint::Tests.check_if_tabs_used(8, "\ttest_value", test_file_bad)).to eq false
48
+ end
49
+
50
+ it 'will allow using spaces instead of tabs' do
51
+ expect(SaltLint::Tests.check_if_tabs_used(8, " test_value", test_file_good)).to eq true
52
+ end
53
+ end
@@ -4,3 +4,5 @@ base:
4
4
  python:
5
5
  pkg:
6
6
  - installed
7
+ - value: 'false'
8
+ - mode: 0644
@@ -3,4 +3,6 @@ base:
3
3
  - core
4
4
  python:
5
5
  pkg.installed
6
+ value: true
7
+ mode: '0644'
6
8
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: salt-lint
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lukasz Raczylo
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-04-02 00:00:00.000000000 Z
11
+ date: 2015-04-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: awesome_print
@@ -151,7 +151,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
151
151
  version: '0'
152
152
  requirements: []
153
153
  rubyforge_project:
154
- rubygems_version: 2.4.5
154
+ rubygems_version: 2.4.6
155
155
  signing_key:
156
156
  specification_version: 4
157
157
  summary: Salt linter written in Ruby
@@ -160,4 +160,3 @@ test_files:
160
160
  - spec/files_spec.rb
161
161
  - spec/spec_helper.rb
162
162
  - spec/tests_spec.rb
163
- has_rdoc: