We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Stdin for templates is broken
As reported here https://github.com/awslabs/aws-cfn-lint-visual-studio-code/issues/47 cfn-lint has broken the ability to use stdin to provide templates. 

The result is the help documentation is provided


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `src/cfnlint/core.py`
Content:
```
1 """
2   Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 
4   Permission is hereby granted, free of charge, to any person obtaining a copy of this
5   software and associated documentation files (the "Software"), to deal in the Software
6   without restriction, including without limitation the rights to use, copy, modify,
7   merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
8   permit persons to whom the Software is furnished to do so.
9 
10   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
11   INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
12   PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
13   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
14   OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
15   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
16 """
17 import logging
18 import os
19 from jsonschema.exceptions import ValidationError
20 from cfnlint import RulesCollection
21 import cfnlint.config
22 import cfnlint.formatters
23 import cfnlint.decode
24 import cfnlint.maintenance
25 from cfnlint.helpers import REGIONS
26 
27 
28 LOGGER = logging.getLogger('cfnlint')
29 DEFAULT_RULESDIR = os.path.join(os.path.dirname(__file__), 'rules')
30 
31 
32 class CfnLintExitException(Exception):
33     """Generic exception used when the cli should exit"""
34     def __init__(self, msg=None, exit_code=1):
35         if msg is None:
36             msg = 'process failed with exit code %s' % exit_code
37         super(CfnLintExitException, self).__init__(msg)
38         self.exit_code = exit_code
39 
40 
41 class InvalidRegionException(CfnLintExitException):
42     """When an unsupported/invalid region is supplied"""
43 
44 
45 class UnexpectedRuleException(CfnLintExitException):
46     """When processing a rule fails in an unexpected way"""
47 
48 
49 def run_cli(filename, template, rules, regions, override_spec):
50     """Process args and run"""
51 
52     if override_spec:
53         cfnlint.helpers.override_specs(override_spec)
54 
55     return run_checks(filename, template, rules, regions)
56 
57 
58 def get_exit_code(matches):
59     """ Determine exit code """
60     exit_code = 0
61     for match in matches:
62         if match.rule.id[0] == 'I':
63             exit_code = exit_code | 8
64         elif match.rule.id[0] == 'W':
65             exit_code = exit_code | 4
66         elif match.rule.id[0] == 'E':
67             exit_code = exit_code | 2
68 
69     return exit_code
70 
71 
72 def get_formatter(fmt):
73     """ Get Formatter"""
74     formatter = {}
75     if fmt:
76         if fmt == 'quiet':
77             formatter = cfnlint.formatters.QuietFormatter()
78         elif fmt == 'parseable':
79             # pylint: disable=bad-option-value
80             formatter = cfnlint.formatters.ParseableFormatter()
81         elif fmt == 'json':
82             formatter = cfnlint.formatters.JsonFormatter()
83     else:
84         formatter = cfnlint.formatters.Formatter()
85 
86     return formatter
87 
88 
89 def get_rules(rulesdir, ignore_rules, include_rules, configure_rules=None, include_experimental=False):
90     """Get rules"""
91     rules = RulesCollection(ignore_rules, include_rules, configure_rules, include_experimental)
92     rules_dirs = [DEFAULT_RULESDIR] + rulesdir
93     try:
94         for rules_dir in rules_dirs:
95             rules.create_from_directory(rules_dir)
96     except OSError as e:
97         raise UnexpectedRuleException('Tried to append rules but got an error: %s' % str(e), 1)
98     return rules
99 
100 
101 def configure_logging(debug_logging):
102     """ Backwards compatibility for integrators """
103     LOGGER.info('Update your integrations to use "cfnlint.config.configure_logging" instead')
104     cfnlint.config.configure_logging(debug_logging, False)
105 
106 
107 def get_args_filenames(cli_args):
108     """ Get Template Configuration items and set them as default values"""
109     try:
110         config = cfnlint.config.ConfigMixIn(cli_args)
111     except ValidationError as e:
112         LOGGER.error('Error parsing config file: %s', str(e))
113         exit(1)
114 
115     fmt = config.format
116     formatter = get_formatter(fmt)
117 
118     if config.update_specs:
119         cfnlint.maintenance.update_resource_specs()
120         exit(0)
121 
122     if config.update_documentation:
123         # Get ALL rules (ignore the CLI settings))
124         documentation_rules = cfnlint.core.get_rules([], [], ['I', 'E', 'W'], {}, True)
125         cfnlint.maintenance.update_documentation(documentation_rules)
126         exit(0)
127 
128     if config.update_iam_policies:
129         cfnlint.maintenance.update_iam_policies()
130         exit(0)
131 
132     if config.listrules:
133         rules = cfnlint.core.get_rules(
134             config.append_rules,
135             config.ignore_checks,
136             config.include_checks,
137             config.configure_rules
138         )
139         print(rules)
140         exit(0)
141 
142     if not config.templates:
143         # Not specified, print the help
144         config.parser.print_help()
145         exit(1)
146 
147     return(config, config.templates, formatter)
148 
149 
150 def get_template_rules(filename, args):
151     """ Get Template Configuration items and set them as default values"""
152 
153     (template, matches) = cfnlint.decode.decode(filename, args.ignore_bad_template)
154 
155     if matches:
156         return(template, [], matches)
157 
158     args.template_args = template
159 
160     rules = cfnlint.core.get_rules(
161         args.append_rules,
162         args.ignore_checks,
163         args.include_checks,
164         args.configure_rules,
165         args.include_experimental,
166     )
167 
168     return(template, rules, [])
169 
170 
171 def run_checks(filename, template, rules, regions):
172     """Run Checks against the template"""
173     if regions:
174         if not set(regions).issubset(set(REGIONS)):
175             unsupported_regions = list(set(regions).difference(set(REGIONS)))
176             msg = 'Regions %s are unsupported. Supported regions are %s' % (unsupported_regions, REGIONS)
177             raise InvalidRegionException(msg, 32)
178 
179     matches = []
180 
181     runner = cfnlint.Runner(rules, filename, template, regions)
182     matches.extend(runner.transform())
183     # Only do rule analysis if Transform was successful
184     if not matches:
185         try:
186             matches.extend(runner.run())
187         except Exception as err:  # pylint: disable=W0703
188             msg = 'Tried to process rules on file %s but got an error: %s' % (filename, str(err))
189             UnexpectedRuleException(msg, 1)
190     matches.sort(key=lambda x: (x.filename, x.linenumber, x.rule.id))
191 
192     return(matches)
193
```

Path: `src/cfnlint/rules/templates/LimitSize.py`
Content:
```
1 """
2   Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 
4   Permission is hereby granted, free of charge, to any person obtaining a copy of this
5   software and associated documentation files (the "Software"), to deal in the Software
6   without restriction, including without limitation the rights to use, copy, modify,
7   merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
8   permit persons to whom the Software is furnished to do so.
9 
10   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
11   INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
12   PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
13   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
14   OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
15   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
16 """
17 import os
18 from cfnlint import CloudFormationLintRule
19 from cfnlint import RuleMatch
20 from cfnlint.helpers import LIMITS
21 try:  # pragma: no cover
22     from pathlib import Path
23 except ImportError:  # pragma: no cover
24     from pathlib2 import Path
25 
26 
27 
28 class LimitSize(CloudFormationLintRule):
29     """Check Template Size"""
30     id = 'E1002'
31     shortdesc = 'Template size limit'
32     description = 'Check the size of the template is less than the upper limit'
33     source_url = 'https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cloudformation-limits.html'
34     tags = ['limits']
35 
36     def match(self, cfn):
37         """Basic Matching"""
38         matches = []
39 
40         # Check number of resources against the defined limit
41         filename = cfn.filename
42 
43         # Only check if the file exists. The template could be passed in using stdIn
44         if Path(filename).is_file():
45             statinfo = os.stat(filename)
46             if statinfo.st_size > LIMITS['template']['body']:
47                 message = 'The template file size ({0} bytes) exceeds the limit ({1} bytes)'
48                 matches.append(RuleMatch(['Template'], message.format(statinfo.st_size, LIMITS['template']['body'])))
49 
50         return matches
51
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/src/cfnlint/core.py b/src/cfnlint/core.py
--- a/src/cfnlint/core.py
+++ b/src/cfnlint/core.py
@@ -16,6 +16,7 @@
 """
 import logging
 import os
+import sys
 from jsonschema.exceptions import ValidationError
 from cfnlint import RulesCollection
 import cfnlint.config
@@ -139,6 +140,9 @@
         print(rules)
         exit(0)
 
+    if not sys.stdin.isatty():
+        return(config, [None], formatter)
+
     if not config.templates:
         # Not specified, print the help
         config.parser.print_help()
diff --git a/src/cfnlint/rules/templates/LimitSize.py b/src/cfnlint/rules/templates/LimitSize.py
--- a/src/cfnlint/rules/templates/LimitSize.py
+++ b/src/cfnlint/rules/templates/LimitSize.py
@@ -41,10 +41,11 @@
         filename = cfn.filename
 
         # Only check if the file exists. The template could be passed in using stdIn
-        if Path(filename).is_file():
-            statinfo = os.stat(filename)
-            if statinfo.st_size > LIMITS['template']['body']:
-                message = 'The template file size ({0} bytes) exceeds the limit ({1} bytes)'
-                matches.append(RuleMatch(['Template'], message.format(statinfo.st_size, LIMITS['template']['body'])))
+        if filename:
+            if Path(filename).is_file():
+                statinfo = os.stat(filename)
+                if statinfo.st_size > LIMITS['template']['body']:
+                    message = 'The template file size ({0} bytes) exceeds the limit ({1} bytes)'
+                    matches.append(RuleMatch(['Template'], message.format(statinfo.st_size, LIMITS['template']['body'])))
 
         return matches

{"golden_diff": "diff --git a/src/cfnlint/core.py b/src/cfnlint/core.py\n--- a/src/cfnlint/core.py\n+++ b/src/cfnlint/core.py\n@@ -16,6 +16,7 @@\n \"\"\"\n import logging\n import os\n+import sys\n from jsonschema.exceptions import ValidationError\n from cfnlint import RulesCollection\n import cfnlint.config\n@@ -139,6 +140,9 @@\n         print(rules)\n         exit(0)\n \n+    if not sys.stdin.isatty():\n+        return(config, [None], formatter)\n+\n     if not config.templates:\n         # Not specified, print the help\n         config.parser.print_help()\ndiff --git a/src/cfnlint/rules/templates/LimitSize.py b/src/cfnlint/rules/templates/LimitSize.py\n--- a/src/cfnlint/rules/templates/LimitSize.py\n+++ b/src/cfnlint/rules/templates/LimitSize.py\n@@ -41,10 +41,11 @@\n         filename = cfn.filename\n \n         # Only check if the file exists. The template could be passed in using stdIn\n-        if Path(filename).is_file():\n-            statinfo = os.stat(filename)\n-            if statinfo.st_size > LIMITS['template']['body']:\n-                message = 'The template file size ({0} bytes) exceeds the limit ({1} bytes)'\n-                matches.append(RuleMatch(['Template'], message.format(statinfo.st_size, LIMITS['template']['body'])))\n+        if filename:\n+            if Path(filename).is_file():\n+                statinfo = os.stat(filename)\n+                if statinfo.st_size > LIMITS['template']['body']:\n+                    message = 'The template file size ({0} bytes) exceeds the limit ({1} bytes)'\n+                    matches.append(RuleMatch(['Template'], message.format(statinfo.st_size, LIMITS['template']['body'])))\n \n         return matches\n", "issue": "Stdin for templates is broken\nAs reported here https://github.com/awslabs/aws-cfn-lint-visual-studio-code/issues/47 cfn-lint has broken the ability to use stdin to provide templates. \r\n\r\nThe result is the help documentation is provided\r\n\n", "before_files": [{"content": "\"\"\"\n  Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.\n\n  Permission is hereby granted, free of charge, to any person obtaining a copy of this\n  software and associated documentation files (the \"Software\"), to deal in the Software\n  without restriction, including without limitation the rights to use, copy, modify,\n  merge, publish, distribute, sublicense, and/or sell copies of the Software, and to\n  permit persons to whom the Software is furnished to do so.\n\n  THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n  INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n  PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n  HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n  SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\"\"\"\nimport logging\nimport os\nfrom jsonschema.exceptions import ValidationError\nfrom cfnlint import RulesCollection\nimport cfnlint.config\nimport cfnlint.formatters\nimport cfnlint.decode\nimport cfnlint.maintenance\nfrom cfnlint.helpers import REGIONS\n\n\nLOGGER = logging.getLogger('cfnlint')\nDEFAULT_RULESDIR = os.path.join(os.path.dirname(__file__), 'rules')\n\n\nclass CfnLintExitException(Exception):\n    \"\"\"Generic exception used when the cli should exit\"\"\"\n    def __init__(self, msg=None, exit_code=1):\n        if msg is None:\n            msg = 'process failed with exit code %s' % exit_code\n        super(CfnLintExitException, self).__init__(msg)\n        self.exit_code = exit_code\n\n\nclass InvalidRegionException(CfnLintExitException):\n    \"\"\"When an unsupported/invalid region is supplied\"\"\"\n\n\nclass UnexpectedRuleException(CfnLintExitException):\n    \"\"\"When processing a rule fails in an unexpected way\"\"\"\n\n\ndef run_cli(filename, template, rules, regions, override_spec):\n    \"\"\"Process args and run\"\"\"\n\n    if override_spec:\n        cfnlint.helpers.override_specs(override_spec)\n\n    return run_checks(filename, template, rules, regions)\n\n\ndef get_exit_code(matches):\n    \"\"\" Determine exit code \"\"\"\n    exit_code = 0\n    for match in matches:\n        if match.rule.id[0] == 'I':\n            exit_code = exit_code | 8\n        elif match.rule.id[0] == 'W':\n            exit_code = exit_code | 4\n        elif match.rule.id[0] == 'E':\n            exit_code = exit_code | 2\n\n    return exit_code\n\n\ndef get_formatter(fmt):\n    \"\"\" Get Formatter\"\"\"\n    formatter = {}\n    if fmt:\n        if fmt == 'quiet':\n            formatter = cfnlint.formatters.QuietFormatter()\n        elif fmt == 'parseable':\n            # pylint: disable=bad-option-value\n            formatter = cfnlint.formatters.ParseableFormatter()\n        elif fmt == 'json':\n            formatter = cfnlint.formatters.JsonFormatter()\n    else:\n        formatter = cfnlint.formatters.Formatter()\n\n    return formatter\n\n\ndef get_rules(rulesdir, ignore_rules, include_rules, configure_rules=None, include_experimental=False):\n    \"\"\"Get rules\"\"\"\n    rules = RulesCollection(ignore_rules, include_rules, configure_rules, include_experimental)\n    rules_dirs = [DEFAULT_RULESDIR] + rulesdir\n    try:\n        for rules_dir in rules_dirs:\n            rules.create_from_directory(rules_dir)\n    except OSError as e:\n        raise UnexpectedRuleException('Tried to append rules but got an error: %s' % str(e), 1)\n    return rules\n\n\ndef configure_logging(debug_logging):\n    \"\"\" Backwards compatibility for integrators \"\"\"\n    LOGGER.info('Update your integrations to use \"cfnlint.config.configure_logging\" instead')\n    cfnlint.config.configure_logging(debug_logging, False)\n\n\ndef get_args_filenames(cli_args):\n    \"\"\" Get Template Configuration items and set them as default values\"\"\"\n    try:\n        config = cfnlint.config.ConfigMixIn(cli_args)\n    except ValidationError as e:\n        LOGGER.error('Error parsing config file: %s', str(e))\n        exit(1)\n\n    fmt = config.format\n    formatter = get_formatter(fmt)\n\n    if config.update_specs:\n        cfnlint.maintenance.update_resource_specs()\n        exit(0)\n\n    if config.update_documentation:\n        # Get ALL rules (ignore the CLI settings))\n        documentation_rules = cfnlint.core.get_rules([], [], ['I', 'E', 'W'], {}, True)\n        cfnlint.maintenance.update_documentation(documentation_rules)\n        exit(0)\n\n    if config.update_iam_policies:\n        cfnlint.maintenance.update_iam_policies()\n        exit(0)\n\n    if config.listrules:\n        rules = cfnlint.core.get_rules(\n            config.append_rules,\n            config.ignore_checks,\n            config.include_checks,\n            config.configure_rules\n        )\n        print(rules)\n        exit(0)\n\n    if not config.templates:\n        # Not specified, print the help\n        config.parser.print_help()\n        exit(1)\n\n    return(config, config.templates, formatter)\n\n\ndef get_template_rules(filename, args):\n    \"\"\" Get Template Configuration items and set them as default values\"\"\"\n\n    (template, matches) = cfnlint.decode.decode(filename, args.ignore_bad_template)\n\n    if matches:\n        return(template, [], matches)\n\n    args.template_args = template\n\n    rules = cfnlint.core.get_rules(\n        args.append_rules,\n        args.ignore_checks,\n        args.include_checks,\n        args.configure_rules,\n        args.include_experimental,\n    )\n\n    return(template, rules, [])\n\n\ndef run_checks(filename, template, rules, regions):\n    \"\"\"Run Checks against the template\"\"\"\n    if regions:\n        if not set(regions).issubset(set(REGIONS)):\n            unsupported_regions = list(set(regions).difference(set(REGIONS)))\n            msg = 'Regions %s are unsupported. Supported regions are %s' % (unsupported_regions, REGIONS)\n            raise InvalidRegionException(msg, 32)\n\n    matches = []\n\n    runner = cfnlint.Runner(rules, filename, template, regions)\n    matches.extend(runner.transform())\n    # Only do rule analysis if Transform was successful\n    if not matches:\n        try:\n            matches.extend(runner.run())\n        except Exception as err:  # pylint: disable=W0703\n            msg = 'Tried to process rules on file %s but got an error: %s' % (filename, str(err))\n            UnexpectedRuleException(msg, 1)\n    matches.sort(key=lambda x: (x.filename, x.linenumber, x.rule.id))\n\n    return(matches)\n", "path": "src/cfnlint/core.py"}, {"content": "\"\"\"\n  Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.\n\n  Permission is hereby granted, free of charge, to any person obtaining a copy of this\n  software and associated documentation files (the \"Software\"), to deal in the Software\n  without restriction, including without limitation the rights to use, copy, modify,\n  merge, publish, distribute, sublicense, and/or sell copies of the Software, and to\n  permit persons to whom the Software is furnished to do so.\n\n  THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n  INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n  PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n  HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n  SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\"\"\"\nimport os\nfrom cfnlint import CloudFormationLintRule\nfrom cfnlint import RuleMatch\nfrom cfnlint.helpers import LIMITS\ntry:  # pragma: no cover\n    from pathlib import Path\nexcept ImportError:  # pragma: no cover\n    from pathlib2 import Path\n\n\n\nclass LimitSize(CloudFormationLintRule):\n    \"\"\"Check Template Size\"\"\"\n    id = 'E1002'\n    shortdesc = 'Template size limit'\n    description = 'Check the size of the template is less than the upper limit'\n    source_url = 'https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cloudformation-limits.html'\n    tags = ['limits']\n\n    def match(self, cfn):\n        \"\"\"Basic Matching\"\"\"\n        matches = []\n\n        # Check number of resources against the defined limit\n        filename = cfn.filename\n\n        # Only check if the file exists. The template could be passed in using stdIn\n        if Path(filename).is_file():\n            statinfo = os.stat(filename)\n            if statinfo.st_size > LIMITS['template']['body']:\n                message = 'The template file size ({0} bytes) exceeds the limit ({1} bytes)'\n                matches.append(RuleMatch(['Template'], message.format(statinfo.st_size, LIMITS['template']['body'])))\n\n        return matches\n", "path": "src/cfnlint/rules/templates/LimitSize.py"}], "after_files": [{"content": "\"\"\"\n  Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.\n\n  Permission is hereby granted, free of charge, to any person obtaining a copy of this\n  software and associated documentation files (the \"Software\"), to deal in the Software\n  without restriction, including without limitation the rights to use, copy, modify,\n  merge, publish, distribute, sublicense, and/or sell copies of the Software, and to\n  permit persons to whom the Software is furnished to do so.\n\n  THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n  INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n  PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n  HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n  SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\"\"\"\nimport logging\nimport os\nimport sys\nfrom jsonschema.exceptions import ValidationError\nfrom cfnlint import RulesCollection\nimport cfnlint.config\nimport cfnlint.formatters\nimport cfnlint.decode\nimport cfnlint.maintenance\nfrom cfnlint.helpers import REGIONS\n\n\nLOGGER = logging.getLogger('cfnlint')\nDEFAULT_RULESDIR = os.path.join(os.path.dirname(__file__), 'rules')\n\n\nclass CfnLintExitException(Exception):\n    \"\"\"Generic exception used when the cli should exit\"\"\"\n    def __init__(self, msg=None, exit_code=1):\n        if msg is None:\n            msg = 'process failed with exit code %s' % exit_code\n        super(CfnLintExitException, self).__init__(msg)\n        self.exit_code = exit_code\n\n\nclass InvalidRegionException(CfnLintExitException):\n    \"\"\"When an unsupported/invalid region is supplied\"\"\"\n\n\nclass UnexpectedRuleException(CfnLintExitException):\n    \"\"\"When processing a rule fails in an unexpected way\"\"\"\n\n\ndef run_cli(filename, template, rules, regions, override_spec):\n    \"\"\"Process args and run\"\"\"\n\n    if override_spec:\n        cfnlint.helpers.override_specs(override_spec)\n\n    return run_checks(filename, template, rules, regions)\n\n\ndef get_exit_code(matches):\n    \"\"\" Determine exit code \"\"\"\n    exit_code = 0\n    for match in matches:\n        if match.rule.id[0] == 'I':\n            exit_code = exit_code | 8\n        elif match.rule.id[0] == 'W':\n            exit_code = exit_code | 4\n        elif match.rule.id[0] == 'E':\n            exit_code = exit_code | 2\n\n    return exit_code\n\n\ndef get_formatter(fmt):\n    \"\"\" Get Formatter\"\"\"\n    formatter = {}\n    if fmt:\n        if fmt == 'quiet':\n            formatter = cfnlint.formatters.QuietFormatter()\n        elif fmt == 'parseable':\n            # pylint: disable=bad-option-value\n            formatter = cfnlint.formatters.ParseableFormatter()\n        elif fmt == 'json':\n            formatter = cfnlint.formatters.JsonFormatter()\n    else:\n        formatter = cfnlint.formatters.Formatter()\n\n    return formatter\n\n\ndef get_rules(rulesdir, ignore_rules, include_rules, configure_rules=None, include_experimental=False):\n    \"\"\"Get rules\"\"\"\n    rules = RulesCollection(ignore_rules, include_rules, configure_rules, include_experimental)\n    rules_dirs = [DEFAULT_RULESDIR] + rulesdir\n    try:\n        for rules_dir in rules_dirs:\n            rules.create_from_directory(rules_dir)\n    except OSError as e:\n        raise UnexpectedRuleException('Tried to append rules but got an error: %s' % str(e), 1)\n    return rules\n\n\ndef configure_logging(debug_logging):\n    \"\"\" Backwards compatibility for integrators \"\"\"\n    LOGGER.info('Update your integrations to use \"cfnlint.config.configure_logging\" instead')\n    cfnlint.config.configure_logging(debug_logging, False)\n\n\ndef get_args_filenames(cli_args):\n    \"\"\" Get Template Configuration items and set them as default values\"\"\"\n    try:\n        config = cfnlint.config.ConfigMixIn(cli_args)\n    except ValidationError as e:\n        LOGGER.error('Error parsing config file: %s', str(e))\n        exit(1)\n\n    fmt = config.format\n    formatter = get_formatter(fmt)\n\n    if config.update_specs:\n        cfnlint.maintenance.update_resource_specs()\n        exit(0)\n\n    if config.update_documentation:\n        # Get ALL rules (ignore the CLI settings))\n        documentation_rules = cfnlint.core.get_rules([], [], ['I', 'E', 'W'], {}, True)\n        cfnlint.maintenance.update_documentation(documentation_rules)\n        exit(0)\n\n    if config.update_iam_policies:\n        cfnlint.maintenance.update_iam_policies()\n        exit(0)\n\n    if config.listrules:\n        rules = cfnlint.core.get_rules(\n            config.append_rules,\n            config.ignore_checks,\n            config.include_checks,\n            config.configure_rules\n        )\n        print(rules)\n        exit(0)\n\n    if not sys.stdin.isatty():\n        return(config, [None], formatter)\n\n    if not config.templates:\n        # Not specified, print the help\n        config.parser.print_help()\n        exit(1)\n\n    return(config, config.templates, formatter)\n\n\ndef get_template_rules(filename, args):\n    \"\"\" Get Template Configuration items and set them as default values\"\"\"\n\n    (template, matches) = cfnlint.decode.decode(filename, args.ignore_bad_template)\n\n    if matches:\n        return(template, [], matches)\n\n    args.template_args = template\n\n    rules = cfnlint.core.get_rules(\n        args.append_rules,\n        args.ignore_checks,\n        args.include_checks,\n        args.configure_rules,\n        args.include_experimental,\n    )\n\n    return(template, rules, [])\n\n\ndef run_checks(filename, template, rules, regions):\n    \"\"\"Run Checks against the template\"\"\"\n    if regions:\n        if not set(regions).issubset(set(REGIONS)):\n            unsupported_regions = list(set(regions).difference(set(REGIONS)))\n            msg = 'Regions %s are unsupported. Supported regions are %s' % (unsupported_regions, REGIONS)\n            raise InvalidRegionException(msg, 32)\n\n    matches = []\n\n    runner = cfnlint.Runner(rules, filename, template, regions)\n    matches.extend(runner.transform())\n    # Only do rule analysis if Transform was successful\n    if not matches:\n        try:\n            matches.extend(runner.run())\n        except Exception as err:  # pylint: disable=W0703\n            msg = 'Tried to process rules on file %s but got an error: %s' % (filename, str(err))\n            UnexpectedRuleException(msg, 1)\n    matches.sort(key=lambda x: (x.filename, x.linenumber, x.rule.id))\n\n    return(matches)\n", "path": "src/cfnlint/core.py"}, {"content": "\"\"\"\n  Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.\n\n  Permission is hereby granted, free of charge, to any person obtaining a copy of this\n  software and associated documentation files (the \"Software\"), to deal in the Software\n  without restriction, including without limitation the rights to use, copy, modify,\n  merge, publish, distribute, sublicense, and/or sell copies of the Software, and to\n  permit persons to whom the Software is furnished to do so.\n\n  THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n  INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n  PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n  HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n  SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\"\"\"\nimport os\nfrom cfnlint import CloudFormationLintRule\nfrom cfnlint import RuleMatch\nfrom cfnlint.helpers import LIMITS\ntry:  # pragma: no cover\n    from pathlib import Path\nexcept ImportError:  # pragma: no cover\n    from pathlib2 import Path\n\n\n\nclass LimitSize(CloudFormationLintRule):\n    \"\"\"Check Template Size\"\"\"\n    id = 'E1002'\n    shortdesc = 'Template size limit'\n    description = 'Check the size of the template is less than the upper limit'\n    source_url = 'https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cloudformation-limits.html'\n    tags = ['limits']\n\n    def match(self, cfn):\n        \"\"\"Basic Matching\"\"\"\n        matches = []\n\n        # Check number of resources against the defined limit\n        filename = cfn.filename\n\n        # Only check if the file exists. The template could be passed in using stdIn\n        if filename:\n            if Path(filename).is_file():\n                statinfo = os.stat(filename)\n                if statinfo.st_size > LIMITS['template']['body']:\n                    message = 'The template file size ({0} bytes) exceeds the limit ({1} bytes)'\n                    matches.append(RuleMatch(['Template'], message.format(statinfo.st_size, LIMITS['template']['body'])))\n\n        return matches\n", "path": "src/cfnlint/rules/templates/LimitSize.py"}]}