Class: EWorld::RouteScanner

Inherits:
Object
  • Object
show all
Defined in:
lib/scanners/route_scanner.rb

Constant Summary collapse

SCHEMA_FILE =
"#{App::Opt::get_base_path}#{App::Opt::OPT_PATH}/schema/routes.yml"
ROUTES =
'Routes'
FULLPATH =
'fullpath'
CODE =
'code'
PATH =
'path'
NAME =
'name'
META =
'meta'
COMPONENT =
'component'
TITLE =
'title'
TAB_PARENT =
'tabParent'
DISABLED =
'disabled'
ICON =
'icon'
INVISIBLE =
'invisible'
CHILDREN =
'children'
HAS_PAGE =
'hasPage'

Class Method Summary collapse

Class Method Details

.scan(project) ⇒ Object

Responsible for scanning the .codegen/routes/routes.yml file.

Returns:

  • Array

Raises:

  • (RuntimeError)


23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
# File 'lib/scanners/route_scanner.rb', line 23

def self.scan(project)
    raise RuntimeError, "Expected project type to be: #{Blufin::Projects::TYPE_QUASAR}, instead got: #{project[Blufin::Projects::TYPE]}" unless project[Blufin::Projects::TYPE] == Blufin::Projects::TYPE_QUASAR
    @errors         = []
    @codes          = []
    @files          = [] # Holds short version of file name.
    @files_expected = [] # Holds full-path to file.
    @files_to_write = [] # Holds list of files that need to be created/stubbed.
    begin
        @td                 = project[Blufin::Projects::TRANSIENT_DATA]
        @path_root          = Blufin::Strings::remove_surrounding_slashes(@td[Blufin::Projects::CG_QUASAR_ROOT])
        @path_routes_file   = Blufin::Strings::remove_surrounding_slashes(@td[Blufin::Projects::CG_QUASAR_ROUTES_FILE])
        @path_pages         = Blufin::Strings::remove_surrounding_slashes(@td[Blufin::Projects::CG_QUASAR_PAGES])
        @path_pages_ignore  = @td[Blufin::Projects::CG_QUASAR_PAGES_IGNORE]
        @project_path       = Blufin::Projects::get_project_path(project[Blufin::Projects::PROJECT_ID])
        @project_path_inner = Blufin::Projects::get_project_path(project[Blufin::Projects::PROJECT_ID], true)
        routes_file         = "#{@project_path_inner}/#{@path_routes_file}"
        # Make sure file exists.
        unless Blufin::Files::file_exists(routes_file)
            @errors << Blufin::ScannerError::add_error(nil, "File not found: #{Blufin::Terminal::format_invalid(routes_file)}")
            return {}, @errors
        end
        # Extract routes file content so we can parse/validate it.
        routes_content = []
        Blufin::Files::read_file(routes_file).each do |line|
            line = line.gsub("\n", '').gsub(/^\s*const\s*routes\s*=\s*\[/, '{ Routes: [')
            # Handle component/import lines.
            if line =~ /^\s*component:\s*\(\)\s*=>\s*import\s*\(['"]\s*@/
                line  = line.gsub(/component:\s*\(\)\s*=>\s*import\s*\(['"]\s*@/, '')
                line  = line.gsub(/['"]\s*\)\s*/, '')
                comma = (line == line.gsub(/,?\s*$/, '')) ? '' : ','
                routes_content << "#{line.split('/')[0]}component: '#{line.gsub(/,?\s*$/, '').strip}'#{comma}"
                next
            end
            break if line =~ /^\s*if\s*\(/
            routes_content << line unless line.strip == ''
        end
        # Remove trailing semi-colon.
        routes_content[routes_content.length - 1] = routes_content[routes_content.length - 1].gsub(/;*\s*$/, '')
        routes_content << '}'
        hash = {}
        eval("hash = #{Blufin::Arrays::convert_line_array_to_string(routes_content)}")
        json         = JSON.parse(hash.to_json)
        # Create tmp file so we can read it. There might be a better way but no time.
        tmp_filename = "/tmp/routes-content-#{Blufin::Strings::random_string(2)}.yaml"
        # Write tmp file.
        Blufin::Files::write_file(tmp_filename, Blufin::Arrays::convert_string_to_line_array(json.to_yaml))
        @routes_yml = Blufin::Yml::read_file(tmp_filename, SCHEMA_FILE)
        @routes_yml[ROUTES].each do |parent|
            parent_path      = parent[PATH]
            parent_title     = parent.has_key?(META) ? parent[META][TITLE] : nil
            parent_icon      = parent.has_key?(META) ? parent[META][ICON] : nil
            parent_has_page  = parent.has_key?(META) ? (parent[META][HAS_PAGE] ? true : false) : false
            parent_invisible = parent.has_key?(META) ? parent[META][INVISIBLE] : nil
            error_prefix     = "Parent path: #{parent_path} \xe2\x80\x94 "
            # Make sure HAS_PAGE is only ever false.
            @errors << Blufin::ScannerError::add_error(routes_file, "#{error_prefix}Unless has_page == true, it is not required.", "has_page: '#{parent_has_page}'") if parent.has_key?(META) && parent[META].has_key?(HAS_PAGE) && !parent_has_page
            # Make sure we have the correct meta properties for parent (based on invisible property).
            if parent_invisible
                @errors << Blufin::ScannerError::add_error(routes_file, "#{error_prefix}Invisible routes shouldn't have: icon") unless parent_icon.nil?
            else
                @errors << Blufin::ScannerError::add_error(routes_file, "#{error_prefix}Missing meta property: icon") if parent_icon.nil?
            end
            @errors << Blufin::ScannerError::add_error(routes_file, "#{error_prefix}Missing meta property: title") if parent_title.nil?
            # Make sure properties are in the correct order.
            expected = {
                PATH      => true,
                META      => false,
                COMPONENT => true,
                CHILDREN  => false
            }
            Blufin::Validate::assert_valid_keys(expected, parent.keys, routes_file)
            # Make sure meta properties are in the correct order.
            if parent.has_key?(META)
                expected = {
                    TITLE     => false,
                    ICON      => false,
                    HAS_PAGE  => false,
                    INVISIBLE => false
                }
                Blufin::Validate::assert_valid_keys(expected, parent[META].keys, routes_file)
            end
            # Make sure parent path(s) have a preceding slash.
            @errors << Blufin::ScannerError::add_error(routes_file, "#{error_prefix}Parent path must have preceding slash.") unless parent[PATH] =~ /^\//
            # Validate children, if they exist.
            validate_children(parent, Blufin::Strings::remove_surrounding_slashes(parent[PATH]), routes_file, error_prefix) if parent.has_key?(CHILDREN)
        end

    rescue => e

        Blufin::Terminal::print_exception(e)

    end

    # Check for rogue files.
    path_to_pages = "#{@project_path_inner}/#{@path_pages}"
    Blufin::Files::get_files_in_dir(path_to_pages).each do |file|
        next if file =~ /#{path_to_pages}\/(#{@path_pages_ignore.join('|')})\/[a-z0-9]/
        unless @files_expected.include?(file.downcase)
            @errors << Blufin::ScannerError::add_error(routes_file, "Rogue file: #{file}")
        end
    end

    return @files_to_write, @errors

end