nasl-pedant 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.
Files changed (34) hide show
  1. data/.gitignore +10 -0
  2. data/Gemfile +4 -0
  3. data/Rakefile +8 -0
  4. data/bin/pedant +33 -0
  5. data/lib/pedant/check.rb +135 -0
  6. data/lib/pedant/checks/conditional_or_loop_is_empty.rb +70 -0
  7. data/lib/pedant/checks/contains_ip_address_literals.rb +49 -0
  8. data/lib/pedant/checks/contains_no_carriage_returns.rb +48 -0
  9. data/lib/pedant/checks/contains_no_tabs.rb +48 -0
  10. data/lib/pedant/checks/contains_registration_section.rb +107 -0
  11. data/lib/pedant/checks/contains_unreachable_code.rb +68 -0
  12. data/lib/pedant/checks/ends_with_newline.rb +49 -0
  13. data/lib/pedant/checks/files_parse_without_error.rb +101 -0
  14. data/lib/pedant/checks/parse_test_code.rb +63 -0
  15. data/lib/pedant/checks/plugin_type_not_specified.rb +79 -0
  16. data/lib/pedant/cli.rb +82 -0
  17. data/lib/pedant/command.rb +96 -0
  18. data/lib/pedant/commands/check.rb +76 -0
  19. data/lib/pedant/commands/test.rb +37 -0
  20. data/lib/pedant/knowledge_base.rb +42 -0
  21. data/lib/pedant/test.rb +59 -0
  22. data/lib/pedant/version.rb +3 -0
  23. data/lib/pedant.rb +51 -0
  24. data/pedant.gemspec +25 -0
  25. data/test/test_helper.rb +5 -0
  26. data/test/unit/checks/conditional_or_loop_is_empty.rb +125 -0
  27. data/test/unit/checks/contains_ip_address_literals.rb +45 -0
  28. data/test/unit/checks/contains_no_carriage_returns.rb +43 -0
  29. data/test/unit/checks/contains_no_tabs.rb +45 -0
  30. data/test/unit/checks/contains_registration_section.rb +101 -0
  31. data/test/unit/checks/contains_unreachable_code.rb +93 -0
  32. data/test/unit/checks/ends_with_newline.rb +45 -0
  33. data/test/unit/checks/plugin_type_not_specified.rb +72 -0
  34. metadata +123 -0
@@ -0,0 +1,101 @@
1
+ ################################################################################
2
+ # Copyright (c) 2011, Mak Kolybabi
3
+ # All rights reserved.
4
+ #
5
+ # Redistribution and use in source and binary forms, with or without
6
+ # modification, are permitted provided that the following conditions are met:
7
+ #
8
+ # 1. Redistributions of source code must retain the above copyright notice, this
9
+ # list of conditions and the following disclaimer.
10
+ #
11
+ # 2. Redistributions in binary form must reproduce the above copyright notice,
12
+ # this list of conditions and the following disclaimer in the documentation
13
+ # and/or other materials provided with the distribution.
14
+ #
15
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18
+ # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
19
+ # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20
+ # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21
+ # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
22
+ # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
23
+ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
+ ################################################################################
26
+
27
+ module Pedant
28
+ class CheckFilesParseWithoutErrors < Check
29
+ def self.requires
30
+ super + [:file_mode, :base, :main]
31
+ end
32
+
33
+ def provides
34
+ super + [:codes, :trees]
35
+ end
36
+
37
+ def run
38
+ def import(path)
39
+ # All files should be relative to the main file's base in practice.
40
+ path = @kb[:base] + path
41
+
42
+ # Since there are potentially several ways to write the path leading to
43
+ # a file, we'll use the basename as the key for hashes. This will
44
+ # prevent parsing the same file multiple times.
45
+ file = path.basename
46
+
47
+ # Mark a placeholder key in the KB for this file. This will prevent us
48
+ # from trying to parse a library more than once if there is a failure.
49
+ @kb[:codes][file] = :pending
50
+ @kb[:trees][file] = :pending
51
+
52
+ begin
53
+ contents = File.open(path, "rb").read
54
+ @kb[:codes][file] = contents
55
+ report(:info, "Read contents of #{path}.")
56
+ rescue
57
+ report(:error, "Failed to read contents #{path}.")
58
+ return fatal
59
+ end
60
+
61
+ begin
62
+ tree = Nasl::Parser.new.parse(contents, path)
63
+ @kb[:trees][file] = tree
64
+ report(:info, "Parsed contents of #{path}.")
65
+ rescue
66
+ # XXX-MAK: Incorporate the error from the parser, as it gives full,
67
+ # coloured context.
68
+ report(:error, "Failed to parse #{path}.")
69
+ return fatal
70
+ end
71
+ end
72
+
73
+ # This check will pass by default.
74
+ pass
75
+
76
+ # Initialize the keys written by this check.
77
+ @kb[:codes] = {}
78
+ @kb[:trees] = {}
79
+
80
+ # Load up the main file.
81
+ import(@kb[:main])
82
+
83
+ return
84
+
85
+ while true
86
+ # Get the list of all Includes, and prune any that have already had the
87
+ # files they reference parsed.
88
+ libs = Nasl::Include.all.map do |inc|
89
+ (@kb[:base] + inc.filename.text).basename
90
+ end
91
+
92
+ libs.delete_if { |lib| lib == @kb[:main] || @kb[:trees].has_key?(lib) }
93
+
94
+ break if libs.empty?
95
+
96
+ # Try and parse each library, continuing on failures.
97
+ libs.each { |lib| import(lib) }
98
+ end
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,63 @@
1
+ ################################################################################
2
+ # Copyright (c) 2011, Mak Kolybabi
3
+ # All rights reserved.
4
+ #
5
+ # Redistribution and use in source and binary forms, with or without
6
+ # modification, are permitted provided that the following conditions are met:
7
+ #
8
+ # 1. Redistributions of source code must retain the above copyright notice, this
9
+ # list of conditions and the following disclaimer.
10
+ #
11
+ # 2. Redistributions in binary form must reproduce the above copyright notice,
12
+ # this list of conditions and the following disclaimer in the documentation
13
+ # and/or other materials provided with the distribution.
14
+ #
15
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18
+ # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
19
+ # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20
+ # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21
+ # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
22
+ # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
23
+ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
+ ################################################################################
26
+
27
+ module Pedant
28
+ class CheckParseTestCode < Check
29
+ def self.requires
30
+ super + [:codes, :main, :test_mode]
31
+ end
32
+
33
+ def self.provides
34
+ super + [:trees]
35
+ end
36
+
37
+ def run
38
+ def import(path)
39
+ # Since there are potentially several ways to write the path leading to
40
+ # a file, we'll use the basename as the key for hashes. This will
41
+ # prevent parsing the same file multiple times.
42
+ file = path.basename
43
+
44
+ # Mark a placeholder key in the KB for this file. This will prevent us
45
+ # from trying to parse a library more than once if there is a failure.
46
+ @kb[:trees][file] = :pending
47
+
48
+ tree = Nasl::Parser.new.parse(@kb[:codes][file], path)
49
+ @kb[:trees][file] = tree
50
+ report(:info, "Parsed contents of #{path}.")
51
+ end
52
+
53
+ # This check will pass by default.
54
+ pass
55
+
56
+ # Initialize the keys written by this check.
57
+ @kb[:trees] = {}
58
+
59
+ # Load up the main file.
60
+ import(@kb[:main])
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,79 @@
1
+ ################################################################################
2
+ # Copyright (c) 2011, Mak Kolybabi
3
+ # All rights reserved.
4
+ #
5
+ # Redistribution and use in source and binary forms, with or without
6
+ # modification, are permitted provided that the following conditions are met:
7
+ #
8
+ # 1. Redistributions of source code must retain the above copyright notice, this
9
+ # list of conditions and the following disclaimer.
10
+ #
11
+ # 2. Redistributions in binary form must reproduce the above copyright notice,
12
+ # this list of conditions and the following disclaimer in the documentation
13
+ # and/or other materials provided with the distribution.
14
+ #
15
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18
+ # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
19
+ # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20
+ # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21
+ # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
22
+ # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
23
+ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
+ ################################################################################
26
+
27
+ module Pedant
28
+ class CheckPluginTypeNotSpecified < Check
29
+ def self.requires
30
+ super + [:main, :trees]
31
+ end
32
+
33
+ def run
34
+ # This check only applies to plugins.
35
+ return skip unless @kb[:main].extname == '.nasl'
36
+
37
+ args = []
38
+
39
+ tree = @kb[:trees][@kb[:main]]
40
+
41
+ tree.all(:Call).each do |node|
42
+ next unless node.name.name == 'script_set_attribute'
43
+ next unless node.arg.has_key? 'attribute'
44
+
45
+ # Pull out the attribute argument.
46
+ arg = node.arg['attribute']
47
+ next if !arg.is_a? Nasl::String
48
+ next if arg.text != 'plugin_type'
49
+
50
+ # Pull out the value argument.
51
+ arg = node.arg['value']
52
+ next if !arg.is_a? Nasl::String
53
+
54
+ # Ensure that the plugin type is valid.
55
+ unless ['combined', 'local', 'remote'].include? arg.text
56
+ report(:info, "Plugin is of unknown type #{arg.text}:\n#{arg.context(node)}")
57
+ return fail
58
+ end
59
+
60
+ args << [arg, node]
61
+ end
62
+
63
+ case args.length
64
+ when 0
65
+ report(:error, "Plugin does not specify a type.")
66
+ fail
67
+ when 1
68
+ arg = args.first[0]
69
+ call = args.first[1]
70
+ report(:info, "Plugin is of type #{arg.text}:\n#{arg.context(call)}")
71
+ pass
72
+ else
73
+ report(:error, "Plugin specifies multiple types.")
74
+ args.each { |arg, call| report(:error, arg.context(call)) }
75
+ fail
76
+ end
77
+ end
78
+ end
79
+ end
data/lib/pedant/cli.rb ADDED
@@ -0,0 +1,82 @@
1
+ ################################################################################
2
+ # Copyright (c) 2011, Mak Kolybabi
3
+ # All rights reserved.
4
+ #
5
+ # Redistribution and use in source and binary forms, with or without
6
+ # modification, are permitted provided that the following conditions are met:
7
+ #
8
+ # 1. Redistributions of source code must retain the above copyright notice, this
9
+ # list of conditions and the following disclaimer.
10
+ #
11
+ # 2. Redistributions in binary form must reproduce the above copyright notice,
12
+ # this list of conditions and the following disclaimer in the documentation
13
+ # and/or other materials provided with the distribution.
14
+ #
15
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18
+ # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
19
+ # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20
+ # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21
+ # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
22
+ # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
23
+ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
+ ################################################################################
26
+
27
+ require 'optparse'
28
+
29
+ module Pedant
30
+ class Cli
31
+ def self.run
32
+ cfg = {}
33
+
34
+ Command.initialize!
35
+
36
+ optparse = OptionParser.new do |opts|
37
+ opts.banner = "Usage: pedant [options] [command [args]]"
38
+
39
+ cfg[:verbose] = 0
40
+ opts.on('-v', '--verbose', 'Output more information') do
41
+ cfg[:verbose] += 1
42
+ end
43
+ end
44
+
45
+ optparse.parse!
46
+
47
+ # Sanity check the command line arguments.
48
+ if ARGV.empty?
49
+ puts "No command was specified."
50
+ puts
51
+ usage
52
+ exit 1
53
+ end
54
+
55
+ cmd = ARGV.shift
56
+ cls = Command.find(cmd)
57
+ if cls.nil? then
58
+ puts "Command '#{cmd}' not supported."
59
+ puts
60
+ usage
61
+ exit 1
62
+ end
63
+
64
+ # Run the command.
65
+ cls.run(cfg, ARGV)
66
+ end
67
+
68
+ def self.usage
69
+ puts "For the moment, you have to run Pedant from its top-level directory."
70
+ puts
71
+ puts "./bin/pedant [flags] [command] [filename ...]"
72
+ puts
73
+ puts "Flags:"
74
+ puts " -v Display more verbose (warning) messages. "
75
+ puts " -vv Display more verbose (informational) messages. "
76
+ puts
77
+ puts "Commands:"
78
+ puts " check Runs all included checks against the specified plugin(s)."
79
+ puts " test Runs the specified unit tests, all are selected by default."
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,96 @@
1
+ ################################################################################
2
+ # Copyright (c) 2011, Mak Kolybabi
3
+ # All rights reserved.
4
+ #
5
+ # Redistribution and use in source and binary forms, with or without
6
+ # modification, are permitted provided that the following conditions are met:
7
+ #
8
+ # 1. Redistributions of source code must retain the above copyright notice, this
9
+ # list of conditions and the following disclaimer.
10
+ #
11
+ # 2. Redistributions in binary form must reproduce the above copyright notice,
12
+ # this list of conditions and the following disclaimer in the documentation
13
+ # and/or other materials provided with the distribution.
14
+ #
15
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18
+ # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
19
+ # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20
+ # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21
+ # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
22
+ # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
23
+ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
+ ################################################################################
26
+
27
+ module Pedant
28
+ class Command
29
+ def self.initialize!
30
+ Dir.glob(Pedant.lib + 'pedant/commands/*.rb').each {|f| load(f)}
31
+ end
32
+
33
+ def self.all
34
+ (@_all ||= [])
35
+ end
36
+
37
+ def self.inherited(cls)
38
+ all << cls
39
+ end
40
+
41
+ def self.find(cmd)
42
+ all.each do |cls|
43
+ return cls if cls.binding == cmd
44
+ end
45
+
46
+ nil
47
+ end
48
+
49
+ def self.banner(title, width=80)
50
+ # Create center of banner.
51
+ middle = "[ #{title} ]"
52
+
53
+ # Make sure width is a float.
54
+ width = width.to_f
55
+
56
+ # Create bars on either side.
57
+ leftover = (width - middle.length) / 2
58
+ left = '-' * leftover.floor
59
+ right = '-' * leftover.ceil
60
+
61
+ left + middle + right
62
+ end
63
+
64
+ def self.run(cfg, args)
65
+ # Separate plugins and libraries from the rest of the arguments.
66
+ paths = args.select { |arg| arg =~ /(\/|\.(inc|nasl))$/ }
67
+ args -= paths
68
+
69
+ # If we have no paths to process, there's a problem. Special purpose
70
+ # commands that don't require files to be declared should override this
71
+ # method.
72
+ if paths.empty?
73
+ puts "No directories (/), libraries (.inc), or plugins (.nasl) were specified."
74
+ exit 1
75
+ end
76
+
77
+ # Collect all the paths together, recursively.
78
+ dirents = []
79
+ paths.each do |path|
80
+ Pathname.new(path).find do |dirent|
81
+ if dirent.file? && dirent.extname =~ /inc|nasl/
82
+ dirents << dirent
83
+ end
84
+ end
85
+ end
86
+
87
+ # If the command is capable of handling all the paths at once, send them
88
+ # in a group, otherwise send them individually.
89
+ if self.respond_to? :analyze_all then
90
+ analyze_all(cfg, dirents, args)
91
+ else
92
+ dirents.each { |d| analyze(cfg, d, args) }
93
+ end
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,76 @@
1
+ ################################################################################
2
+ # Copyright (c) 2011, Mak Kolybabi
3
+ # All rights reserved.
4
+ #
5
+ # Redistribution and use in source and binary forms, with or without
6
+ # modification, are permitted provided that the following conditions are met:
7
+ #
8
+ # 1. Redistributions of source code must retain the above copyright notice, this
9
+ # list of conditions and the following disclaimer.
10
+ #
11
+ # 2. Redistributions in binary form must reproduce the above copyright notice,
12
+ # this list of conditions and the following disclaimer in the documentation
13
+ # and/or other materials provided with the distribution.
14
+ #
15
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18
+ # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
19
+ # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20
+ # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21
+ # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
22
+ # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
23
+ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
+ ################################################################################
26
+
27
+ module Pedant
28
+ class CommandCheck < Command
29
+ def self.binding
30
+ 'check'
31
+ end
32
+
33
+ def self.analyze(cfg, path, args)
34
+ Check.initialize!
35
+
36
+ # Get a list of every existing check.
37
+ pending = Check.all
38
+
39
+ # Initialize the knowledge base where checks can store information for
40
+ # other checks.
41
+ kb = KnowledgeBase.new(:file_mode, path)
42
+
43
+ # Try to run each pending check, until we've run all our checks or
44
+ # deadlocked.
45
+ fatal = false
46
+ until pending.empty? || fatal
47
+ # Find all of the checks that can run right now.
48
+ ready = pending.select { |cls| cls.ready?(kb) }
49
+ break if ready.empty?
50
+
51
+ # Run all of the checks that are ready.
52
+ ready.each do |cls|
53
+ # Create a new check instance.
54
+ chk = cls.new(kb)
55
+ pending.delete(cls)
56
+
57
+ chk.run
58
+
59
+ # Fatal errors mean that no further checks should be processed.
60
+ if chk.result == :fatal
61
+ fatal = true
62
+ break
63
+ end
64
+
65
+ # Display the results of the check.
66
+ puts chk.report(cfg[:verbose])
67
+ end
68
+ end
69
+
70
+ # Notify the user if any checks did not run due to unsatisfied
71
+ # dependencies or a fatal error occurring before they had the chance to
72
+ # run.
73
+ pending.each { |cls| puts cls.new(kb).report(cfg[:verbose]) }
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,37 @@
1
+ ################################################################################
2
+ # Copyright (c) 2011, Mak Kolybabi
3
+ # All rights reserved.
4
+ #
5
+ # Redistribution and use in source and binary forms, with or without
6
+ # modification, are permitted provided that the following conditions are met:
7
+ #
8
+ # 1. Redistributions of source code must retain the above copyright notice, this
9
+ # list of conditions and the following disclaimer.
10
+ #
11
+ # 2. Redistributions in binary form must reproduce the above copyright notice,
12
+ # this list of conditions and the following disclaimer in the documentation
13
+ # and/or other materials provided with the distribution.
14
+ #
15
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18
+ # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
19
+ # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20
+ # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21
+ # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
22
+ # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
23
+ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
+ ################################################################################
26
+
27
+ module Pedant
28
+ class CommandTest < Command
29
+ def self.binding
30
+ 'test'
31
+ end
32
+
33
+ def self.run(cfg, args)
34
+ Test.initialize!(args)
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,42 @@
1
+ ################################################################################
2
+ # Copyright (c) 2011, Mak Kolybabi
3
+ # All rights reserved.
4
+ #
5
+ # Redistribution and use in source and binary forms, with or without
6
+ # modification, are permitted provided that the following conditions are met:
7
+ #
8
+ # 1. Redistributions of source code must retain the above copyright notice, this
9
+ # list of conditions and the following disclaimer.
10
+ #
11
+ # 2. Redistributions in binary form must reproduce the above copyright notice,
12
+ # this list of conditions and the following disclaimer in the documentation
13
+ # and/or other materials provided with the distribution.
14
+ #
15
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18
+ # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
19
+ # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20
+ # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21
+ # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
22
+ # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
23
+ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
+ ################################################################################
26
+
27
+ module Pedant
28
+ class KnowledgeBase < Hash
29
+ def initialize(mode, path=nil)
30
+ self[mode] = true
31
+
32
+ case mode
33
+ when :file_mode
34
+ self[:base] = path.dirname
35
+ self[:main] = path.basename
36
+ when :test_mode
37
+ self[:base] = Pathname.new('/var/empty')
38
+ self[:main] = Pathname.new('test.nasl')
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,59 @@
1
+ ################################################################################
2
+ # Copyright (c) 2011, Mak Kolybabi
3
+ # All rights reserved.
4
+ #
5
+ # Redistribution and use in source and binary forms, with or without
6
+ # modification, are permitted provided that the following conditions are met:
7
+ #
8
+ # 1. Redistributions of source code must retain the above copyright notice, this
9
+ # list of conditions and the following disclaimer.
10
+ #
11
+ # 2. Redistributions in binary form must reproduce the above copyright notice,
12
+ # this list of conditions and the following disclaimer in the documentation
13
+ # and/or other materials provided with the distribution.
14
+ #
15
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18
+ # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
19
+ # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20
+ # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21
+ # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
22
+ # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
23
+ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
+ ################################################################################
26
+
27
+ require 'test/unit'
28
+
29
+ module Pedant
30
+ module Test
31
+ def self.initialize!(args)
32
+ # Run all tests by default.
33
+ args = ['unit/*', 'unit/*/*'] if args.empty?
34
+
35
+ # Run each test or category of tests specified on the command line.
36
+ args.each do |test|
37
+ Dir.glob(Pedant.test + (test + '.rb')).each { |f| load(f) }
38
+ end
39
+
40
+ Check.initialize!
41
+ end
42
+
43
+ def check(result, cls, code)
44
+ # Create a knowledge base.
45
+ kb = KnowledgeBase.new(:test_mode)
46
+
47
+ # Put test code into the knowledge base.
48
+ kb[:codes] = {}
49
+ kb[:codes][kb[:main]] = code
50
+
51
+ # Create a new instance of the check, which will execute all dependencies.
52
+ chk = Pedant.const_get(cls).new(kb)
53
+
54
+ # Run the test and ensure we got the expected result.
55
+ chk.run
56
+ assert_equal(result, chk.result)
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,3 @@
1
+ module Pedant
2
+ VERSION = '0.0.1'
3
+ end