├── .classpath
├── .gitignore
├── .gitlab-ci.yml
├── .project
├── .settings
├── org.eclipse.jdt.core.prefs
├── org.eclipse.jdt.ui.prefs
├── org.eclipse.m2e.core.prefs
└── org.eclipse.wst.common.project.facet.core.xml
├── .travis.yml
├── CONTRIBUTING.md
├── ISSUE_TEMPLATE.md
├── LICENSE
├── README.md
├── logo.jpeg
├── pom.xml
└── src
├── main
├── java
│ └── fr
│ │ └── univartois
│ │ └── sonargo
│ │ ├── SonarGoPlugin.java
│ │ ├── core
│ │ ├── Parser.java
│ │ ├── ProjectExplorer.java
│ │ ├── language
│ │ │ ├── GoGrammar.java
│ │ │ ├── GoLanguage.java
│ │ │ ├── GoLexer.java
│ │ │ ├── GoParser.java
│ │ │ └── GoQualityProfile.java
│ │ ├── metrics
│ │ │ ├── GoLineMetrics.java
│ │ │ └── GoMetricSensor.java
│ │ ├── rules
│ │ │ ├── GoError.java
│ │ │ ├── GoKeyRule.java
│ │ │ ├── GoLintIssueLoaderSensor.java
│ │ │ └── GoLintRulesDefinition.java
│ │ └── settings
│ │ │ └── GoProperties.java
│ │ ├── coverage
│ │ ├── CoverageParser.java
│ │ ├── CoverageSensor.java
│ │ ├── FactoryLine.java
│ │ ├── LineCoverage.java
│ │ └── LinePredicate.java
│ │ ├── gotest
│ │ ├── FunctionFinder.java
│ │ ├── GoJunitParser.java
│ │ ├── GoTestCase.java
│ │ ├── GoTestFile.java
│ │ ├── GoTestReportSaver.java
│ │ └── GoTestSensor.java
│ │ ├── highlighter
│ │ ├── Colorizer.java
│ │ └── HighlighterSensor.java
│ │ └── toolkit
│ │ ├── GoColorizer.java
│ │ └── GoToolkit.java
└── resources
│ ├── key.properties
│ ├── profile.properties
│ └── rules
│ └── golint-rules.xml
└── test
├── java
└── fr
│ └── univartois
│ └── sonargo
│ ├── AbstractSonarTest.java
│ ├── AllTests.java
│ ├── FunctionFinderTest.java
│ ├── GoPluginTest.java
│ ├── TestUtils.java
│ ├── core
│ ├── ProjectExplorerTest.java
│ ├── language
│ │ ├── GoGrammarTest.java
│ │ ├── GoLanguageTest.java
│ │ ├── GoLexerTest.java
│ │ └── GoQualityProfileTest.java
│ ├── metrics
│ │ └── GoMetricSensorTest.java
│ ├── rules
│ │ ├── EvalTest.java
│ │ ├── GoErrorTest.java
│ │ ├── GoLintIssueLoaderSendorTest.java
│ │ ├── GoLintRulesDefinitionTest.java
│ │ ├── ReportEvalStoryTest.java
│ │ └── expression.story
│ └── settings
│ │ └── GoPropertiesTest.java
│ ├── coverage
│ └── CoverageSensorTest.java
│ ├── gotest
│ └── FunctionFinderTest.java
│ └── highlighter
│ └── ColorizerTest.java
└── resources
├── coverage
├── .ignoredfile
├── .sonar
│ └── test
├── bug
│ └── coverage.xml
├── issue60
│ └── a.go
├── issue61
│ ├── multilinecomment.go
│ ├── simplelinecomment.go
│ └── typestruct.go
├── mathutil
│ ├── coverage.out
│ ├── coverage.out.xml
│ ├── coverage.xml
│ ├── filewithnocoverage.go
│ ├── mathutil.go
│ └── mathutil_test.go
├── pixel
│ ├── coverage.out
│ ├── coverage.xml
│ ├── pixel.go
│ └── pixel_test.go
├── test
├── test.git
│ └── test
├── util
│ ├── cover.out
│ ├── coverage.out.xml
│ ├── coverage.xml
│ ├── util.go
│ ├── util2.go
│ ├── util2_test.go
│ └── util_test.go
└── vendor
│ └── fileexcludedinvendordirectory.txt
├── gotest
├── test1_test.go
├── test2_test.go
└── test_test.go
├── grammar
├── constant_expressions.go
├── import_complex_definition.go
├── import_simple_definition.go
├── package_definition.go
├── var_definition.go
└── var_fast_definition.go
├── highlighter
├── test.go
└── testbug1.go
├── key.properties
├── profile.properties
├── project
├── package1.go
├── package1_test.go
└── test.py
└── rules
└── golint-rules.xml
/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /target/
2 | /build/
3 | pom.xml.tag
4 | pom.xml.releaseBackup
5 | pom.xml.versionsBackup
6 | pom.xml.next
7 | release.properties
8 | dependency-reduced-pom.xml
9 | buildNumber.properties
10 | .mvn/timing.properties
11 | doc
12 | .sonar
13 | .idea/
14 | *.iml
15 | !./src/test/resources/coverage/.sonar
16 |
--------------------------------------------------------------------------------
/.gitlab-ci.yml:
--------------------------------------------------------------------------------
1 |
2 |
3 | artifact:
4 | script: "mvn clean install && mvn clean verify sonar:sonar"
5 | stage: build
6 | artifacts:
7 | paths:
8 | - target/*.jar
9 | tags:
10 | - maven
--------------------------------------------------------------------------------
/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | sonarqubego
4 |
5 |
6 |
7 |
8 |
9 | org.eclipse.xtext.ui.shared.xtextBuilder
10 |
11 |
12 |
13 |
14 | org.eclipse.jdt.core.javabuilder
15 |
16 |
17 |
18 |
19 | org.eclipse.wst.common.project.facet.core.builder
20 |
21 |
22 |
23 |
24 | org.eclipse.m2e.core.maven2Builder
25 |
26 |
27 |
28 |
29 |
30 | org.eclipse.m2e.core.maven2Nature
31 | org.eclipse.wst.common.project.facet.core.nature
32 | org.eclipse.jdt.core.javanature
33 | org.eclipse.xtext.ui.shared.xtextNature
34 |
35 |
36 |
--------------------------------------------------------------------------------
/.settings/org.eclipse.jdt.ui.prefs:
--------------------------------------------------------------------------------
1 | eclipse.preferences.version=1
2 | editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
3 | formatter_profile=_Java Conventions Artois
4 | formatter_settings_version=12
5 | org.eclipse.jdt.ui.exception.name=e
6 | org.eclipse.jdt.ui.gettersetter.use.is=true
7 | org.eclipse.jdt.ui.keywordthis=false
8 | org.eclipse.jdt.ui.overrideannotation=true
9 | sp_cleanup.add_default_serial_version_id=true
10 | sp_cleanup.add_generated_serial_version_id=false
11 | sp_cleanup.add_missing_annotations=true
12 | sp_cleanup.add_missing_deprecated_annotations=true
13 | sp_cleanup.add_missing_methods=false
14 | sp_cleanup.add_missing_nls_tags=false
15 | sp_cleanup.add_missing_override_annotations=true
16 | sp_cleanup.add_missing_override_annotations_interface_methods=true
17 | sp_cleanup.add_serial_version_id=false
18 | sp_cleanup.always_use_blocks=true
19 | sp_cleanup.always_use_parentheses_in_expressions=false
20 | sp_cleanup.always_use_this_for_non_static_field_access=false
21 | sp_cleanup.always_use_this_for_non_static_method_access=false
22 | sp_cleanup.convert_functional_interfaces=false
23 | sp_cleanup.convert_to_enhanced_for_loop=false
24 | sp_cleanup.correct_indentation=false
25 | sp_cleanup.format_source_code=true
26 | sp_cleanup.format_source_code_changes_only=false
27 | sp_cleanup.insert_inferred_type_arguments=false
28 | sp_cleanup.make_local_variable_final=true
29 | sp_cleanup.make_parameters_final=false
30 | sp_cleanup.make_private_fields_final=true
31 | sp_cleanup.make_type_abstract_if_missing_method=false
32 | sp_cleanup.make_variable_declarations_final=false
33 | sp_cleanup.never_use_blocks=false
34 | sp_cleanup.never_use_parentheses_in_expressions=true
35 | sp_cleanup.on_save_use_additional_actions=false
36 | sp_cleanup.organize_imports=true
37 | sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
38 | sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
39 | sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
40 | sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
41 | sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
42 | sp_cleanup.remove_private_constructors=true
43 | sp_cleanup.remove_redundant_type_arguments=false
44 | sp_cleanup.remove_trailing_whitespaces=false
45 | sp_cleanup.remove_trailing_whitespaces_all=true
46 | sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
47 | sp_cleanup.remove_unnecessary_casts=true
48 | sp_cleanup.remove_unnecessary_nls_tags=false
49 | sp_cleanup.remove_unused_imports=false
50 | sp_cleanup.remove_unused_local_variables=false
51 | sp_cleanup.remove_unused_private_fields=true
52 | sp_cleanup.remove_unused_private_members=false
53 | sp_cleanup.remove_unused_private_methods=true
54 | sp_cleanup.remove_unused_private_types=true
55 | sp_cleanup.sort_members=false
56 | sp_cleanup.sort_members_all=false
57 | sp_cleanup.use_anonymous_class_creation=false
58 | sp_cleanup.use_blocks=false
59 | sp_cleanup.use_blocks_only_for_return_and_throw=false
60 | sp_cleanup.use_lambda=true
61 | sp_cleanup.use_parentheses_in_expressions=false
62 | sp_cleanup.use_this_for_non_static_field_access=false
63 | sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
64 | sp_cleanup.use_this_for_non_static_method_access=false
65 | sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
66 |
--------------------------------------------------------------------------------
/.settings/org.eclipse.m2e.core.prefs:
--------------------------------------------------------------------------------
1 | activeProfiles=
2 | eclipse.preferences.version=1
3 | resolveWorkspaceProjects=true
4 | version=1
5 |
--------------------------------------------------------------------------------
/.settings/org.eclipse.wst.common.project.facet.core.xml:
--------------------------------------------------------------------------------
1 |
2 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | dist: trusty
2 | language: java
3 | sudo: false
4 | install: true
5 | addons:
6 | sonarcloud:
7 | organization: thibaultfalque-github
8 | token:
9 | secure: "fmvXUI+OCn3UThPkooHMJ7c/iwLQ4e8ZPBEP4lKNnMPvnO8jox4V9jBPhTcBZNHAn+SlMgV0C2ttZ6LjpJI+6ZEYi+AVBIGQb7RNdjpEue3nLNG1WzUbl0Byy/xwgWiIG1ffVXTkPdEoD6d9WoDvYr9p3Ff3n0/Op6GN0J27OU/7yq5OEXpwwsmS32yw4aAltZISLRWUPhqRrnV7aopfFr1zRGe4ddBe2UFIVH8gnTgYtYNF1FTiWdtPKeVDea3dnW9R/kwF/IFiVEk/gOXPFTWSOulFssc3o1p89yCFmnS4JZ8kK5IOnY1TZCVZ7MhprXLLRjy9+MlKIcwjlzsvAKHHc17krRKDsY4wZBT9QUa7nOG926YForIa9DOigQ4F+oMhiu2LRo/5qe2p9GgzRLx5RXsJ4rgGHPn6IkuVaX9qpvoyMwnS2fOy1NU93C8JDF1WKM/9RRBAKDpdI3iQIXqkPA3v86Jj/fkNTAKijqOPSKNiZzl5/5uysXLDIlSOKGkDurjRZ+H5gibx47nBm5Vx9ufq23hRWH55g1oMvUDj3XAs39Ih+Hqn1CwOfnTOC4gy6TE3fy5beE2cz7GVrO90eaog9IlGF0umIwAHb1PaEDkcLSpg3uWbAP7jrkqhhceqBeJJi98Ly+Hn0Nfkme6oBwbE9YqN/v7mSNLBa/g="
10 | branches:
11 | - maintenance
12 | jdk:
13 | - oraclejdk8
14 | script:
15 | - mvn clean install sonar:sonar
16 | cache:
17 | directories:
18 | - "$HOME/.m2/repository"
19 | - "$HOME/.sonar/cache"
20 | env:
21 | global:
22 | secure: euv9zwF2OjgTWHBFmLUhxVWIlLcHALm8nNIz2a+MzBloB8f5bmtWSzik9JkyRoJJs3G9R/IT9nkdqi6Kw/7WtNTKhG+ZEDrnzWnHyJwhX7aaJCLJHDvoeC9Pv7h5JMotXQm8g1YOlUzAcs2A/hEfdpUYdjEU43+RGQHniBnAvMeumkmtq9dYR5Ch3J1m/fC3wqvQQREeMw4XIpHb4X/Ih9VMnPcCmiBhMdHAYGrbNXcwONCgYRZbyDoQP5ndx9vrnJ4BV+Q/x5E13jC//PdgwsWtgSKvOP5LIEFI/xSg/hKTSue8f4jBny4FEZ7G6PjeU7urTvf1qo1GSpS7W2pLEdnGoMvi5XqhNpRVgbItVlKVqGoh8VdR9zQvaDYifuvtLclOLnw2Rlan5oVgRbUzJWT0r98BZkdEH8PiW/0qycgBY5T4mcoXGAYjdu7ZFWdsE9SINbWmoCzXJgSJ6lySQOtSDD0wS5X510flRrwHytBa/9de19IEkW0yxPBQDPrDvMB/SOrjlvLP5DBDK52KhXhIugL0I/yMLzaKzqqyUeLkifpVrfW8Sg3sYF1louSwL2gL3dC2jbwpHM2Yc3pyUa1Q0/rpo0+tFpbmSb9ig0zHFNqp1Ia5t+3y+qSwlpAV8GenFfr/km0tDnfjnH96fAKQ2W0JKfnqVaZoOpfxYCM=
23 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing to Golang SonarQube Plugin
2 |
3 | The following is a set of guidelines for contributing to Golang Plugin Sonarqube, which are hosted in the University Artois Organization on GitHub. These are just guidelines, not rules. Use your best judgment, and feel free to propose changes to this document in a pull request.
4 |
5 |
6 | #### Table Of Contents
7 | [What should I know before I get started?](#what-should-i-know-before-i-get-started)
8 |
9 | ## What should I know before I get started?
10 |
11 | ### Convention
12 |
13 | This project respect the [code convention of Java](http://www.oracle.com/technetwork/java/codeconvtoc-136057.html). So if you want contributing you must respect this convention.
14 |
15 | ## How Can I Contribute?
16 |
17 | ### Reporting Bugs
18 |
19 | This section guides you through submitting a bug report for Atom. Following these guidelines helps maintainers and the community understand your report :pencil:.
20 |
21 | Create an issue on that repository and provide the following information by filling in [the template](ISSUE_TEMPLATE.md).
22 |
23 |
24 | ### Add rule from new Linter
25 |
26 | Gometalinter use many linters. So if the plugin don't report the violation of a linter, you can add new violation without write any code.
27 |
28 | For a rule you have 3 files that you must modify.
29 |
30 | * [the xml file of violations](https://github.com/uartois/sonar-golang/blob/master/src/main/resources/rules/golint-rules.xml). This file define the rules. A rule is a xml tag, for exemple:
31 |
32 | ```xml
33 |
34 | AUniqueKey
35 | A name for the rule
36 | AUniqueKey
37 | A description: foo should be bar
38 | Additional information can be found at .... (an eventual link with more information)
39 |
40 | MINOR can be MAJOR, BLOCKER or CRITICAL
41 | SINGLE
42 | READY
43 | CODE_SMELL can be Vulnerability, Bug
44 | bad-practice
45 | comments
46 | CONSTANT_ISSUE
47 | 10min
48 |
49 | More information here https://docs.sonarqube.org/display/DEV/Coding+Rule+Guidelines
50 | ```
51 | * [the key properties](https://github.com/uartois/sonar-golang/blob/master/src/main/resources/key.properties) This file define a pattern that can be match with the description and define a link between the issue in the gometalinter report and the violation in the xml.
52 |
53 | * [the profile properties](https://github.com/uartois/sonar-golang/blob/master/src/main/resources/profile.properties) This file associate the key of the rule with a boolean. If it's true the rule is activated by default.
54 |
--------------------------------------------------------------------------------
/ISSUE_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | ### Description
2 |
3 | [Description of the issue]
4 |
5 | ### Steps to Reproduce
6 |
7 | 1. [First Step]
8 | 2. [Second Step]
9 | 3. [and so on...]
10 |
11 | ### Content of your sonar-project.properties
12 |
13 | *It will help us to check how you configured the plugin.*
14 |
15 | ### Log of sonar-scanner related to the plugin
16 |
17 | *The plugin logs major events, including which report files have been found and analyzed.*
18 |
19 | ### Versions
20 |
21 | Versions of your sonar installation (server, sonar-scanner), gometalinter, go and OS.
22 |
23 | ### Additional Information
24 |
25 | Sample reports may be necessary to reproduce the issue. Please attach if possible reports files (report.xml, coverage.xml, test.xml) corresponding to the feature which is not working as expected.
26 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU LESSER GENERAL PUBLIC LICENSE
2 | Version 3, 29 June 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 |
9 | This version of the GNU Lesser General Public License incorporates
10 | the terms and conditions of version 3 of the GNU General Public
11 | License, supplemented by the additional permissions listed below.
12 |
13 | 0. Additional Definitions.
14 |
15 | As used herein, "this License" refers to version 3 of the GNU Lesser
16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU
17 | General Public License.
18 |
19 | "The Library" refers to a covered work governed by this License,
20 | other than an Application or a Combined Work as defined below.
21 |
22 | An "Application" is any work that makes use of an interface provided
23 | by the Library, but which is not otherwise based on the Library.
24 | Defining a subclass of a class defined by the Library is deemed a mode
25 | of using an interface provided by the Library.
26 |
27 | A "Combined Work" is a work produced by combining or linking an
28 | Application with the Library. The particular version of the Library
29 | with which the Combined Work was made is also called the "Linked
30 | Version".
31 |
32 | The "Minimal Corresponding Source" for a Combined Work means the
33 | Corresponding Source for the Combined Work, excluding any source code
34 | for portions of the Combined Work that, considered in isolation, are
35 | based on the Application, and not on the Linked Version.
36 |
37 | The "Corresponding Application Code" for a Combined Work means the
38 | object code and/or source code for the Application, including any data
39 | and utility programs needed for reproducing the Combined Work from the
40 | Application, but excluding the System Libraries of the Combined Work.
41 |
42 | 1. Exception to Section 3 of the GNU GPL.
43 |
44 | You may convey a covered work under sections 3 and 4 of this License
45 | without being bound by section 3 of the GNU GPL.
46 |
47 | 2. Conveying Modified Versions.
48 |
49 | If you modify a copy of the Library, and, in your modifications, a
50 | facility refers to a function or data to be supplied by an Application
51 | that uses the facility (other than as an argument passed when the
52 | facility is invoked), then you may convey a copy of the modified
53 | version:
54 |
55 | a) under this License, provided that you make a good faith effort to
56 | ensure that, in the event an Application does not supply the
57 | function or data, the facility still operates, and performs
58 | whatever part of its purpose remains meaningful, or
59 |
60 | b) under the GNU GPL, with none of the additional permissions of
61 | this License applicable to that copy.
62 |
63 | 3. Object Code Incorporating Material from Library Header Files.
64 |
65 | The object code form of an Application may incorporate material from
66 | a header file that is part of the Library. You may convey such object
67 | code under terms of your choice, provided that, if the incorporated
68 | material is not limited to numerical parameters, data structure
69 | layouts and accessors, or small macros, inline functions and templates
70 | (ten or fewer lines in length), you do both of the following:
71 |
72 | a) Give prominent notice with each copy of the object code that the
73 | Library is used in it and that the Library and its use are
74 | covered by this License.
75 |
76 | b) Accompany the object code with a copy of the GNU GPL and this license
77 | document.
78 |
79 | 4. Combined Works.
80 |
81 | You may convey a Combined Work under terms of your choice that,
82 | taken together, effectively do not restrict modification of the
83 | portions of the Library contained in the Combined Work and reverse
84 | engineering for debugging such modifications, if you also do each of
85 | the following:
86 |
87 | a) Give prominent notice with each copy of the Combined Work that
88 | the Library is used in it and that the Library and its use are
89 | covered by this License.
90 |
91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license
92 | document.
93 |
94 | c) For a Combined Work that displays copyright notices during
95 | execution, include the copyright notice for the Library among
96 | these notices, as well as a reference directing the user to the
97 | copies of the GNU GPL and this license document.
98 |
99 | d) Do one of the following:
100 |
101 | 0) Convey the Minimal Corresponding Source under the terms of this
102 | License, and the Corresponding Application Code in a form
103 | suitable for, and under terms that permit, the user to
104 | recombine or relink the Application with a modified version of
105 | the Linked Version to produce a modified Combined Work, in the
106 | manner specified by section 6 of the GNU GPL for conveying
107 | Corresponding Source.
108 |
109 | 1) Use a suitable shared library mechanism for linking with the
110 | Library. A suitable mechanism is one that (a) uses at run time
111 | a copy of the Library already present on the user's computer
112 | system, and (b) will operate properly with a modified version
113 | of the Library that is interface-compatible with the Linked
114 | Version.
115 |
116 | e) Provide Installation Information, but only if you would otherwise
117 | be required to provide such information under section 6 of the
118 | GNU GPL, and only to the extent that such information is
119 | necessary to install and execute a modified version of the
120 | Combined Work produced by recombining or relinking the
121 | Application with a modified version of the Linked Version. (If
122 | you use option 4d0, the Installation Information must accompany
123 | the Minimal Corresponding Source and Corresponding Application
124 | Code. If you use option 4d1, you must provide the Installation
125 | Information in the manner specified by section 6 of the GNU GPL
126 | for conveying Corresponding Source.)
127 |
128 | 5. Combined Libraries.
129 |
130 | You may place library facilities that are a work based on the
131 | Library side by side in a single library together with other library
132 | facilities that are not Applications and are not covered by this
133 | License, and convey such a combined library under terms of your
134 | choice, if you do both of the following:
135 |
136 | a) Accompany the combined library with a copy of the same work based
137 | on the Library, uncombined with any other library facilities,
138 | conveyed under the terms of this License.
139 |
140 | b) Give prominent notice with the combined library that part of it
141 | is a work based on the Library, and explaining where to find the
142 | accompanying uncombined form of the same work.
143 |
144 | 6. Revised Versions of the GNU Lesser General Public License.
145 |
146 | The Free Software Foundation may publish revised and/or new versions
147 | of the GNU Lesser General Public License from time to time. Such new
148 | versions will be similar in spirit to the present version, but may
149 | differ in detail to address new problems or concerns.
150 |
151 | Each version is given a distinguishing version number. If the
152 | Library as you received it specifies that a certain numbered version
153 | of the GNU Lesser General Public License "or any later version"
154 | applies to it, you have the option of following the terms and
155 | conditions either of that published version or of any later version
156 | published by the Free Software Foundation. If the Library as you
157 | received it does not specify a version number of the GNU Lesser
158 | General Public License, you may choose any version of the GNU Lesser
159 | General Public License ever published by the Free Software Foundation.
160 |
161 | If the Library as you received it specifies that a proxy can decide
162 | whether future versions of the GNU Lesser General Public License shall
163 | apply, that proxy's public statement of acceptance of any version is
164 | permanent authorization for you to choose that version for the
165 | Library.
166 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Community SonarQube Plugin for the Go language
2 |
3 | [](https://travis-ci.org/uartois/sonar-golang) 
4 |
5 | 
6 |
7 | **This is a community plugin for SonarQube to support the Go language started in April 2017 at Artois University.
8 | Since May 2018, Go is officially supported by SonarSource with [SonarGo](https://github.com/SonarSource/sonar-go).**
9 |
10 | It integrates [GoMetaLinter](https://github.com/alecthomas/gometalinter) reports
11 | within SonarQube dashboard.
12 |
13 | The user must generate a GoMetaLinter report for the code using the checkstyle
14 | format. The report is thus integrated to SonarQube using
15 | [sonar-scanner](https://docs.sonarqube.org/display/SCAN/Analyzing+with+SonarQube+Scanner).
16 |
17 | Release 1.0 only provides golint support. Release 1.1 provides test coverage support. Upcoming releases will bring support
18 | for additional linters.
19 |
20 |
21 | # Authors
22 |
23 | + Thibault Falque
24 | + Daniel Le Berre
25 |
26 |
27 | # Installation
28 |
29 | * Download the latest version of the artifact
30 | * Stop sonarqube server
31 | * Put the jar file in `$SONAR_PATH/extensions/plugins`
32 | * Start sonarqube server
33 |
34 | # Enabling all latest rules
35 |
36 | If you have already installed the plugin and you want to enable the new rules provided by
37 | the new version of the plugin, follow those steps after the installation:
38 |
39 | * Go on the Quality Profiles page
40 | * Click on the arrow near the "Create" button
41 | * Click on "Restore Built-In Profiles"
42 | * Choose the language (Go)
43 | * Click on "Restore"
44 |
45 |
46 | # Using the plugin
47 |
48 | * create a `sonar-project.properties` file.
49 |
50 | ```
51 | sonar.projectKey=yourprojectid
52 | sonar.projectName=name of project
53 | sonar.projectVersion=1.0
54 | # GoLint report path, default value is report.xml
55 | sonar.golint.reportPath=report.xml
56 | # Cobertura like coverage report path, default value is coverage.xml
57 | sonar.coverage.reportPath=coverage.xml
58 | # if you want disabled the DTD verification for a proxy problem for example, true by default
59 | sonar.coverage.dtdVerification=false
60 | # JUnit like test report, default value is test.xml
61 | sonar.test.reportPath=test.xml
62 | sonar.sources=./
63 | sonar.tests=./
64 | sonar.test.inclusions=**/**_test.go
65 | sonar.sources.inclusions=**/**.go
66 | ```
67 |
68 | * start the analysis
69 | ```shell
70 | sonar-scanner
71 | ```
72 |
73 | It is assumed that you have the sonar scanner executable on your path and
74 | to run it at the root of your go project.
75 |
76 | # GoMetaLinter support
77 |
78 | * install [gometalinter](https://github.com/alecthomas/gometalinter)
79 | ```shell
80 | go get -u gopkg.in/alecthomas/gometalinter.v1
81 | gometalinter.v1 --install
82 | ```
83 |
84 | * Generate a gometalinter report using the checkstyle format:
85 | ```shell
86 | gometalinter.v1 --checkstyle > report.xml
87 | ```
88 |
89 | # Coverage (since release 1.1)
90 |
91 | For coverage metrics you must have one or multiple `coverage.xml` (cobertura xml format) files.
92 |
93 | * First install the tools for converting a coverprofile in cobertura file:
94 | ```shell
95 | go get github.com/axw/gocov/...
96 | go get github.com/AlekSi/gocov-xml
97 | ```
98 |
99 | * Then from the root of your project:
100 | ```shell
101 | gocov test ./... | gocov-xml > coverage.xml
102 | ```
103 |
104 | Note that `gocov test ./...` internally calls `go test` with the `-coverprofile` flag for
105 | all folders and subfolders, and assembles the coverprofile accordingly by itself (this is
106 | necessary, as Golang [up to 1.9](https://tip.golang.org/doc/go1.10#test) does not support the
107 | combination `go test ./... -coverprofile=...`).
108 |
109 | If you want to invoke `go test` manually, you need to do this and the conversion for each
110 | package by yourself. For example:
111 |
112 | * For all packages execute those commands:
113 | ```shell
114 | go test -coverprofile=cover.out
115 | gocov convert cover.out | gocov-xml > coverage.xml
116 | ```
117 |
118 | You then end-up with one coverage file per directory:
119 | ```
120 | pkg1/coverage.xml
121 | pkg2/coverage.xml
122 | pkg3/coverage.xml
123 | ...
124 | ```
125 |
126 |
127 | This is an example of script for create all coverage files for all packages in one time.
128 |
129 |
130 | ```bash
131 | for D in `find . -type d`
132 | do
133 | echo $D
134 | if [[ $D == ./.git/* ]]; then
135 | continue
136 | elif [[ $D == .. ]]; then
137 | continue
138 | elif [[ $D == . ]]; then
139 | continue
140 | fi
141 |
142 | cd $D
143 | go test -coverprofile=cover.out
144 | gocov convert cover.out | gocov-xml > coverage.xml
145 | cd ..
146 | done
147 | ```
148 | or
149 |
150 | ```bash
151 | go list -f '{{if len .TestGoFiles}}"go test -coverprofile={{.Dir}}/cover.out {{.ImportPath}}"{{end}}' ./... | xargs -L 1 sh -c
152 | go list -f '{{if len .TestGoFiles}}"gocov convert {{.Dir}}/cover.out | gocov-xml > {{.Dir}}/coverage.xml"{{end}}' ./... | xargs -L 1 sh -c
153 | ```
154 |
155 | > Note for docker users: by default, `gocov-xml` uses absolute paths which prevents this plugin to use
156 | > coverage files built on a different file system than the one used to run the plugin.
157 | > A workaround is to use a [patched version of gocov](https://github.com/Centny/gocov-xml.git) which provides
158 | > the `-pwd` option to use relative paths instead of absolute paths. See [#35](https://github.com/uartois/sonar-golang/issues/35) for details.
159 |
160 | # Tests (since release 1.1)
161 |
162 | For test metrics you must generate a junit report file.
163 |
164 | * install the tools:
165 | ```shell
166 | go get -u github.com/jstemmer/go-junit-report
167 | ```
168 |
169 | * run the tests from the root of your project:
170 | ```shell
171 | go test -v ./... | go-junit-report > test.xml
172 | ```
173 |
--------------------------------------------------------------------------------
/logo.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uartois/sonar-golang/c57c5baba1b546642bfdf56d6be8d4ef06edcbf8/logo.jpeg
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
13 |
14 |
16 | 4.0.0
17 | fr.univartois
18 |
20 | sonar-golang-plugin
21 | 1.2.11
22 |
23 | Golang
24 | Golang Plugin for SonarQube: Golang, Golint
25 |
26 | University of Artois
27 | http://www.univ-artois.fr/
28 |
29 | https://github.com/uartois/sonar-golang
30 |
31 | https://github.com/uartois/sonar-golang/issues
32 |
33 |
34 |
35 | GNU LGPL 3.0
36 | https://www.gnu.org/licenses/lgpl-3.0.en.html
37 | manual
38 |
39 |
40 |
41 |
42 | sonar-plugin
43 |
44 |
45 | 1.8
46 | 1.8
47 | https://sonarqube.com
48 | ${maven.compiler.source}
49 |
50 |
51 |
52 |
53 | junit
54 | junit
55 | 4.12
56 | test
57 |
58 |
59 |
60 | org.sonarsource.sonarqube
61 | sonar-plugin-api
62 |
64 | 6.0
65 |
66 | provided
67 |
68 |
69 |
70 |
71 |
72 | org.apache.commons
73 | commons-lang3
74 | 3.5
75 |
76 |
77 |
78 |
79 |
80 | org.mockito
81 | mockito-all
82 | 1.10.19
83 |
84 |
85 |
86 | org.mockito
87 | mockito-core
88 | 2.7.22
89 |
90 |
91 |
92 | org.jbehave
93 | jbehave-core
94 | 4.1
95 |
96 |
97 |
98 | de.codecentric
99 | jbehave-junit-runner
100 | 1.2.0
101 |
102 |
103 |
104 |
105 | org.sonarsource.sslr
106 | sslr-core
107 | 1.21
108 |
109 |
110 |
111 | org.sonarsource.sslr
112 | sslr-toolkit
113 | 1.21
114 |
115 |
116 |
117 | org.sonarsource.sslr
118 | sslr-testing-harness
119 | 1.21
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 | org.sonarsource.sonar-packaging-maven-plugin
131 | sonar-packaging-maven-plugin
132 | 1.17
133 | true
134 |
135 |
136 | fr.univartois.sonargo.SonarGoPlugin
137 | Sonarqube Plugin for Golang
138 |
140 | true
141 |
142 |
143 |
144 |
145 |
146 | org.apache.maven.plugins
147 | maven-surefire-plugin
148 | 2.19.1
149 |
150 | true
151 | false
152 |
153 | **/*Test*
154 |
155 |
156 | **/GoGrammarTest.java
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 | org.jacoco
168 | jacoco-maven-plugin
169 | 0.7.9
170 |
171 |
172 |
173 | process-test-classes
174 |
175 | prepare-agent
176 |
177 |
178 | ${basedir}/target/jacoco.exec
179 |
180 |
181 |
182 |
183 |
184 | org.jbehave
185 | jbehave-maven-plugin
186 |
187 |
188 | run-stories-as-embeddables
189 | integration-test
190 |
191 | run-stories-as-embeddables
192 |
193 |
194 | test
195 |
196 | **/*Scenarios.java
197 |
198 | true
199 | false
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 | org.jacoco
212 | jacoco-maven-plugin
213 |
214 |
215 |
216 | report
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
--------------------------------------------------------------------------------
/src/main/java/fr/univartois/sonargo/SonarGoPlugin.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright 2017 - Université d'Artois
3 | *
4 | * This file is part of SonarQube Golang plugin (sonar-golang).
5 | *
6 | * Sonar-golang is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU Lesser General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * Sonar-golang is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with Sonar-golang. If not, see .
18 | *
19 | * Contributors:
20 | * Thibault Falque (thibault_falque@ens.univ-artois.fr)
21 | *******************************************************************************/
22 | package fr.univartois.sonargo;
23 |
24 | import org.sonar.api.Plugin;
25 |
26 | import fr.univartois.sonargo.core.language.GoLanguage;
27 | import fr.univartois.sonargo.core.language.GoQualityProfile;
28 | import fr.univartois.sonargo.core.metrics.GoMetricSensor;
29 | import fr.univartois.sonargo.core.rules.GoLintIssueLoaderSensor;
30 | import fr.univartois.sonargo.core.rules.GoLintRulesDefinition;
31 | import fr.univartois.sonargo.core.settings.GoProperties;
32 | import fr.univartois.sonargo.coverage.CoverageSensor;
33 | import fr.univartois.sonargo.gotest.GoTestSensor;
34 | import fr.univartois.sonargo.highlighter.HighlighterSensor;
35 |
36 | /**
37 | * This class is the entry point of the plugin
38 | *
39 | *
40 | *
41 | * @author thibault
42 | *
43 | */
44 | public class SonarGoPlugin implements Plugin {
45 |
46 | @Override
47 | public void define(Context context) {
48 | context.addExtensions(GoProperties.getProperties());
49 | context.addExtensions(GoLanguage.class, GoQualityProfile.class);
50 | context.addExtensions(GoLintRulesDefinition.class, GoLintIssueLoaderSensor.class);
51 | context.addExtension(CoverageSensor.class);
52 | context.addExtension(GoTestSensor.class);
53 | context.addExtension(HighlighterSensor.class);
54 | context.addExtension(GoMetricSensor.class);
55 |
56 | }
57 |
58 | }
59 |
--------------------------------------------------------------------------------
/src/main/java/fr/univartois/sonargo/core/Parser.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright 2017 - Université d'Artois
3 | *
4 | * This file is part of SonarQube Golang plugin (sonar-golang).
5 | *
6 | * Sonar-golang is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU Lesser General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * Sonar-golang is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with Sonar-golang. If not, see .
18 | *
19 | * Contributors:
20 | * Thibault Falque (thibault_falque@ens.univ-artois.fr)
21 | *******************************************************************************/
22 | package fr.univartois.sonargo.core;
23 |
24 | import java.io.IOException;
25 |
26 | import javax.xml.parsers.ParserConfigurationException;
27 |
28 | import org.xml.sax.SAXException;
29 |
30 | public interface Parser {
31 | public void parse(String reportPath) throws ParserConfigurationException, SAXException, IOException;
32 | }
33 |
--------------------------------------------------------------------------------
/src/main/java/fr/univartois/sonargo/core/ProjectExplorer.java:
--------------------------------------------------------------------------------
1 | package fr.univartois.sonargo.core;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | import org.sonar.api.batch.fs.FilePredicates;
7 | import org.sonar.api.batch.fs.FileSystem;
8 | import org.sonar.api.batch.fs.InputFile;
9 | import org.sonar.api.batch.sensor.SensorContext;
10 |
11 | import fr.univartois.sonargo.core.language.GoLanguage;
12 |
13 | public class ProjectExplorer {
14 |
15 | private ProjectExplorer() {
16 | // prevent the instantiation
17 | }
18 |
19 | public static List searchByType(final SensorContext context, final InputFile.Type type) {
20 | FileSystem system = context.fileSystem();
21 | FilePredicates predicate = system.predicates();
22 | Iterable iter = system
23 | .inputFiles(predicate.and(predicate.hasLanguage(GoLanguage.KEY), predicate.hasType(type)));
24 |
25 | final List listFiles = new ArrayList<>();
26 | iter.forEach(listFiles::add);
27 | return listFiles;
28 | }
29 |
30 | public static List searchFileWithTypeMainOrTest(final SensorContext context) {
31 | FilePredicates predicate = context.fileSystem().predicates();
32 | Iterable iter = context.fileSystem().inputFiles(predicate.and(predicate.hasLanguage(GoLanguage.KEY),
33 | predicate.or(predicate.hasType(InputFile.Type.MAIN), predicate.hasType(InputFile.Type.TEST))));
34 |
35 | final List listFiles = new ArrayList<>();
36 | iter.forEach(listFiles::add);
37 | return listFiles;
38 | }
39 |
40 | public static InputFile getByPath(final SensorContext context, final String filePath) {
41 | final FileSystem fileSystem = context.fileSystem();
42 | final FilePredicates predicates = fileSystem.predicates();
43 | return fileSystem.inputFile(predicates.hasPath(filePath));
44 |
45 | }
46 |
47 | }
48 |
--------------------------------------------------------------------------------
/src/main/java/fr/univartois/sonargo/core/language/GoLanguage.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright 2017 - Université d'Artois
3 | *
4 | * This file is part of SonarQube Golang plugin (sonar-golang).
5 | *
6 | * Sonar-golang is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU Lesser General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * Sonar-golang is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with Sonar-golang. If not, see .
18 | *
19 | * Contributors:
20 | * Thibault Falque (thibault_falque@ens.univ-artois.fr)
21 | *******************************************************************************/
22 | package fr.univartois.sonargo.core.language;
23 |
24 | import org.apache.commons.lang3.StringUtils;
25 | import org.sonar.api.resources.AbstractLanguage;
26 |
27 | /**
28 | * This class defines the Golang language
29 | *
30 | * @author thibault
31 | *
32 | */
33 | public class GoLanguage extends AbstractLanguage {
34 |
35 | public static final String NAME = "GO";
36 | public static final String KEY = "go";
37 |
38 | private static final String[] DEFAULT_FILE_SUFFIXES = { "go" };
39 |
40 | /**
41 | * Create the GoLangage
42 | */
43 | public GoLanguage() {
44 | super(KEY, NAME);
45 | }
46 |
47 | /**
48 | * {@inheritDoc}}
49 | */
50 | @Override
51 | public String[] getFileSuffixes() {
52 | return DEFAULT_FILE_SUFFIXES;
53 | }
54 |
55 | /**
56 | * Allows to know if the given file name has a valid suffix
57 | *
58 | * @param filename
59 | * String representing the file name
60 | * @return boolean true
if the file name's suffix is known,
61 | * false
any other way
62 | */
63 | public boolean hasValidSuffixes(String filename) {
64 | for (String str : DEFAULT_FILE_SUFFIXES) {
65 | if (StringUtils.lowerCase(filename).endsWith("." + str)) {
66 | return true;
67 | }
68 | }
69 | return false;
70 | }
71 |
72 | }
73 |
--------------------------------------------------------------------------------
/src/main/java/fr/univartois/sonargo/core/language/GoLexer.java:
--------------------------------------------------------------------------------
1 | package fr.univartois.sonargo.core.language;
2 |
3 | import com.sonar.sslr.api.AstNode;
4 | import com.sonar.sslr.api.TokenType;
5 | import com.sonar.sslr.impl.Lexer;
6 | import com.sonar.sslr.impl.channel.BlackHoleChannel;
7 | import com.sonar.sslr.impl.channel.CommentRegexpChannel;
8 | import com.sonar.sslr.impl.channel.IdentifierAndKeywordChannel;
9 | import com.sonar.sslr.impl.channel.PunctuatorChannel;
10 | import com.sonar.sslr.impl.channel.RegexpChannel;
11 |
12 | public final class GoLexer {
13 |
14 | private static final String DECIMAL_DIGIT = "\\d";
15 | private static final String DECIMAL_LIT = "[1-9]" + DECIMAL_DIGIT + "*";
16 | private static final String HEXADECIMAL_LIT = "0(x|X)\\p{XDigit}(\\p{XDigit})*";
17 | private static final String OCTAL_DIGIT = "[0-7]";
18 | private static final String OCTAL_LIT = "0" + OCTAL_DIGIT + "*";
19 | private static final String FLOAT_SEPARATOR = "\\.";
20 | private static final String DECIMALS = DECIMAL_DIGIT + "+";
21 | private static final String EXPONENT = "[eE][+-]?+" + DECIMALS;
22 | private static final String FLOAT_LIT = "(" + DECIMALS + FLOAT_SEPARATOR + "(" + DECIMALS + ")*(" + EXPONENT
23 | + ")*)|(" + DECIMALS + EXPONENT + ")|(" + FLOAT_SEPARATOR + DECIMALS + "(" + EXPONENT + ")" + "?)";
24 |
25 | private static final String UNICODE_CHAR = "^\\u000A";
26 | private static final String NEWLINE = "\\u000A";
27 |
28 | private static final String INTERPRETED_STRING_LIT = "\"(\\p{L}|\\p{N}|\\p{Z}|\\p{Punct})*\"";
29 | private static final String RAW_STRING_LIT = "`" + UNICODE_CHAR + "|" + NEWLINE + "`";
30 | private static final String STRING_LIT = RAW_STRING_LIT + "|" + INTERPRETED_STRING_LIT;
31 |
32 | private GoLexer() {
33 | }
34 |
35 | public enum Literals implements TokenType {
36 |
37 | INTEGER(DECIMAL_LIT + "|" + HEXADECIMAL_LIT + "|" + OCTAL_LIT),
38 | FLOAT(FLOAT_LIT),
39 | STRING(STRING_LIT);
40 | private final String regexp;
41 |
42 | private Literals(String regexp) {
43 | this.regexp = regexp;
44 | }
45 |
46 | @Override
47 | public String getName() {
48 | return name();
49 | }
50 |
51 | @Override
52 | public String getValue() {
53 | return regexp;
54 | }
55 |
56 | @Override
57 | public boolean hasToBeSkippedFromAst(AstNode node) {
58 | return false;
59 | }
60 |
61 | }
62 |
63 | public enum Keyword implements TokenType {
64 | BREAK("break"),
65 | DEFAULT("default"),
66 | FUNC("func"),
67 | INTERFACE("interface"),
68 | SELECT("select"),
69 | CASE("case"),
70 | DEFER("defer"),
71 | GO("go"),
72 | MAP("map"),
73 | STRUCT("struct"),
74 | CHAN("chan"),
75 | ELSE("else"),
76 | GOTO("goto"),
77 | PACKAGE("package"),
78 | SWITCH("switch"),
79 | CONST("const"),
80 | FALLTHROUGH("fallthrough"),
81 | IF("if"),
82 | RANGE("range"),
83 | TYPE("type"),
84 | CONTINUE("continue"),
85 | FOR("for"),
86 | IMPORT("import"),
87 | RETURN("return"),
88 | VAR("var"),
89 | UINT8("uint8"),
90 | UINT16("uint16"),
91 | UINT32("uint32"),
92 | UINT64("uint64"),
93 | INT("int"),
94 | INT8("int8"),
95 | INT16("int16"),
96 | INT32("int32"),
97 | INT64("int64"),
98 | FLOAT32("float32"),
99 | FLOAT64("float64"),
100 | COMPLEX64("complex64"),
101 | COMPLEX128("complex128"),
102 | BYTE("byte"),
103 | RUNE("rune"),
104 | BOOL("bool"),
105 | UINTPTR("uintptr"),
106 | STRING("string");
107 |
108 | private final String value;
109 |
110 | private Keyword(String value) {
111 | this.value = value;
112 | }
113 |
114 | @Override
115 | public String getName() {
116 | return name();
117 | }
118 |
119 | @Override
120 | public String getValue() {
121 | return value;
122 | }
123 |
124 | @Override
125 | public boolean hasToBeSkippedFromAst(AstNode arg0) {
126 | return false;
127 | }
128 |
129 | public static String[] keywordValues() {
130 | final Keyword[] keywordsEnum = Keyword.values();
131 | final String[] keywords = new String[keywordsEnum.length];
132 | for (int i = 0; i < keywords.length; i++) {
133 | keywords[i] = keywordsEnum[i].getValue();
134 | }
135 | return keywords;
136 | }
137 |
138 | }
139 |
140 | public static final String COMMENT_SYMBOL = "//";
141 |
142 | public enum Punctuators implements TokenType {
143 |
144 | PAREN_L("("),
145 | PAREN_R(")"),
146 | BRACE_L("{"),
147 | BRACE_R("}"),
148 | EQ("="),
149 | EQ2(":="),
150 | COMMA(","),
151 | SEMICOLON(";"),
152 | ADD("+"),
153 | SUB("-"),
154 | MUL("*"),
155 | DIV("/"),
156 | EQEQ("=="),
157 | NE("!="),
158 | LT("<"),
159 | LTE("<="),
160 | GT(">"),
161 | GTE(">="),
162 | INC("++"),
163 | DEC("--"),
164 | DOT("."),
165 | OR("||"),
166 | AND("&&"),
167 | PERCENT("%"),
168 | LEFT_SHIFT("<<"),
169 | RIGHT_SHIFT(">>"),
170 | AND_BITBIT("&"),
171 | OR_BITBIT("|"),
172 | AND_NOT_BITBIT("&^"),
173 | XOR("&"),
174 | NOT("!"),
175 | LEFT("<-"),
176 | SQUARE_BRACKET_LEFT("]"),
177 | SQUARE_BRACKET_RIGHT("["),
178 | COLON(":"),
179 | DOT3("...");
180 |
181 | private final String value;
182 |
183 | private Punctuators(String value) {
184 | this.value = value;
185 | }
186 |
187 | @Override
188 | public String getName() {
189 | return name();
190 | }
191 |
192 | @Override
193 | public String getValue() {
194 | return value;
195 | }
196 |
197 | @Override
198 | public boolean hasToBeSkippedFromAst(AstNode node) {
199 | return false;
200 | }
201 |
202 | }
203 |
204 | public static Lexer create() {
205 | return Lexer.builder().withFailIfNoChannelToConsumeOneCharacter(false)
206 | .withChannel(new IdentifierAndKeywordChannel("\\p{L}(\\p{L}|\\p{N}|_)*", true, Keyword.values()))
207 | .withChannel(new RegexpChannel(Literals.FLOAT, Literals.FLOAT.regexp))
208 | .withChannel(new RegexpChannel(Literals.INTEGER, Literals.INTEGER.regexp))
209 | .withChannel(new RegexpChannel(Literals.STRING, Literals.STRING.regexp))
210 | .withChannel(new CommentRegexpChannel("^//.*")).withChannel(new PunctuatorChannel(Punctuators.values()))
211 | .withChannel(new BlackHoleChannel("[ \t\r\n]+")).build();
212 | }
213 |
214 | }
215 |
--------------------------------------------------------------------------------
/src/main/java/fr/univartois/sonargo/core/language/GoParser.java:
--------------------------------------------------------------------------------
1 | package fr.univartois.sonargo.core.language;
2 |
3 | import java.io.File;
4 |
5 | import org.apache.commons.io.FileUtils;
6 |
7 | import com.sonar.sslr.api.AstNode;
8 | import com.sonar.sslr.api.Grammar;
9 | import com.sonar.sslr.impl.Parser;
10 |
11 | public final class GoParser {
12 |
13 | private static final Parser P = GoParser.create();
14 |
15 | private GoParser() {
16 | }
17 |
18 | public static Parser create() {
19 | return Parser.builder(GoGrammar.create()).withLexer(GoLexer.create()).build();
20 | }
21 |
22 | public static AstNode parseFile(String filePath) {
23 | final File file = FileUtils.toFile(GoParser.class.getResource(filePath));
24 | if (file == null || !file.exists()) {
25 | throw new AssertionError("The file \"" + filePath + "\" does not exist.");
26 | }
27 |
28 | return P.parse(file);
29 | }
30 |
31 | public static AstNode parseString(String source) {
32 | return P.parse(source);
33 | }
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/src/main/java/fr/univartois/sonargo/core/language/GoQualityProfile.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright 2017 - Université d'Artois
3 | *
4 | * This file is part of SonarQube Golang plugin (sonar-golang).
5 | *
6 | * Sonar-golang is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU Lesser General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * Sonar-golang is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with Sonar-golang. If not, see .
18 | *
19 | * Contributors:
20 | * Thibault Falque (thibault_falque@ens.univ-artois.fr)
21 | *******************************************************************************/
22 | package fr.univartois.sonargo.core.language;
23 |
24 | import static fr.univartois.sonargo.core.rules.GoLintRulesDefinition.REPO_KEY;
25 | import static fr.univartois.sonargo.core.rules.GoLintRulesDefinition.REPO_NAME;
26 |
27 | import java.io.IOException;
28 | import java.util.Map.Entry;
29 | import java.util.Properties;
30 |
31 | import org.sonar.api.profiles.ProfileDefinition;
32 | import org.sonar.api.profiles.RulesProfile;
33 | import org.sonar.api.rules.Rule;
34 | import org.sonar.api.utils.ValidationMessages;
35 | import org.sonar.api.utils.log.Logger;
36 | import org.sonar.api.utils.log.Loggers;
37 |
38 | import fr.univartois.sonargo.core.rules.GoLintRulesDefinition;
39 |
40 | /**
41 | * The class define all rules that will detect by the sensor, it's not the same
42 | * of {@link GoLintRulesDefinition}
43 | *
44 | * @author thibault
45 | *
46 | */
47 | public final class GoQualityProfile extends ProfileDefinition {
48 | private static final Logger LOGGER = Loggers.get(GoQualityProfile.class);
49 | public static final String PROFILE_PATH = "/profile.properties";
50 |
51 | /**
52 | * {@inheritDoc}
53 | */
54 | @Override
55 | public RulesProfile createProfile(ValidationMessages validation) {
56 |
57 | LOGGER.info("GoMetaLinter Quality profile");
58 | RulesProfile profile = RulesProfile.create("Golint Rules", GoLanguage.KEY);
59 | profile.setDefaultProfile(Boolean.TRUE);
60 |
61 | Properties prop = new Properties();
62 |
63 | try {
64 | prop.load(GoQualityProfile.class.getResourceAsStream(GoQualityProfile.PROFILE_PATH));
65 |
66 | for (Entry e : prop.entrySet()) {
67 | if (Boolean.TRUE.equals(Boolean.valueOf((String) e.getValue()))) {
68 | profile.activateRule(Rule.create(REPO_KEY, (String) e.getKey(), REPO_NAME), null);
69 | }
70 | }
71 |
72 | } catch (IOException e) {
73 | LOGGER.error((new StringBuilder()).append("Unable to load ").append(PROFILE_PATH).toString(), e);
74 | }
75 |
76 | LOGGER.debug((new StringBuilder()).append("Profil generate: ").append(profile.getActiveRules()).toString());
77 |
78 | return profile;
79 | }
80 |
81 | }
82 |
--------------------------------------------------------------------------------
/src/main/java/fr/univartois/sonargo/core/metrics/GoLineMetrics.java:
--------------------------------------------------------------------------------
1 | package fr.univartois.sonargo.core.metrics;
2 |
3 | import java.io.BufferedReader;
4 | import java.io.File;
5 | import java.io.FileInputStream;
6 | import java.io.IOException;
7 | import java.io.InputStreamReader;
8 | import java.nio.charset.StandardCharsets;
9 |
10 | import org.sonar.api.batch.fs.InputFile;
11 | import org.sonar.api.utils.log.Logger;
12 | import org.sonar.api.utils.log.Loggers;
13 |
14 | public class GoLineMetrics {
15 | private static final Logger LOGGER = Loggers.get(GoLineMetrics.class);
16 |
17 | private int numberLineOfCode = 0;
18 | private int numberLineComment = 0;
19 | private final InputFile file;
20 |
21 | public GoLineMetrics(InputFile f) {
22 | file = f;
23 | }
24 |
25 | public void analyseFile() {
26 |
27 | final File f = file.file();
28 |
29 | try (final BufferedReader br = new BufferedReader(
30 | new InputStreamReader(new FileInputStream(f), StandardCharsets.UTF_8))) {
31 |
32 | String line;
33 | while ((line = br.readLine()) != null) {
34 | if (!line.startsWith("//")) {
35 | numberLineOfCode++;
36 | } else {
37 | numberLineComment++;
38 | }
39 | }
40 | } catch (final IOException e) {
41 | LOGGER.error("IO Exception", e);
42 | }
43 | }
44 |
45 | public int getNumberLineOfCode() {
46 | return numberLineOfCode;
47 | }
48 |
49 | public int getNumberLineComment() {
50 | return numberLineComment;
51 | }
52 |
53 | }
54 |
--------------------------------------------------------------------------------
/src/main/java/fr/univartois/sonargo/core/metrics/GoMetricSensor.java:
--------------------------------------------------------------------------------
1 | package fr.univartois.sonargo.core.metrics;
2 |
3 | import java.io.IOException;
4 | import java.nio.file.Files;
5 | import java.nio.file.Path;
6 | import java.nio.file.Paths;
7 | import java.util.HashMap;
8 | import java.util.Map;
9 | import java.util.stream.Stream;
10 |
11 | import org.sonar.api.batch.fs.FilePredicates;
12 | import org.sonar.api.batch.fs.FileSystem;
13 | import org.sonar.api.batch.fs.InputFile;
14 | import org.sonar.api.batch.fs.InputFile.Type;
15 | import org.sonar.api.batch.sensor.Sensor;
16 | import org.sonar.api.batch.sensor.SensorContext;
17 | import org.sonar.api.batch.sensor.SensorDescriptor;
18 | import org.sonar.api.measures.CoreMetrics;
19 | import org.sonar.api.measures.Metric;
20 |
21 | import fr.univartois.sonargo.core.language.GoLanguage;
22 |
23 | public class GoMetricSensor implements Sensor {
24 | private Map, Integer> measures;
25 |
26 | public GoMetricSensor() {
27 | measures = new HashMap<>();
28 | }
29 |
30 | public Stream createStream(SensorContext context) throws IOException {
31 | return Files.walk(Paths.get(context.fileSystem().baseDir().getPath()))
32 | .filter(p -> !p.getFileName().toString().endsWith(".go"));
33 | }
34 |
35 | @Override
36 | public void describe(SensorDescriptor descriptor) {
37 | descriptor.name("Go Metrics Sensor");
38 |
39 | }
40 |
41 | @Override
42 | public void execute(SensorContext context) {
43 | final FileSystem fileSystem = context.fileSystem();
44 | final FilePredicates predicates = fileSystem.predicates();
45 | final Iterable files = fileSystem
46 | .inputFiles(predicates.and(predicates.hasLanguage(GoLanguage.KEY), predicates.hasType(Type.MAIN)));
47 | files.forEach(i -> {
48 | final GoLineMetrics goline = new GoLineMetrics(i);
49 | goline.analyseFile();
50 | saveMetrics(context, i, CoreMetrics.NCLOC, goline.getNumberLineOfCode());
51 | saveMetrics(context, i, CoreMetrics.COMMENT_LINES, goline.getNumberLineComment());
52 | });
53 | }
54 |
55 | public void saveMetrics(SensorContext context, InputFile inputFile, Metric metric, Integer value) {
56 | context.newMeasure().withValue(value).forMetric(metric).on(inputFile).save();
57 | measures.put(metric, value);
58 | }
59 |
60 | public Map, Integer> getMeasures() {
61 | return measures;
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/src/main/java/fr/univartois/sonargo/core/rules/GoError.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright 2017 - Université d'Artois
3 | *
4 | * This file is part of SonarQube Golang plugin (sonar-golang).
5 | *
6 | * Sonar-golang is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU Lesser General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * Sonar-golang is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with Sonar-golang. If not, see .
18 | *
19 | * Contributors:
20 | * Thibault Falque (thibault_falque@ens.univ-artois.fr)
21 | *******************************************************************************/
22 | package fr.univartois.sonargo.core.rules;
23 |
24 | /**
25 | * GoError Represents an Error from a gometalinter checkstyle report
26 | *
27 | * This is an example of gometalinter checkstyle report This class have a field
28 | * for all attribute of error tag except the attribute "source" {@code
29 | *
30 |
31 |
32 | *
35 | *
37 | *
40 | *
42 | *
44 | *
46 | *
48 | *
50 | * }
51 | *
52 | * @author thibault
53 | */
54 | public class GoError {
55 | private final int line;
56 | private final String message;
57 | private final String severity;
58 | private final String filePath;
59 |
60 | /**
61 | * Create a GoError
62 | *
63 | * @param line
64 | * The line where there is the problem
65 | * @param message
66 | * The message for the error
67 | * @param severity
68 | * The severity for the message, this is the severity by the
69 | * linter it's not directly the severity of SonarQube
70 | * @param filePath
71 | * The file where there is the error
72 | */
73 | public GoError(int line, String message, String severity, String filePath) {
74 | super();
75 | this.line = line;
76 | this.message = message;
77 | this.severity = severity;
78 | this.filePath = filePath;
79 | }
80 |
81 | /**
82 | * Get the line where there is the problem
83 | *
84 | * @return The line attribute
85 | */
86 | public int getLine() {
87 | return line;
88 | }
89 |
90 | /**
91 | * Get the message where there is the problem
92 | *
93 | * @return The message attribute
94 | */
95 | public String getMessage() {
96 | return message;
97 | }
98 |
99 | /**
100 | * Get the severity where there is the problem
101 | *
102 | * @return The severity attribute
103 | */
104 | public String getSeverity() {
105 | return severity;
106 | }
107 |
108 | /**
109 | * Get the filePath of file where there is the problem
110 | *
111 | * @return The filePath attribute
112 | */
113 | public String getFilePath() {
114 | return filePath;
115 | }
116 |
117 | @Override
118 | public int hashCode() {
119 | final int prime = 31;
120 | int result = 1;
121 | result = prime * result + ((filePath == null) ? 0 : filePath.hashCode());
122 | result = prime * result + line;
123 | result = prime * result + ((message == null) ? 0 : message.hashCode());
124 | return prime * result + ((severity == null) ? 0 : severity.hashCode());
125 |
126 | }
127 |
128 | @Override
129 | public boolean equals(Object obj) {
130 | if (this == obj)
131 | return true;
132 | if (obj == null)
133 | return false;
134 | if (getClass() != obj.getClass())
135 | return false;
136 | GoError other = (GoError) obj;
137 | if (filePath == null) {
138 | if (other.filePath != null)
139 | return false;
140 | } else if (!filePath.equals(other.filePath))
141 | return false;
142 | if (line != other.line)
143 | return false;
144 | if (message == null) {
145 | if (other.message != null)
146 | return false;
147 | } else if (!message.equals(other.message))
148 | return false;
149 | if (severity == null) {
150 | if (other.severity != null)
151 | return false;
152 | } else if (!severity.equals(other.severity))
153 | return false;
154 | return true;
155 | }
156 |
157 | @Override
158 | public String toString() {
159 | return "GoError [line=" + line + ", message=" + message + ", severity=" + severity + ", filePath=" + filePath
160 | + "]";
161 | }
162 |
163 | }
--------------------------------------------------------------------------------
/src/main/java/fr/univartois/sonargo/core/rules/GoKeyRule.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright 2017 - Université d'Artois
3 | *
4 | * This file is part of SonarQube Golang plugin (sonar-golang).
5 | *
6 | * Sonar-golang is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU Lesser General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * Sonar-golang is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with Sonar-golang. If not, see .
18 | *
19 | * Contributors:
20 | * Thibault Falque (thibault_falque@ens.univ-artois.fr)
21 | *******************************************************************************/
22 | package fr.univartois.sonargo.core.rules;
23 |
24 | import java.io.FileNotFoundException;
25 | import java.io.IOException;
26 | import java.io.InputStream;
27 | import java.util.Map.Entry;
28 | import java.util.Properties;
29 | import java.util.regex.Matcher;
30 | import java.util.regex.Pattern;
31 |
32 | import org.sonar.api.utils.log.Logger;
33 | import org.sonar.api.utils.log.Loggers;
34 |
35 | /**
36 | * This class load the file key.properties where there is a map that can
37 | * correspond lint a internal key with a Pattern for match with the message of
38 | * the report
39 | *
40 | * @author thibault
41 | *
42 | */
43 | public class GoKeyRule {
44 | public static final String PATH_FILE = "/key.properties";
45 | private static final Logger LOGGER = Loggers.get(GoKeyRule.class);
46 | private static Properties prop;
47 |
48 | private GoKeyRule() {
49 | throw new IllegalAccessError("Utility class");
50 | }
51 |
52 | /**
53 | * Allow to load the key.properties file where there is a map that can
54 | * correspond lint a internal key with a Pattern for match with the message
55 | * of the report
56 | */
57 | public static synchronized void init() {
58 | if (prop == null) {
59 | prop = new Properties();
60 | try {
61 | LOGGER.info("Load " + PATH_FILE);
62 |
63 | InputStream input = GoKeyRule.class.getResourceAsStream(PATH_FILE);
64 |
65 | if (input == null) {
66 | throw new FileNotFoundException(PATH_FILE);
67 | }
68 |
69 | prop.load(input);
70 |
71 | LOGGER.info("loaded " + prop.keySet().size());
72 | } catch (IOException e) {
73 | LOGGER.error("Unable to load the config file", e);
74 | }
75 | }
76 | }
77 |
78 | public static Properties getProp() {
79 | return prop;
80 | }
81 |
82 | /**
83 | * Allow to get the corresponding key of the message of the error
84 | *
85 | * @param error
86 | * @return
87 | */
88 | public static String getKeyFromError(GoError error) {
89 | Pattern pattern;
90 | Matcher matcher;
91 |
92 | for (Entry e : prop.entrySet()) {
93 |
94 | pattern = Pattern.compile((String) e.getValue());
95 | matcher = pattern.matcher(error.getMessage());
96 | if (!matcher.matches())
97 | continue;
98 | return (String) e.getKey();
99 | }
100 |
101 | LOGGER.debug("This description \"" + error.getMessage() + "\" is not usable");
102 | return null;
103 |
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/src/main/java/fr/univartois/sonargo/core/rules/GoLintRulesDefinition.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright 2017 - Université d'Artois
3 | *
4 | * This file is part of SonarQube Golang plugin (sonar-golang).
5 | *
6 | * Sonar-golang is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU Lesser General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * Sonar-golang is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with Sonar-golang. If not, see .
18 | *
19 | * Contributors:
20 | * Thibault Falque (thibault_falque@ens.univ-artois.fr)
21 | *******************************************************************************/
22 | package fr.univartois.sonargo.core.rules;
23 |
24 | import java.io.InputStream;
25 | import java.nio.charset.StandardCharsets;
26 |
27 | import org.sonar.api.server.rule.RulesDefinition;
28 | import org.sonar.api.server.rule.RulesDefinitionXmlLoader;
29 | import org.sonar.api.utils.log.Logger;
30 | import org.sonar.api.utils.log.Loggers;
31 |
32 | import fr.univartois.sonargo.core.language.GoLanguage;
33 |
34 | /**
35 | * This class read the "/rules/golint-rules.xml" file and create all the rule
36 | * than can detect by the Sensor
37 | *
38 | * @author thibault
39 | *
40 | */
41 | public class GoLintRulesDefinition implements RulesDefinition {
42 | private static final String PATH_TO_RULES_XML = "/rules/golint-rules.xml";
43 | private static final Logger LOGGER = Loggers.get(GoLintRulesDefinition.class);
44 | protected static final String KEY = "go";
45 | protected static final String NAME = "Go";
46 |
47 | public static final String REPO_KEY = GoLanguage.KEY + "-" + KEY;
48 | public static final String REPO_NAME = GoLanguage.KEY + "-" + NAME;
49 |
50 | protected String rulesDefinitionFilePath() {
51 | return PATH_TO_RULES_XML;
52 | }
53 |
54 | private void defineRulesForLanguage(Context context, String repositoryKey, String repositoryName,
55 | String languageKey) {
56 | NewRepository repository = context.createRepository(repositoryKey, languageKey).setName(repositoryName);
57 |
58 | LOGGER.debug("Repository " + repositoryName + " created with the key " + repositoryKey + " " + repository);
59 |
60 | InputStream rulesXml = this.getClass().getResourceAsStream(rulesDefinitionFilePath());
61 | if (rulesXml != null) {
62 | RulesDefinitionXmlLoader rulesLoader = new RulesDefinitionXmlLoader();
63 | rulesLoader.load(repository, rulesXml, StandardCharsets.UTF_8.name());
64 | } else {
65 | LOGGER.warn("Cannot load the rules file " + PATH_TO_RULES_XML);
66 | }
67 |
68 | repository.done();
69 |
70 | LOGGER.debug("Repository " + repositoryName + " done: " + repository.rules() + " " + repository.rules().size());
71 |
72 | }
73 |
74 | @Override
75 | public void define(Context context) {
76 | defineRulesForLanguage(context, REPO_KEY, REPO_NAME, GoLanguage.KEY);
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/src/main/java/fr/univartois/sonargo/core/settings/GoProperties.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright 2017 - Université d'Artois
3 | *
4 | * This file is part of SonarQube Golang plugin (sonar-golang).
5 | *
6 | * Sonar-golang is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU Lesser General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * Sonar-golang is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with Sonar-golang. If not, see .
18 | *
19 | * Contributors:
20 | * Thibault Falque (thibault_falque@ens.univ-artois.fr)
21 | *******************************************************************************/
22 | package fr.univartois.sonargo.core.settings;
23 |
24 | import static java.util.Arrays.asList;
25 |
26 | import java.util.List;
27 |
28 | import org.sonar.api.config.PropertyDefinition;
29 |
30 | public class GoProperties {
31 | public static final String REPORT_PATH_KEY = "sonar.golint.reportPath";
32 | public static final String REPORT_PATH_DEFAULT = "report.xml";
33 |
34 | public static final String COVERAGE_REPORT_PATH_KEY = "sonar.coverage.reportPath";
35 | public static final String COVERAGE_REPORT_PATH_DEFAULT = "coverage.xml";
36 |
37 | public static final String JUNIT_REPORT_PATH_KEY = "sonar.test.reportPath";
38 | public static final String JUNIT_REPORT_PATH_DEFAULT = "test.xml";
39 |
40 | public static final String DTD_VERIFICATION_KEY = "sonar.coverage.dtdVerification";
41 | public static final String DTD_VERIFICATION_DEFAULT = "true";
42 |
43 | public static final String HIGHLIGHTING_KEY = "sonar.highlighting";
44 | public static final String HIGHLIGHTING_DEFAULT = "true";
45 |
46 | private GoProperties() {
47 |
48 | }
49 |
50 | public static List getProperties() {
51 | return asList(
52 | PropertyDefinition.builder(REPORT_PATH_KEY).defaultValue(REPORT_PATH_DEFAULT).category("Go")
53 | .name("Report path of Golint").description("relative path for golint report").build(),
54 | PropertyDefinition.builder(COVERAGE_REPORT_PATH_KEY).defaultValue(COVERAGE_REPORT_PATH_DEFAULT)
55 | .category("Go").name("Report path of coverage report")
56 | .description("relative path for coverage report").build(),
57 | PropertyDefinition.builder(JUNIT_REPORT_PATH_KEY).defaultValue(JUNIT_REPORT_PATH_DEFAULT).category("Go")
58 | .name("Report path of JUnit report").description("relative path for JUnit report").build(),
59 | PropertyDefinition.builder(DTD_VERIFICATION_KEY).defaultValue(DTD_VERIFICATION_DEFAULT).category("Go")
60 | .name("Boolean for DTD verification")
61 | .description("false if you want disabled the DTD verification for coverage file").build(),
62 | PropertyDefinition.builder(HIGHLIGHTING_KEY).defaultValue(HIGHLIGHTING_DEFAULT).category("Go")
63 | .name("Boolean for highlighting verification")
64 | .description("false if you want disabled the highlighting").build());
65 |
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/src/main/java/fr/univartois/sonargo/coverage/CoverageParser.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright 2017 - Université d'Artois
3 | *
4 | * This file is part of SonarQube Golang plugin (sonar-golang).
5 | *
6 | * Sonar-golang is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU Lesser General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * Sonar-golang is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with Sonar-golang. If not, see .
18 | *
19 | * Contributors:
20 | * Thibault Falque (thibault_falque@ens.univ-artois.fr)
21 | *******************************************************************************/
22 | package fr.univartois.sonargo.coverage;
23 |
24 | import java.io.File;
25 | import java.io.IOException;
26 | import java.io.StringReader;
27 | import java.util.ArrayList;
28 | import java.util.HashMap;
29 | import java.util.List;
30 | import java.util.Map;
31 |
32 | import javax.xml.parsers.DocumentBuilder;
33 | import javax.xml.parsers.DocumentBuilderFactory;
34 | import javax.xml.parsers.ParserConfigurationException;
35 |
36 | import org.sonar.api.batch.sensor.SensorContext;
37 | import org.sonar.api.utils.log.Logger;
38 | import org.sonar.api.utils.log.Loggers;
39 | import org.w3c.dom.Document;
40 | import org.w3c.dom.Element;
41 | import org.w3c.dom.Node;
42 | import org.w3c.dom.NodeList;
43 | import org.xml.sax.InputSource;
44 | import org.xml.sax.SAXException;
45 |
46 | import fr.univartois.sonargo.core.Parser;
47 | import fr.univartois.sonargo.core.settings.GoProperties;
48 |
49 | public class CoverageParser implements Parser {
50 |
51 | private final Map> coverageByFile = new HashMap<>();
52 | private static final String FILE_NAME_ATTR = "filename";
53 | private static final String LINE_NUMBER_ATTR = "number";
54 | private static final String HITS_ATTR = "hits";
55 | private static final String METHOD_TAG = "method";
56 | private static final String CLASS_TAG = "class";
57 | private static final String LINE_TAG = "line";
58 | private static final Logger LOGGER = Loggers.get(CoverageParser.class);
59 |
60 | private final boolean checkDtd;
61 |
62 | public CoverageParser(SensorContext context) {
63 | checkDtd = context.settings().getBoolean(GoProperties.DTD_VERIFICATION_KEY);
64 | }
65 |
66 | private DocumentBuilder constructDocumentBuilder() throws ParserConfigurationException {
67 | final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
68 |
69 | final DocumentBuilder db = dbf.newDocumentBuilder();
70 |
71 | if (!checkDtd) {
72 | db.setEntityResolver((publicId, systemId) -> {
73 | if (systemId.contains("http://cobertura.sourceforge.net/xml/coverage-03.dtd")) {
74 | return new InputSource(new StringReader(""));
75 | } else {
76 | return null;
77 | }
78 | });
79 | }
80 |
81 | return db;
82 | }
83 |
84 | /**
85 | * {@link http://stackoverflow.com/questions/13786607/normalization-in-dom-parsing-with-java-how-does-it-work}
86 | *
87 | * @param reportPath
88 | * @throws ParserConfigurationException
89 | * @throws SAXException
90 | * @throws IOException
91 | */
92 | @Override
93 | public void parse(String reportPath) throws IOException, ParserConfigurationException {
94 | final DocumentBuilder db = constructDocumentBuilder();
95 | Document doc;
96 | try {
97 | doc = db.parse(new File(reportPath));
98 | doc.getDocumentElement().normalize();
99 |
100 | final NodeList classList = doc.getElementsByTagName(CLASS_TAG);
101 |
102 | for (int i = 0; i < classList.getLength(); i++) {
103 | final Node nNode = classList.item(i);
104 | if (nNode.getNodeType() == Node.ELEMENT_NODE) {
105 |
106 | final Element eElement = (Element) nNode;
107 | final String filepath = eElement.getAttribute(FILE_NAME_ATTR);
108 | LOGGER.debug("filepath from coverage file " + filepath);
109 | parseMethodTag(eElement.getElementsByTagName(METHOD_TAG), getListForFile(filepath));
110 | }
111 | }
112 |
113 | } catch (SAXException e) {
114 | LOGGER.error("A SAX error on file " + reportPath, e);
115 | }
116 |
117 | }
118 |
119 | public Map> getCoveragePerFile() {
120 | for (Map.Entry> entry : coverageByFile.entrySet()) {
121 | String fileName = entry.getKey();
122 | List list = entry.getValue();
123 | LOGGER.debug(list.size() + "line coverage for file " + fileName);
124 | }
125 | return coverageByFile;
126 | }
127 |
128 | private List getListForFile(String filepath) {
129 | return coverageByFile.computeIfAbsent(filepath, k -> new ArrayList<>());
130 | }
131 |
132 | private void parseMethodTag(NodeList methodsList, List listOfCoverage) {
133 | for (int j = 0; j < methodsList.getLength(); j++) {
134 | final Node nNode = methodsList.item(j);
135 | if (nNode.getNodeType() == Node.ELEMENT_NODE) {
136 | final Element eElement = (Element) nNode;
137 | parseLineTag(eElement.getElementsByTagName(LINE_TAG), listOfCoverage);
138 | }
139 | }
140 | }
141 |
142 | private void parseLineTag(NodeList lineList, List listOfCoverage) {
143 | for (int j = 0; j < lineList.getLength(); j++) {
144 | final Node nNode = lineList.item(j);
145 | if (nNode.getNodeType() == Node.ELEMENT_NODE) {
146 | final Element eElement = (Element) nNode;
147 | listOfCoverage.add(new LineCoverage(Integer.parseInt(eElement.getAttribute(LINE_NUMBER_ATTR)),
148 | Integer.parseInt(eElement.getAttribute(HITS_ATTR))));
149 | }
150 | }
151 | }
152 | }
153 |
--------------------------------------------------------------------------------
/src/main/java/fr/univartois/sonargo/coverage/CoverageSensor.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright 2017 - Université d'Artois
3 | *
4 | * This file is part of SonarQube Golang plugin (sonar-golang).
5 | *
6 | * Sonar-golang is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU Lesser General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * Sonar-golang is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with Sonar-golang. If not, see .
18 | *
19 | * Contributors:
20 | * Thibault Falque (thibault_falque@ens.univ-artois.fr)
21 | *******************************************************************************/
22 | package fr.univartois.sonargo.coverage;
23 |
24 | import java.io.File;
25 | import java.io.IOException;
26 | import java.nio.file.Files;
27 | import java.nio.file.Path;
28 | import java.nio.file.PathMatcher;
29 | import java.nio.file.Paths;
30 | import java.util.ArrayList;
31 | import java.util.Arrays;
32 | import java.util.HashSet;
33 | import java.util.List;
34 | import java.util.Map;
35 | import java.util.Set;
36 | import java.util.stream.Stream;
37 |
38 | import javax.xml.parsers.ParserConfigurationException;
39 |
40 | import org.sonar.api.CoreProperties;
41 | import org.sonar.api.batch.fs.InputFile;
42 | import org.sonar.api.batch.sensor.Sensor;
43 | import org.sonar.api.batch.sensor.SensorContext;
44 | import org.sonar.api.batch.sensor.SensorDescriptor;
45 | import org.sonar.api.batch.sensor.coverage.CoverageType;
46 | import org.sonar.api.batch.sensor.coverage.NewCoverage;
47 | import org.sonar.api.utils.log.Logger;
48 | import org.sonar.api.utils.log.Loggers;
49 |
50 | import fr.univartois.sonargo.core.ProjectExplorer;
51 | import fr.univartois.sonargo.core.language.GoLanguage;
52 | import fr.univartois.sonargo.core.settings.GoProperties;
53 |
54 | public class CoverageSensor implements Sensor {
55 |
56 | private static final Logger LOGGER = Loggers.get(CoverageSensor.class);
57 | private Set inputFileWithCoverage = new HashSet<>();
58 |
59 | @Override
60 | public void describe(SensorDescriptor descriptor) {
61 | descriptor.name("Go Coverage").onlyOnFileType(InputFile.Type.MAIN).onlyOnLanguage(GoLanguage.KEY);
62 | }
63 |
64 | private List getExcludedPath(SensorContext context) {
65 |
66 | String globalExcludedPath = context.settings().getString(CoreProperties.PROJECT_EXCLUSIONS_PROPERTY);
67 |
68 | if (globalExcludedPath == null) {
69 | return new ArrayList<>();
70 | }
71 |
72 | return Arrays.asList(globalExcludedPath.split(","));
73 | }
74 |
75 | public boolean isAnExcludedPath(Path candidatePath, SensorContext context) {
76 | List listExcludedPath = getExcludedPath(context);
77 |
78 | for (String s : listExcludedPath) {
79 | Path pathAbsolute = candidatePath.toAbsolutePath();
80 | Path pathBase = context.fileSystem().baseDir().toPath();
81 | Path pathRelative = pathBase.relativize(pathAbsolute);
82 | if (s.contains("*")) {
83 | PathMatcher pathMatcher = java.nio.file.FileSystems.getDefault().getPathMatcher("glob:" + s);
84 | if (pathMatcher.matches(pathRelative)) {
85 | return true;
86 | }
87 | }
88 |
89 | if ((candidatePath.isAbsolute() && candidatePath.endsWith(s))
90 | || (candidatePath.getFileName().toFile().getName().equals(s))) {
91 | return true;
92 | }
93 | }
94 | return false;
95 |
96 | }
97 |
98 | public Stream createStream(SensorContext context) throws IOException {
99 | final String fullPath = context.fileSystem().baseDir().getPath();
100 | LOGGER.info(fullPath);
101 | return Files.walk(Paths.get(fullPath))
102 | .filter(p -> !p.getParent().toString().equals(".git") && !p.getParent().toString().contains(".sonar")
103 | && !p.getParent().toString().contains(".scannerwork")
104 | && !p.getFileName().toString().startsWith(".") && !isAnExcludedPath(p, context));
105 |
106 | }
107 |
108 | @Override
109 | public void execute(SensorContext context) {
110 | try (Stream paths = createStream(context)) {
111 | paths.forEach(filePath -> {
112 |
113 | LOGGER.debug("Path in stream" + filePath.toFile().getAbsolutePath());
114 |
115 | if (filePath.toFile().isDirectory()) {
116 | final String reportPath = context.settings().getString(GoProperties.COVERAGE_REPORT_PATH_KEY);
117 | final File f = new File(filePath + File.separator + reportPath);
118 | if (f.exists()) {
119 | LOGGER.info("Analyse for " + f.getPath());
120 |
121 | final CoverageParser coverParser = new CoverageParser(context);
122 |
123 | try {
124 | coverParser.parse(f.getPath());
125 | save(context, coverParser.getCoveragePerFile());
126 | } catch (ParserConfigurationException | IOException e) {
127 | LOGGER.error("Exception: ", e);
128 | }
129 |
130 | } else {
131 | LOGGER.info("no coverage file in package " + f.getPath());
132 | }
133 | }
134 | });
135 |
136 | ProjectExplorer.searchByType(context, InputFile.Type.MAIN).stream()
137 | .filter(i -> !inputFileWithCoverage.contains(i)).forEach(i -> saveForAllLine(context, i));
138 |
139 | } catch (final IOException e) {
140 | LOGGER.error("IO Exception " + context.fileSystem().baseDir().getPath());
141 | }
142 | }
143 |
144 | public void saveForAllLine(final SensorContext context, final InputFile i) {
145 | final NewCoverage coverage = context.newCoverage().onFile(i);
146 | try (Stream fileLine = Files.lines(i.path())) {
147 | FactoryLine.init();
148 | LinePredicate.init();
149 | fileLine.map(FactoryLine::create).filter(LinePredicate::filterLine)
150 | .forEach(l -> coverage.lineHits(l.getLineNumber(), l.getHits()));
151 |
152 | coverage.ofType(CoverageType.UNIT);
153 | coverage.save();
154 | } catch (IOException e) {
155 | LOGGER.warn("IO Exception" + e);
156 | }
157 |
158 | }
159 |
160 | public void save(SensorContext context, Map> coveragePerFile) {
161 | for (Map.Entry> entry : coveragePerFile.entrySet()) {
162 | final String filePath = entry.getKey();
163 | final List lines = entry.getValue();
164 | final InputFile inputFile = ProjectExplorer.getByPath(context, filePath);
165 | inputFileWithCoverage.add(inputFile);
166 | if (inputFile == null) {
167 | LOGGER.warn("unable to create InputFile object: " + filePath);
168 | return;
169 | }
170 |
171 | final NewCoverage coverage = context.newCoverage().onFile(inputFile);
172 |
173 | for (final LineCoverage line : lines) {
174 | try {
175 | coverage.lineHits(line.getLineNumber(), line.getHits());
176 | } catch (final Exception ex) {
177 | LOGGER.error(ex.getMessage() + line);
178 | }
179 | }
180 | coverage.ofType(CoverageType.UNIT);
181 | coverage.save();
182 | }
183 | }
184 |
185 | }
186 |
--------------------------------------------------------------------------------
/src/main/java/fr/univartois/sonargo/coverage/FactoryLine.java:
--------------------------------------------------------------------------------
1 | package fr.univartois.sonargo.coverage;
2 |
3 | public class FactoryLine {
4 | private static int line = 1;
5 |
6 | private FactoryLine() {
7 | throw new IllegalStateException("Utility class");
8 | }
9 |
10 | public static void init() {
11 | line = 1;
12 | }
13 |
14 | public static LineCoverage create(String l) {
15 | return new LineCoverage(line++, 0, l);
16 | }
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/src/main/java/fr/univartois/sonargo/coverage/LineCoverage.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright 2017 - Université d'Artois
3 | *
4 | * This file is part of SonarQube Golang plugin (sonar-golang).
5 | *
6 | * Sonar-golang is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU Lesser General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * Sonar-golang is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with Sonar-golang. If not, see .
18 | *
19 | * Contributors:
20 | * Thibault Falque (thibault_falque@ens.univ-artois.fr)
21 | *******************************************************************************/
22 | package fr.univartois.sonargo.coverage;
23 |
24 | public class LineCoverage {
25 | private int lineNumber;
26 | private int hits;
27 | private String line;
28 |
29 | public LineCoverage(int lineNumber, int hits) {
30 | super();
31 | this.lineNumber = lineNumber;
32 | this.hits = hits;
33 | this.line = null;
34 | }
35 |
36 | public LineCoverage(int lineNumber, int hits, String line) {
37 | this(lineNumber, hits);
38 | this.line = line;
39 | }
40 |
41 | public int getLineNumber() {
42 | return lineNumber;
43 | }
44 |
45 | public int getHits() {
46 | return hits;
47 | }
48 |
49 | public String getLine() {
50 | return line;
51 | }
52 |
53 | @Override
54 | public String toString() {
55 | return "LineCoverage [lineNumber=" + lineNumber + ", hits=" + hits + "]";
56 | }
57 |
58 | }
59 |
--------------------------------------------------------------------------------
/src/main/java/fr/univartois/sonargo/coverage/LinePredicate.java:
--------------------------------------------------------------------------------
1 | package fr.univartois.sonargo.coverage;
2 |
3 | public class LinePredicate {
4 | private static boolean funcFound = false;
5 | private static boolean commentFound = false;
6 | private static boolean typeFound = false;
7 |
8 | private LinePredicate() {
9 | throw new IllegalStateException("Utility class");
10 | }
11 |
12 | public static void init() {
13 | funcFound = false;
14 | commentFound = false;
15 | typeFound = false;
16 | }
17 |
18 | public static boolean filterLine(LineCoverage l) {
19 | String s = l.getLine().trim();
20 | if (s.matches("^func.*")) {
21 | funcFound = true;
22 | return false;
23 | }
24 | if (s.matches("^//.*")) {
25 | return false;
26 | }
27 |
28 | if (s.matches("^/\\*.*")) {
29 | commentFound = true;
30 | return false;
31 | }
32 |
33 | if (s.matches("^\\*/.*")) {
34 | commentFound = false;
35 | return false;
36 | }
37 |
38 | if (s.matches("^type.*") || s.matches("^interface.*") || s.matches("^struct.*")) {
39 | typeFound = true;
40 | return false;
41 | }
42 |
43 | if (s.matches("}.*") && typeFound) {
44 | typeFound = true;
45 | return false;
46 | }
47 |
48 | return funcFound && !commentFound && !typeFound && !s.isEmpty() && !"}".equals(s) && !s.matches("^type.*")
49 | && !s.matches("^func.*") && !s.matches("^import.*") && !s.matches("^package.*");
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/main/java/fr/univartois/sonargo/gotest/FunctionFinder.java:
--------------------------------------------------------------------------------
1 | package fr.univartois.sonargo.gotest;
2 |
3 | import java.io.FileInputStream;
4 | import java.io.IOException;
5 | import java.nio.ByteBuffer;
6 | import java.nio.CharBuffer;
7 | import java.nio.channels.FileChannel;
8 | import java.nio.charset.Charset;
9 | import java.nio.file.Path;
10 | import java.util.ArrayList;
11 | import java.util.HashMap;
12 | import java.util.List;
13 | import java.util.Map;
14 | import java.util.regex.Matcher;
15 | import java.util.regex.Pattern;
16 |
17 | import org.sonar.api.batch.fs.InputFile;
18 | import org.sonar.api.batch.sensor.SensorContext;
19 | import org.sonar.api.utils.log.Logger;
20 | import org.sonar.api.utils.log.Loggers;
21 |
22 | import fr.univartois.sonargo.core.ProjectExplorer;
23 |
24 | public class FunctionFinder {
25 | private static final Logger LOGGER = Loggers.get(FunctionFinder.class);
26 |
27 | private HashMap result = new HashMap<>();
28 | private String baseDir;
29 | private List paths;
30 |
31 | private static final Pattern MATCH_FUNC_NAME = Pattern.compile(
32 | "func\\s+(\\(suite\\s+[a-zA-Z0-9\\*\\._-]*\\)\\s+)?(?Test[^\\s]+)\\s*\\([a-zA-Z0-9\\*\\s\\.\\,_-]*\\)\\s*\\{");
33 |
34 | public FunctionFinder(SensorContext context) {
35 | this.baseDir = context.fileSystem().baseDir().getPath();
36 |
37 | LOGGER.info("base dir " + baseDir);
38 |
39 | paths = new ArrayList<>();
40 | ProjectExplorer.searchByType(context, InputFile.Type.TEST).forEach(i -> paths.add(i.file().toPath()));
41 |
42 | }
43 |
44 | public Map searchFunction() {
45 |
46 | paths.forEach(p -> {
47 | LOGGER.info("search test function in " + p.toFile().getAbsolutePath());
48 | searchFunctionInFile(p);
49 | });
50 | LOGGER.debug(result.toString());
51 | return result;
52 | }
53 |
54 | private CharBuffer getFileAsBufferFromPath(Path p) {
55 | try (FileInputStream input = new FileInputStream(p.toString())) {
56 | FileChannel channel = input.getChannel();
57 | ByteBuffer bbuf = channel.map(FileChannel.MapMode.READ_ONLY, 0, (int) channel.size());
58 | return Charset.forName("utf8").newDecoder().decode(bbuf);
59 | } catch (IOException e) {
60 | LOGGER.warn("IO Exception caught -", e);
61 | }
62 | return null;
63 | }
64 |
65 | public void searchFunctionInFile(Path p) {
66 | String absolutePath = p.toFile().getAbsolutePath();
67 | Matcher matcher = MATCH_FUNC_NAME.matcher(getFileAsBufferFromPath(p));
68 | while (matcher.find()) {
69 | String func = matcher.group("functionName");
70 | LOGGER.debug("Found function " + func + " at path " + absolutePath);
71 | if (func != null && absolutePath != null) {
72 | result.put(func, absolutePath);
73 | }
74 | }
75 | }
76 |
77 | public Map getResult() {
78 | return result;
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/src/main/java/fr/univartois/sonargo/gotest/GoJunitParser.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright 2017 - Université d'Artois
3 | *
4 | * This file is part of SonarQube Golang plugin (sonar-golang).
5 | *
6 | * Sonar-golang is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU Lesser General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * Sonar-golang is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with Sonar-golang. If not, see .
18 | *
19 | * Contributors:
20 | * Thibault Falque (thibault_falque@ens.univ-artois.fr)
21 | *******************************************************************************/
22 | package fr.univartois.sonargo.gotest;
23 |
24 | import java.io.File;
25 | import java.io.IOException;
26 | import java.util.ArrayList;
27 | import java.util.HashMap;
28 | import java.util.List;
29 | import java.util.Map;
30 |
31 | import javax.xml.parsers.DocumentBuilder;
32 | import javax.xml.parsers.DocumentBuilderFactory;
33 | import javax.xml.parsers.ParserConfigurationException;
34 |
35 | import org.sonar.api.utils.log.Logger;
36 | import org.sonar.api.utils.log.Loggers;
37 | import org.w3c.dom.Document;
38 | import org.w3c.dom.Element;
39 | import org.w3c.dom.Node;
40 | import org.w3c.dom.NodeList;
41 | import org.xml.sax.SAXException;
42 |
43 | import fr.univartois.sonargo.core.Parser;
44 |
45 | public class GoJunitParser implements Parser {
46 | private static final String TEST_SUITE_TAG = "testsuite";
47 | private static final String TEST_SKIPPED_TAG = "skipped";
48 | private static final String NAME_TEST_ATTR = "name";
49 | private static final String TIME_TEST_ATTR = "time";
50 | private static final String FAILURE_TAG = "failure";
51 | private static final String TEST_CASE_TAG = "testcase";
52 |
53 | private static final Logger LOGGER = Loggers.get(GoJunitParser.class);
54 |
55 | private final List> listTestSuiteByPackage = new ArrayList<>();
56 |
57 | private Map functionFileName;
58 |
59 | public GoJunitParser(Map functionFileName) {
60 | this.functionFileName = functionFileName;
61 | }
62 |
63 | @Override
64 | public void parse(String reportPath) throws ParserConfigurationException, SAXException, IOException {
65 | listTestSuiteByPackage.clear();
66 | final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
67 | final DocumentBuilder db = dbf.newDocumentBuilder();
68 | final Document doc = db.parse(new File(reportPath));
69 |
70 | doc.getDocumentElement().normalize();
71 |
72 | final NodeList testSuiteList = doc.getElementsByTagName(TEST_SUITE_TAG);
73 | for (int i = 0; i < testSuiteList.getLength(); i++) {
74 | final Node nNode = testSuiteList.item(i);
75 | if (nNode.getNodeType() == Node.ELEMENT_NODE) {
76 | final Element eElement = (Element) nNode;
77 |
78 | listTestSuiteByPackage.add(groupTestCaseByFile(eElement));
79 | }
80 | }
81 |
82 | }
83 |
84 | private HashMap groupTestCaseByFile(Element testSuite) {
85 | final NodeList testCaseList = testSuite.getElementsByTagName(TEST_CASE_TAG);
86 | HashMap mapResult = new HashMap<>();
87 | for (int i = 0; i < testCaseList.getLength(); i++) {
88 | final Node nNode = testCaseList.item(i);
89 | if (nNode.getNodeType() == Node.ELEMENT_NODE) {
90 | final Element testCase = (Element) nNode;
91 | String functionName = testCase.getAttribute(NAME_TEST_ATTR);
92 | String fileName = functionFileName.get(functionName);
93 | GoTestFile goTest = null;
94 | if (mapResult.containsKey(fileName)) {
95 | goTest = mapResult.get(fileName);
96 | } else if (fileName != null) {
97 | goTest = new GoTestFile();
98 | goTest.setFile(fileName);
99 | } else {
100 | LOGGER.warn("The key is null");
101 | continue;
102 | }
103 |
104 | goTest.addTestCase(new GoTestCase(testCase.getElementsByTagName(FAILURE_TAG).getLength() > 0,
105 | testCase.getElementsByTagName(TEST_SKIPPED_TAG).getLength() > 0,
106 | Double.parseDouble(testCase.getAttribute(TIME_TEST_ATTR))));
107 | mapResult.put(fileName, goTest);
108 | }
109 |
110 | }
111 | return mapResult;
112 |
113 | }
114 |
115 | public List> getListTestSuite() {
116 | return listTestSuiteByPackage;
117 | }
118 |
119 | }
120 |
--------------------------------------------------------------------------------
/src/main/java/fr/univartois/sonargo/gotest/GoTestCase.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright 2017 - Université d'Artois
3 | *
4 | * This file is part of SonarQube Golang plugin (sonar-golang).
5 | *
6 | * Sonar-golang is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU Lesser General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * Sonar-golang is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with Sonar-golang. If not, see .
18 | *
19 | * Contributors:
20 | * Thibault Falque (thibault_falque@ens.univ-artois.fr)
21 | *******************************************************************************/
22 | package fr.univartois.sonargo.gotest;
23 |
24 | public class GoTestCase {
25 | private boolean fail;
26 | private boolean skipped;
27 | private Double time;
28 |
29 | public GoTestCase(boolean fail, boolean skipped, Double time) {
30 | super();
31 | this.fail = fail;
32 | this.skipped = skipped;
33 | this.time = time;
34 | }
35 |
36 | public boolean isFail() {
37 | return fail;
38 | }
39 |
40 | public void setFail(boolean fail) {
41 | this.fail = fail;
42 | }
43 |
44 | public boolean isSkipped() {
45 | return skipped;
46 | }
47 |
48 | public void setSkipped(boolean skipped) {
49 | this.skipped = skipped;
50 | }
51 |
52 | public Double getTime() {
53 | return time;
54 | }
55 |
56 | public void setTime(Double time) {
57 | this.time = time;
58 | }
59 |
60 | }
61 |
--------------------------------------------------------------------------------
/src/main/java/fr/univartois/sonargo/gotest/GoTestFile.java:
--------------------------------------------------------------------------------
1 | package fr.univartois.sonargo.gotest;
2 |
3 | import java.util.ArrayList;
4 |
5 | public class GoTestFile {
6 | private ArrayList list;
7 | private String file;
8 |
9 | public GoTestFile() {
10 | super();
11 | list = new ArrayList<>();
12 | }
13 |
14 | public int getNbTotalTest() {
15 | return list.size();
16 | }
17 |
18 | public void addTestCase(GoTestCase t) {
19 | list.add(t);
20 | }
21 |
22 | public int getNbFailureTest() {
23 | int nbFailure = 0;
24 | for (GoTestCase tc : list) {
25 | if (tc.isFail())
26 | nbFailure++;
27 | }
28 | return nbFailure;
29 | }
30 |
31 | public int getSkipped() {
32 | int nbSkipped = 0;
33 | for (GoTestCase tc : list) {
34 | if (tc.isSkipped())
35 | nbSkipped++;
36 | }
37 | return nbSkipped;
38 | }
39 |
40 | public String getFile() {
41 | return file;
42 | }
43 |
44 | public void setFile(String file) {
45 | this.file = file;
46 | }
47 |
48 | public long getTime() {
49 | double time = 0.0;
50 | for (GoTestCase tc : list) {
51 | time += tc.getTime();
52 | }
53 | return (long) (time * 1000);
54 | }
55 |
56 | }
57 |
--------------------------------------------------------------------------------
/src/main/java/fr/univartois/sonargo/gotest/GoTestReportSaver.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright 2017 - Université d'Artois
3 | *
4 | * This file is part of SonarQube Golang plugin (sonar-golang).
5 | *
6 | * Sonar-golang is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU Lesser General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * Sonar-golang is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with Sonar-golang. If not, see .
18 | *
19 | * Contributors:
20 | * Thibault Falque (thibault_falque@ens.univ-artois.fr)
21 | *******************************************************************************/
22 | package fr.univartois.sonargo.gotest;
23 |
24 | import java.io.Serializable;
25 | import java.util.List;
26 | import java.util.Map;
27 |
28 | import org.sonar.api.batch.fs.FilePredicates;
29 | import org.sonar.api.batch.fs.InputFile;
30 | import org.sonar.api.batch.sensor.SensorContext;
31 | import org.sonar.api.measures.CoreMetrics;
32 | import org.sonar.api.measures.Metric;
33 | import org.sonar.api.utils.log.Logger;
34 | import org.sonar.api.utils.log.Loggers;
35 |
36 | public class GoTestReportSaver {
37 | private static final Logger LOGGER = Loggers.get(GoTestReportSaver.class);
38 |
39 | private GoTestReportSaver() {
40 | throw new IllegalStateException("Utility class");
41 | }
42 |
43 | public static void save(SensorContext context, List> list) {
44 | FilePredicates predicates = context.fileSystem().predicates();
45 | for (Map map : list) {
46 | for (Map.Entry entry : map.entrySet()) {
47 | String key = entry.getKey();
48 | GoTestFile value = entry.getValue();
49 | if (value == null) {
50 | LOGGER.warn("Value for " + key + " is null");
51 | continue;
52 | }
53 | if (value.getFile() == null) {
54 | LOGGER.debug("saving measures for file " + value.getFile());
55 | LOGGER.warn("No file could be determined from " + value.getFile());
56 | continue;
57 | }
58 | InputFile file = context.fileSystem().inputFile(predicates.hasAbsolutePath(value.getFile()));
59 | if (file == null) {
60 | LOGGER.warn("File not found " + value.getFile());
61 | continue;
62 | }
63 | try {
64 | saveMeasure(value, context, file);
65 | } catch (Exception e) { // yes, I know this is naughty...
66 | LOGGER.warn(e.getMessage());
67 | }
68 | }
69 | }
70 |
71 | }
72 |
73 | private static void saveMeasure(GoTestFile t, SensorContext context, InputFile file) {
74 | saveMeasure(context, file, CoreMetrics.SKIPPED_TESTS, t.getSkipped());
75 | saveMeasure(context, file, CoreMetrics.TESTS, t.getNbTotalTest());
76 | saveMeasure(context, file, CoreMetrics.TEST_FAILURES, t.getNbFailureTest());
77 | saveMeasure(context, file, CoreMetrics.TEST_EXECUTION_TIME, t.getTime());
78 | }
79 |
80 | private static void saveMeasure(SensorContext context, InputFile inputFile,
81 | Metric metric, T value) {
82 | LOGGER.warn(inputFile.absolutePath());
83 | LOGGER.warn(metric.toString());
84 | context.newMeasure().forMetric(metric).on(inputFile).withValue(value).save();
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/src/main/java/fr/univartois/sonargo/gotest/GoTestSensor.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright 2017 - Université d'Artois
3 | *
4 | * This file is part of SonarQube Golang plugin (sonar-golang).
5 | *
6 | * Sonar-golang is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU Lesser General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * Sonar-golang is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with Sonar-golang. If not, see .
18 | *
19 | * Contributors:
20 | * Thibault Falque (thibault_falque@ens.univ-artois.fr)
21 | *******************************************************************************/
22 | package fr.univartois.sonargo.gotest;
23 |
24 | import java.io.File;
25 | import java.io.IOException;
26 | import java.util.Map;
27 |
28 | import javax.xml.parsers.ParserConfigurationException;
29 |
30 | import org.sonar.api.batch.sensor.Sensor;
31 | import org.sonar.api.batch.sensor.SensorContext;
32 | import org.sonar.api.batch.sensor.SensorDescriptor;
33 | import org.sonar.api.utils.log.Logger;
34 | import org.sonar.api.utils.log.Loggers;
35 | import org.xml.sax.SAXException;
36 |
37 | import fr.univartois.sonargo.core.language.GoLanguage;
38 | import fr.univartois.sonargo.core.settings.GoProperties;
39 |
40 | public class GoTestSensor implements Sensor {
41 | private static final Logger LOGGER = Loggers.get(GoTestSensor.class);
42 |
43 | @Override
44 | public void describe(SensorDescriptor descriptor) {
45 | descriptor.onlyOnLanguage(GoLanguage.KEY).name("Go test JUnit loader sensor");
46 |
47 | }
48 |
49 | @Override
50 | public void execute(SensorContext context) {
51 | String reportPath = context.settings().getString(GoProperties.JUNIT_REPORT_PATH_KEY);
52 |
53 | if (reportPath == null || !(new File(reportPath)).exists()) {
54 | LOGGER.info("no junit report");
55 | return;
56 | }
57 | FunctionFinder ff;
58 | try {
59 | ff = new FunctionFinder(context);
60 |
61 | Map nameFunction = ff.searchFunction();
62 |
63 | LOGGER.debug(nameFunction.toString());
64 |
65 | GoJunitParser junitParser = new GoJunitParser(nameFunction);
66 |
67 | junitParser.parse(reportPath);
68 |
69 | GoTestReportSaver.save(context, junitParser.getListTestSuite());
70 |
71 | } catch (ParserConfigurationException | SAXException | IOException e) {
72 | LOGGER.error("Parse exception ", e);
73 | }
74 | }
75 |
76 | }
77 |
--------------------------------------------------------------------------------
/src/main/java/fr/univartois/sonargo/highlighter/Colorizer.java:
--------------------------------------------------------------------------------
1 | package fr.univartois.sonargo.highlighter;
2 |
3 | import java.io.BufferedReader;
4 | import java.io.File;
5 | import java.io.FileInputStream;
6 | import java.io.IOException;
7 | import java.io.InputStreamReader;
8 | import java.nio.charset.StandardCharsets;
9 |
10 | import org.sonar.api.batch.fs.InputFile;
11 | import org.sonar.api.batch.sensor.SensorContext;
12 | import org.sonar.api.batch.sensor.highlighting.NewHighlighting;
13 | import org.sonar.api.batch.sensor.highlighting.TypeOfText;
14 | import org.sonar.api.utils.log.Logger;
15 | import org.sonar.api.utils.log.Loggers;
16 |
17 | import fr.univartois.sonargo.core.language.GoLexer;
18 |
19 | public class Colorizer {
20 |
21 | private static final Logger LOGGER = Loggers.get(Colorizer.class);
22 | private final NewHighlighting highlighting;
23 |
24 | public Colorizer(SensorContext context) {
25 | super();
26 |
27 | highlighting = context.newHighlighting();
28 | }
29 |
30 | public void colorize(InputFile i) {
31 | final File f = i.file();
32 | LOGGER.debug("Coloring the file: " + f.getPath());
33 | highlighting.onFile(i);
34 | try (final BufferedReader br = new BufferedReader(
35 | new InputStreamReader(new FileInputStream(f), StandardCharsets.UTF_8))) {
36 |
37 | String line;
38 | int lineNumber = 1;
39 | while ((line = br.readLine()) != null) {
40 | searchAndColor(line, lineNumber);
41 | lineNumber++;
42 | }
43 | } catch (final IOException e) {
44 | LOGGER.error("IO Exception", e);
45 | }
46 | try {
47 | highlighting.save();
48 | } catch (Exception ex) {
49 | LOGGER.error("Highlighting problem on save", ex.getMessage());
50 | }
51 |
52 | }
53 |
54 | private boolean haveString(String s) {
55 | return s.chars().filter(i -> i == '"').count() > 0;
56 | }
57 |
58 | private void highlightingComment(int lineNumber, int end) {
59 | highlighting.highlight(lineNumber, 0, lineNumber, end, TypeOfText.COMMENT);
60 |
61 | }
62 |
63 | private int searchNextOccurrenceOfDoubleQuote(String line, int start) {
64 | int index = line.indexOf('"', start);
65 | LOGGER.debug(line + " " + index);
66 | while (index > 0 && line.charAt(index - 1) == '\\') {
67 | index = line.indexOf('"', index + 1);
68 | LOGGER.debug(line + " " + index);
69 | }
70 | return index;
71 | }
72 |
73 | private void highlightingStringInLine(String line, int lineNumber) {
74 | if (!haveString(line)) {
75 | return;
76 | }
77 | int start = 0;
78 | int index = searchNextOccurrenceOfDoubleQuote(line, start);
79 | int indexEnd = searchNextOccurrenceOfDoubleQuote(line, index + 1);
80 |
81 | int lastIndex = 0;
82 | int lastIndexEnd = 0;
83 |
84 | while (index != -1 && indexEnd != -1 && lastIndex != index && lastIndexEnd != indexEnd) {
85 | LOGGER.debug("index " + index + " indexEnd " + indexEnd);
86 | try {
87 | highlighting.highlight(lineNumber, index, lineNumber, indexEnd + 1, TypeOfText.STRING);
88 | } catch (Exception ex) {
89 | LOGGER.error("String highlighting problem", ex);
90 | }
91 | start = indexEnd + 1;
92 | lastIndex = index;
93 | lastIndexEnd = indexEnd;
94 | index = searchNextOccurrenceOfDoubleQuote(line, start);
95 | indexEnd = searchNextOccurrenceOfDoubleQuote(line, index + 1);
96 | }
97 |
98 | }
99 |
100 | private boolean isAString(String line, int index) {
101 | return line.substring(0, index).chars().filter(i -> i == '"').count() % 2 != 0;
102 |
103 | }
104 |
105 | private void highlightingKeyWord(String line, int lineNumber) {
106 | for (final GoLexer.Keyword k : GoLexer.Keyword.values()) {
107 | final String key = k.getValue();
108 | int index = 0;
109 | while ((index = line.indexOf(key, index)) != -1 && !isAString(line, index)) {
110 |
111 | LOGGER.debug("Line number " + lineNumber + " index start: " + index + " index end: "
112 | + (index + key.length()));
113 | try {
114 | highlighting.highlight(lineNumber, index, lineNumber, index + key.length(), TypeOfText.KEYWORD);
115 | } catch (Exception ex) {
116 | LOGGER.error("Keyword highlighting problem", ex);
117 | }
118 | index = index + key.length();
119 | }
120 | }
121 | }
122 |
123 | private void searchAndColor(String s, int lineNumber) {
124 | if (s.trim().startsWith(GoLexer.COMMENT_SYMBOL)) {
125 | highlightingComment(lineNumber, s.length());
126 | } else {
127 | highlightingStringInLine(s, lineNumber);
128 | highlightingKeyWord(s, lineNumber);
129 | }
130 | }
131 |
132 | }
133 |
--------------------------------------------------------------------------------
/src/main/java/fr/univartois/sonargo/highlighter/HighlighterSensor.java:
--------------------------------------------------------------------------------
1 | package fr.univartois.sonargo.highlighter;
2 |
3 | import java.util.List;
4 |
5 | import org.sonar.api.batch.fs.InputFile;
6 | import org.sonar.api.batch.sensor.Sensor;
7 | import org.sonar.api.batch.sensor.SensorContext;
8 | import org.sonar.api.batch.sensor.SensorDescriptor;
9 | import org.sonar.api.utils.log.Logger;
10 | import org.sonar.api.utils.log.Loggers;
11 |
12 | import fr.univartois.sonargo.core.ProjectExplorer;
13 | import fr.univartois.sonargo.core.settings.GoProperties;
14 |
15 | public class HighlighterSensor implements Sensor {
16 | private static final Logger LOGGER = Loggers.get(HighlighterSensor.class);
17 |
18 | @Override
19 | public void describe(SensorDescriptor descriptor) {
20 | descriptor.name("Go Highlighter Sensor");
21 |
22 | }
23 |
24 | @Override
25 | public void execute(SensorContext context) {
26 |
27 | if (!context.settings().getBoolean(GoProperties.HIGHLIGHTING_KEY)) {
28 | LOGGER.info("highlighting disabled");
29 | return;
30 | }
31 |
32 | final List listFiles = ProjectExplorer.searchFileWithTypeMainOrTest(context);
33 | listFiles.forEach(i -> new Colorizer(context).colorize(i));
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/java/fr/univartois/sonargo/toolkit/GoColorizer.java:
--------------------------------------------------------------------------------
1 | package fr.univartois.sonargo.toolkit;
2 |
3 | import java.util.Arrays;
4 | import java.util.List;
5 |
6 | import org.sonar.colorizer.CDocTokenizer;
7 | import org.sonar.colorizer.CppDocTokenizer;
8 | import org.sonar.colorizer.KeywordsTokenizer;
9 | import org.sonar.colorizer.Tokenizer;
10 |
11 | import fr.univartois.sonargo.core.language.GoLexer;
12 |
13 | public final class GoColorizer {
14 |
15 | private GoColorizer() {
16 | }
17 |
18 | public static List getTokenizers() {
19 | return Arrays.asList(new CDocTokenizer("", " "),
20 | new CppDocTokenizer("", " "),
21 | new KeywordsTokenizer("", " ", GoLexer.Keyword.keywordValues()));
22 | }
23 |
24 | }
--------------------------------------------------------------------------------
/src/main/java/fr/univartois/sonargo/toolkit/GoToolkit.java:
--------------------------------------------------------------------------------
1 | package fr.univartois.sonargo.toolkit;
2 |
3 | import java.nio.charset.Charset;
4 | import java.nio.charset.IllegalCharsetNameException;
5 | import java.nio.charset.UnsupportedCharsetException;
6 | import java.util.List;
7 |
8 | import org.sonar.api.internal.google.common.collect.ImmutableList;
9 | import org.sonar.colorizer.Tokenizer;
10 | import org.sonar.sslr.toolkit.AbstractConfigurationModel;
11 | import org.sonar.sslr.toolkit.ConfigurationProperty;
12 | import org.sonar.sslr.toolkit.Toolkit;
13 |
14 | import com.sonar.sslr.api.Grammar;
15 | import com.sonar.sslr.impl.Parser;
16 |
17 | import fr.univartois.sonargo.core.language.GoParser;
18 |
19 | public final class GoToolkit {
20 |
21 | private GoToolkit() {
22 | }
23 |
24 | public static void main(String[] args) {
25 | final Toolkit toolkit = new Toolkit("SonarSource : Go : Toolkit", new GoConfigurationModel());
26 | toolkit.run();
27 | }
28 |
29 | static class GoConfigurationModel extends AbstractConfigurationModel {
30 |
31 | private final ConfigurationProperty charsetProperty = new ConfigurationProperty("Charset",
32 | "Charset used when opening files.", "UTF-8", newValueCandidate -> {
33 | try {
34 | Charset.forName(newValueCandidate);
35 | return "";
36 | } catch (final IllegalCharsetNameException e1) {
37 | return "Illegal charset name: " + newValueCandidate;
38 | } catch (final UnsupportedCharsetException e2) {
39 | return "Unsupported charset: " + newValueCandidate;
40 | }
41 | });
42 |
43 | @Override
44 | public List getProperties() {
45 | return ImmutableList.of(charsetProperty);
46 | }
47 |
48 | @Override
49 | public Charset getCharset() {
50 | return Charset.forName(charsetProperty.getValue());
51 | }
52 |
53 | @Override
54 | public Parser doGetParser() {
55 | updateConfiguration();
56 | return GoParser.create();
57 | }
58 |
59 | @Override
60 | public List doGetTokenizers() {
61 | updateConfiguration();
62 | return GoColorizer.getTokenizers();
63 | }
64 |
65 | private static void updateConfiguration() {
66 | /* Construct a parser configuration object from the properties */
67 | }
68 |
69 | }
70 |
71 | }
--------------------------------------------------------------------------------
/src/main/resources/key.properties:
--------------------------------------------------------------------------------
1 | ###############################################################################
2 | # Copyright 2017 - Université d'Artois
3 | #
4 | # This file is part of SonarQube Golang plugin (sonar-golang).
5 | #
6 | # Sonar-golang is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU Lesser General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 | #
11 | # Sonar-golang is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU Lesser General Public License for more details.
15 | #
16 | # You should have received a copy of the GNU Lesser General Public License
17 | # along with Sonar-golang. If not, see .
18 | #
19 | # Contributors:
20 | # Thibault Falque (thibault_falque@ens.univ-artois.fr)
21 | ###############################################################################
22 | #golint\:ExportedType=exported type [a-zA-Z0-9]+ should have comment or be unexported
23 | golint\:FormComment=comment on exported [a-zA-Z0-9]+ [a-zA-Z0-9\.]+ should be of the form "[a-zA-Z\.]+ *\t*..."
24 | golint\:AllCaps=don't use ALL_CAPS in Go names; use CamelCase
25 | golint\:UnderscoreInPackageName=don't use an underscore in package name
26 | golint\:LeadingK=don't use leading k in Go names; [a-zA-Z0-9]+ [a-zA-Z0-9]+ should be [a-zA-Z0-9]+
27 | golint\:UnderscoreInGoName=don't use underscores in Go names; [a-zA-Z0-9]+ [a-zA-Z0-9_]+ should be [a-zA-Z0-9]+
28 | golint\:ErrorLastReturn=error should be the last type when returning multiple items
29 | golint\:ErrorEndString=error strings should not be capitalized or end with punctuation or a newline
30 | golint\:ErrorVarName=error var [a-zA-Z0-9]+ should have name of the form [a-zA-Z0-9]+
31 | golint\:AnnoyingUseExportedType=exported [a-zA-Z0-9]+ [a-zA-Z0-9]+ returns unexported type [a-zA-Z0-9]+, which can be annoying to use
32 | golint\:IfBlockReturn=if block ends with a return statement, so drop this else and outdent its block
33 | golint\:PackageCommentForm=package comment should be of the form \"[a-zA-Z0-9]+...\"
34 | golint\:PackageCommentSpace=package comment should not have leading space
35 | golint\:ReceiverNameConsistent=receiver name [a-zA-Z0-9]+ should be consistent with previous receiver name [a-zA-Z0-9]+ for [a-zA-Z0-9]+
36 | golint\:ReceiverNameReflection=receiver name should be a reflection of its identity; don't use generic names such as \"this\" or \"self\"
37 | golint\:ReceiverNameNotUnderscore=receiver name should not be an underscore
38 | golint\:DropAssignment=should drop = [a-zA-Z0-9]+ from declaration of var [a-zA-Z0-9]+; it is the zero value
39 | golint\:HavePackageComment=should have a package comment, unless it's in another file for this package
40 | golint\:NotUseBasicType=should not use basic type [a-zA-Z0-9]+ as key in context.WithValue
41 | golint\:NotUseDotImport=should not use dot imports
42 | golint\:Omit2ndValueFromRange=should omit 2nd value from range; this loop is equivalent to `for [a-zA-Z0-9]+ := range ...`
43 | golint\:OmitType=should omit type [a-zA-Z0-9]+ from declaration of var [a-zA-Z0-9]+; it will be inferred from the right-hand side
44 | golint\:ReplaceLintIncDec=should replace [a-zA-Z0-9\-\+=]+ with [a-zA-Z0-9\-\+]+
45 | golint\:ReplaceSprintf=should replace [a-zA-Z0-9\.]+\\(fmt.Sprintf\\(...\\)\\) with [a-zA-Z0-9]+.Errorf\\(...\\)
46 | golint\:Initialisms=[a-zA-Z0-9]+ [a-zA-Z0-9]+ should be [a-zA-Z0-9]+
47 | golint\:PackageNames=[a-zA-Z0-9]+ name will be used as [a-zA-Z0-9]+.[a-zA-Z0-9]+ by other packages, and that stutters; consider calling this [a-zA-Z0-9]+
48 | golint\:BlankImport=a blank import should be only in a main or test package, or have a comment justifying it
49 | golint\:CommentExportedType=comment on exported type [a-zA-Z0-9]+ should be of the form "[a-zA-Z0-9]+ ..." \\(with optional leading article\\)
50 | golint\:ContextContextFirstArg=context.Context should be the first parameter of a function
51 | golint\:ExportedHaveComment=exported [a-zA-Z0-9]+ [a-zA-Z0-9\.]+ should have comment or be unexported
52 | golint\:ExportedHaveComment2=exported [a-zA-Z0-9\.]+ [a-zA-Z0-9\.]+ should have comment[\(\) a-zA-Z0-9]+ or be unexported
53 | golint\:ExportedDeclaration=exported [a-zA-Z0-9]+ [a-zA-Z0-9]+ should have its own declaration
54 | golint\:SpecificSuffix=var [a-zA-Z0-9]+ is of type [a-zA-Z0-9\.]+; don't use unit-specific suffix [a-zA-Z0-9]+
55 | golint\:StructFieldInitialisms=struct field [a-zA-Z0-9]+ should be [a-zA-Z0-9]+
56 | gocyclo\:CyclomaticComplexity=cyclomatic complexity [0-9]+ of function (\\(([a-zA-Z0-9]+ )?\\*?[a-zA-Z0-9]+\\)\\.)?[a-zA-Z0-9]+\\(\\) is high \\(> [0-9]+\\)
57 | errcheck\:ValueNotChecked=error return value not checked .*
58 | unconvert\:UnnecessaryConversion=unnecessary conversion
59 | structcheck\:UnusedStructField=unused struct field \\w+[\\w\\.]*
60 | gosimple\:ChannelInsteadSelect=
61 | ineffassign\:IneffectualAssignment=ineffectual assignment to [a-zA-Z0-9]+
62 | gas\:UnhandledErrors=Errors unhandled\.,LOW,HIGH
63 | goimports\:FileNotImported=file is not goimported
64 | vet\:Unreachable=unreachable code
65 | vet\:Shadow=declaration of "[A-Za-z0-9\\.]+" shadows declaration at [A-Za-z0-9_\\-/]+.go:[0-9]+
66 | vet\:Misuse=possible misuse of unsafe.Pointer
67 | gas\:SQLFormatting=SQL string formatting,MEDIUM,HIGH
68 | gas\:SQLConcatenation=SQL string concatenation,MEDIUM,HIGH
69 | gas\:RSAKeyLength=RSA keys should be at least 2048 bits,MEDIUM,HIGH
70 | gas\:UnsafeCall=Use of unsafe calls should be audited,LOW,HIGH
71 | gas\:UnescapedHTMLTemplates=this method will not auto-escape HTML\. Verify data is well formed\.,MEDIUM,LOW
72 | gas\:WeakCrypto=Use of weak cryptographic primitive,HIGH,HIGH
73 | vet\:Lock=[A-Za-z0-9\.]+ passes lock by value: [A-Za-z0-9\.]+ contains [A-Za-z0-9\.]+
74 | vet\:FormatingPrintfFamily=possible formatting directive in [A-Za-z0-9\.]+ call
75 |
--------------------------------------------------------------------------------
/src/main/resources/profile.properties:
--------------------------------------------------------------------------------
1 | ###############################################################################
2 | # Copyright 2017 - Université d'Artois
3 | #
4 | # This file is part of SonarQube Golang plugin (sonar-golang).
5 | #
6 | # Sonar-golang is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU Lesser General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 | #
11 | # Sonar-golang is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU Lesser General Public License for more details.
15 | #
16 | # You should have received a copy of the GNU Lesser General Public License
17 | # along with Sonar-golang. If not, see .
18 | #
19 | # Contributors:
20 | # Thibault Falque (thibault_falque@ens.univ-artois.fr)
21 | ###############################################################################
22 | #golint\:ExportedType=true
23 | golint\:FormComment=true
24 | golint\:AllCaps=true
25 | golint\:UnderscoreInPackageName=true
26 | golint\:LeadingK=true
27 | golint\:UnderscoreInGoName=true
28 | golint\:ErrorLastReturn=true
29 | golint\:ErrorEndString=true
30 | golint\:ErrorVarName=true
31 | golint\:AnnoyingUseExportedType=true
32 | golint\:IfBlockReturn=true
33 | golint\:PackageCommentForm=true
34 | golint\:PackageCommentSpace=true
35 | golint\:ReceiverNameConsistent=true
36 | golint\:ReceiverNameReflection=true
37 | golint\:ReceiverNameNotUnderscore=true
38 | golint\:DropAssignment=true
39 | golint\:HavePackageComment=true
40 | golint\:NotUseBasicType=true
41 | golint\:NotUseDotImport=true
42 | golint\:Omit2ndValueFromRange=true
43 | golint\:OmitType=true
44 | golint\:ReplaceLintIncDec=true
45 | golint\:ReplaceSprintf=true
46 | golint\:Initialisms=true
47 | golint\:PackageNames=true
48 | golint\:BlankImport=true
49 | golint\:CommentExportedType=true
50 | golint\:ContextContextFirstArg=true
51 | golint\:ExportedHaveComment=true
52 | golint\:ExportedHaveComment2=true
53 | golint\:ExportedDeclaration=true
54 | golint\:SpecificSuffix=true
55 | golint\:StructFieldInitialisms=true
56 | gocyclo\:CyclomaticComplexity=true
57 | errcheck\:ValueNotChecked=true
58 | unconvert\:UnnecessaryConversion=true
59 | structcheck\:UnusedStructField=true
60 | gosimple\:ChannelInsteadSelect=true
61 | ineffassign\:IneffectualAssignment=true
62 | gas\:UnhandledErrors=true
63 | goimports\:FileNotImported=true
64 | gas\:SQLFormatting=true
65 | vet\:Shadow=true
66 | gas\:SQLConcatenation=true
67 | gas\:RSAKeyLength=true
68 | gas\:UnsafeCall=true
69 | gas\:UnescapedHTMLTemplates=true
70 | gas\:WeakCrypto=true
71 | vet\:Unreachable=true
72 | vet\:Misuse=true
73 | vet\:Lock=true
74 | vet\:FormatingPrintfFamily=true
--------------------------------------------------------------------------------
/src/test/java/fr/univartois/sonargo/AbstractSonarTest.java:
--------------------------------------------------------------------------------
1 | package fr.univartois.sonargo;
2 |
3 | import org.sonar.api.CoreProperties;
4 | import org.sonar.api.batch.fs.internal.DefaultFileSystem;
5 | import org.sonar.api.batch.sensor.internal.SensorContextTester;
6 |
7 | import fr.univartois.sonargo.core.settings.GoProperties;
8 |
9 | public abstract class AbstractSonarTest {
10 | protected DefaultFileSystem fileSystem;
11 | protected SensorContextTester testerContext;
12 |
13 | public void init() {
14 | init(TestUtils.getDefaultFileSystem());
15 | }
16 |
17 | public void init(DefaultFileSystem fileSystem) {
18 | this.fileSystem = fileSystem;
19 |
20 | testerContext = SensorContextTester.create(fileSystem.baseDir());
21 |
22 | testerContext.settings().appendProperty(GoProperties.COVERAGE_REPORT_PATH_KEY,
23 | GoProperties.COVERAGE_REPORT_PATH_DEFAULT);
24 | testerContext.settings().appendProperty(GoProperties.REPORT_PATH_KEY, GoProperties.REPORT_PATH_DEFAULT);
25 | testerContext.settings().appendProperty(GoProperties.JUNIT_REPORT_PATH_KEY,
26 | GoProperties.JUNIT_REPORT_PATH_DEFAULT);
27 |
28 | testerContext.settings().appendProperty(CoreProperties.PROJECT_EXCLUSIONS_PROPERTY, "vendor/**,.git/**");
29 | testerContext.settings().appendProperty(CoreProperties.PROJECT_TEST_INCLUSIONS_PROPERTY, "**/**_test.go");
30 | testerContext.settings().appendProperty(CoreProperties.PROJECT_INCLUSIONS_PROPERTY, "**/**.go");
31 | testerContext.settings().appendProperty("sonar.sources", "./");
32 | testerContext.settings().appendProperty("sonar.tests", "./");
33 |
34 | testerContext.setFileSystem(fileSystem);
35 |
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/src/test/java/fr/univartois/sonargo/AllTests.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright 2017 - Université d'Artois
3 | *
4 | * This file is part of SonarQube Golang plugin (sonar-golang).
5 | *
6 | * Sonar-golang is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU Lesser General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * Sonar-golang is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with Sonar-golang. If not, see .
18 | *
19 | * Contributors:
20 | * Thibault Falque (thibault_falque@ens.univ-artois.fr)
21 | *******************************************************************************/
22 | package fr.univartois.sonargo;
23 |
24 | import org.junit.runner.RunWith;
25 | import org.junit.runners.Suite;
26 | import org.junit.runners.Suite.SuiteClasses;
27 |
28 | import fr.univartois.sonargo.core.ProjectExplorerTest;
29 | import fr.univartois.sonargo.core.language.GoLanguageTest;
30 | import fr.univartois.sonargo.core.language.GoLexerTest;
31 | import fr.univartois.sonargo.core.language.GoQualityProfileTest;
32 | import fr.univartois.sonargo.core.rules.EvalTest;
33 | import fr.univartois.sonargo.core.rules.GoErrorTest;
34 | import fr.univartois.sonargo.core.rules.GoLintIssueLoaderSendorTest;
35 | import fr.univartois.sonargo.core.rules.GoLintRulesDefinitionTest;
36 | import fr.univartois.sonargo.core.settings.GoPropertiesTest;
37 | import fr.univartois.sonargo.coverage.CoverageSensorTest;
38 | import fr.univartois.sonargo.gotest.FunctionFinderTest;
39 |
40 | @RunWith(Suite.class)
41 | @SuiteClasses({ EvalTest.class, GoErrorTest.class, GoLanguageTest.class, GoQualityProfileTest.class,
42 | GoLintIssueLoaderSendorTest.class, GoLintRulesDefinitionTest.class, GoPluginTest.class, GoPropertiesTest.class,
43 | CoverageSensorTest.class, GoLexerTest.class, FunctionFinderTest.class, ProjectExplorerTest.class })
44 | public class AllTests {
45 | }
46 |
--------------------------------------------------------------------------------
/src/test/java/fr/univartois/sonargo/FunctionFinderTest.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package fr.univartois.sonargo;
5 |
6 | import static org.junit.Assert.assertEquals;
7 |
8 | import java.io.File;
9 | import java.nio.file.Paths;
10 | import java.util.Map;
11 | import java.util.Set;
12 |
13 | import org.junit.Before;
14 | import org.junit.Ignore;
15 | import org.junit.Test;
16 |
17 | import fr.univartois.sonargo.gotest.FunctionFinder;
18 |
19 | /**
20 | * @author thibault
21 | *
22 | */
23 | @Ignore
24 | public class FunctionFinderTest extends AbstractSonarTest {
25 | @Before
26 | @Override
27 | public void init() {
28 | init(TestUtils.getDefaultFileSystem());
29 | }
30 |
31 | @Test
32 | public void testSearchInFile() {
33 | String path = new File(testerContext.fileSystem().baseDir(), "test_test.go").getPath();
34 |
35 | FunctionFinder f = new FunctionFinder(testerContext);
36 | f.searchFunctionInFile(Paths.get(path));
37 | Map result = f.getResult();
38 | Set expected = new java.util.HashSet();
39 | expected.add("TestEasyDef");
40 | expected.add("TestSpaceDef");
41 | expected.add("TestNoSpaceDef");
42 | expected.add("TestTwoLines1");
43 | expected.add("TestTwoLines2");
44 | expected.add("TestNested");
45 | expected.add("TestSuite");
46 | assertEquals(expected, result.keySet());
47 |
48 | }
49 |
50 | }
51 |
--------------------------------------------------------------------------------
/src/test/java/fr/univartois/sonargo/GoPluginTest.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright 2017 - Université d'Artois
3 | *
4 | * This file is part of SonarQube Golang plugin (sonar-golang).
5 | *
6 | * Sonar-golang is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU Lesser General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * Sonar-golang is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with Sonar-golang. If not, see .
18 | *
19 | * Contributors:
20 | * Thibault Falque (thibault_falque@ens.univ-artois.fr)
21 | *******************************************************************************/
22 | package fr.univartois.sonargo;
23 |
24 | import static org.junit.Assert.assertEquals;
25 |
26 | import org.junit.Test;
27 | import org.sonar.api.Plugin;
28 | import org.sonar.api.SonarRuntime;
29 | import org.sonar.api.internal.SonarRuntimeImpl;
30 | import org.sonar.api.utils.Version;
31 |
32 | public class GoPluginTest {
33 | private final SonarGoPlugin javaPlugin = new SonarGoPlugin();
34 | private static final Version VERSION_6_0 = Version.create(6, 0);
35 |
36 | @Test
37 | public void test() {
38 | final SonarRuntime runtime = SonarRuntimeImpl.forSonarLint(VERSION_6_0);
39 | final Plugin.Context context = new Plugin.Context(runtime);
40 |
41 | javaPlugin.define(context);
42 |
43 | assertEquals(13, context.getExtensions().size());
44 |
45 | }
46 |
47 | }
48 |
--------------------------------------------------------------------------------
/src/test/java/fr/univartois/sonargo/TestUtils.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright 2017 - Université d'Artois
3 | *
4 | * This file is part of SonarQube Golang plugin (sonar-golang).
5 | *
6 | * Sonar-golang is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU Lesser General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * Sonar-golang is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with Sonar-golang. If not, see .
18 | *
19 | * Contributors:
20 | * Thibault Falque (thibault_falque@ens.univ-artois.fr)
21 | *******************************************************************************/
22 | package fr.univartois.sonargo;
23 |
24 | import java.io.File;
25 |
26 | import org.sonar.api.batch.fs.InputFile;
27 | import org.sonar.api.batch.fs.internal.DefaultFileSystem;
28 | import org.sonar.api.batch.fs.internal.DefaultInputFile;
29 |
30 | import fr.univartois.sonargo.core.language.GoLanguage;
31 |
32 | public class TestUtils {
33 | private static final String TEST_RESSOURCES = "src/test/resources";
34 | private static final String COVERAGE_REPORT_PATH = "coverage";
35 | private static final String TEST_PATH = "gotest";
36 | private static final String HIGLIGHTER_CODE_PATH = "highlighter";
37 | private static final String PROJECT_CODE_PATH = "project";
38 |
39 | public static DefaultFileSystem getDefaultFileSystem() {
40 | return new DefaultFileSystem(getModuleBaseDir());
41 | }
42 |
43 | public static DefaultFileSystem getTestBaseDir() {
44 | DefaultFileSystem fs = new DefaultFileSystem(
45 | (new File(TEST_RESSOURCES + File.separator + TEST_PATH)).getAbsoluteFile());
46 |
47 | DefaultInputFile f1 = new DefaultInputFile("module", "test1_test.go");
48 | f1 = f1.setType(InputFile.Type.TEST);
49 | f1 = f1.setLanguage(GoLanguage.KEY);
50 |
51 | DefaultInputFile f2 = new DefaultInputFile("module", "test_test.go");
52 | f2 = f2.setType(InputFile.Type.TEST);
53 | f2 = f2.setLanguage(GoLanguage.KEY);
54 |
55 | fs = fs.add(f1);
56 | fs = fs.add(f2);
57 |
58 | return fs;
59 | }
60 |
61 | public static DefaultFileSystem getCoverageBaseDir() {
62 | return new DefaultFileSystem(new File(TEST_RESSOURCES + File.separator + COVERAGE_REPORT_PATH));
63 | }
64 |
65 | public static DefaultFileSystem getProjectDir() {
66 | DefaultFileSystem fs = new DefaultFileSystem(new File(TEST_RESSOURCES + File.separator + PROJECT_CODE_PATH));
67 | DefaultInputFile f = new DefaultInputFile("module", "package1.go");
68 | f = f.setType(InputFile.Type.MAIN);
69 | f = f.setLanguage(GoLanguage.KEY);
70 |
71 | DefaultInputFile f2 = new DefaultInputFile("module", "package1_test.go");
72 | f2 = f2.setType(InputFile.Type.TEST);
73 | f2 = f2.setLanguage(GoLanguage.KEY);
74 |
75 | DefaultInputFile f3 = new DefaultInputFile("module", "test.py");
76 | f3 = f3.setType(InputFile.Type.MAIN);
77 | f3 = f3.setLanguage("python");
78 |
79 | fs = fs.add(f);
80 | fs = fs.add(f2);
81 | fs = fs.add(f3);
82 |
83 | return fs;
84 | }
85 |
86 | public static DefaultFileSystem getColorizeDir() {
87 | return new DefaultFileSystem(new File(TEST_RESSOURCES + File.separator + HIGLIGHTER_CODE_PATH));
88 | }
89 |
90 | public static File getModuleBaseDir() {
91 | return new File(TEST_RESSOURCES);
92 | }
93 |
94 | }
95 |
--------------------------------------------------------------------------------
/src/test/java/fr/univartois/sonargo/core/ProjectExplorerTest.java:
--------------------------------------------------------------------------------
1 | package fr.univartois.sonargo.core;
2 |
3 | import static org.junit.Assert.assertEquals;
4 | import static org.junit.Assert.assertFalse;
5 | import static org.junit.Assert.assertNotNull;
6 |
7 | import java.util.List;
8 |
9 | import org.junit.Before;
10 | import org.junit.Test;
11 | import org.sonar.api.batch.fs.InputFile;
12 |
13 | import fr.univartois.sonargo.AbstractSonarTest;
14 | import fr.univartois.sonargo.TestUtils;
15 | import fr.univartois.sonargo.core.language.GoLanguage;
16 |
17 | public class ProjectExplorerTest extends AbstractSonarTest {
18 |
19 | @Before
20 | @Override
21 | public void init() {
22 | init(TestUtils.getProjectDir());
23 | }
24 |
25 | @Test
26 | public void testSearchByType() {
27 |
28 | List list = ProjectExplorer.searchByType(testerContext, InputFile.Type.MAIN);
29 | assertFalse(list.isEmpty());
30 | assertEquals(1, list.size());
31 | }
32 |
33 | @Test
34 | public void testSearchFileWithTypeMainOrTest() {
35 | List list = ProjectExplorer.searchFileWithTypeMainOrTest(testerContext);
36 | assertFalse(list.isEmpty());
37 | assertEquals(2, list.size());
38 | }
39 |
40 | @Test
41 | public void testGetByPath() {
42 | assertNotNull(ProjectExplorer.getByPath(testerContext, "package1.go"));
43 | assertNotNull(ProjectExplorer.getByPath(testerContext, "package1.go").language());
44 | assertEquals(GoLanguage.KEY, ProjectExplorer.getByPath(testerContext, "package1.go").language());
45 | }
46 |
47 | }
48 |
--------------------------------------------------------------------------------
/src/test/java/fr/univartois/sonargo/core/language/GoGrammarTest.java:
--------------------------------------------------------------------------------
1 | package fr.univartois.sonargo.core.language;
2 |
3 | import java.io.BufferedReader;
4 | import java.io.File;
5 | import java.io.FileReader;
6 | import java.io.IOException;
7 | import java.nio.file.Files;
8 | import java.util.ArrayList;
9 |
10 | import org.junit.Before;
11 | import org.junit.Test;
12 | import org.sonar.sslr.tests.ParserAssert;
13 |
14 | import com.sonar.sslr.api.Grammar;
15 | import com.sonar.sslr.api.Rule;
16 | import com.sonar.sslr.impl.Lexer;
17 | import com.sonar.sslr.impl.Parser;
18 | import com.sonar.sslr.impl.matcher.RuleDefinition;
19 |
20 | import fr.univartois.sonargo.coverage.CoverageSensor;
21 |
22 | public class GoGrammarTest {
23 | private Rule rule;
24 | private Parser parser;
25 | private ArrayList goCodes;
26 |
27 | @Before
28 | public void init() {
29 | Lexer lexer = GoLexer.create();
30 | rule = new RuleDefinition("ruleName").is("foo");
31 | Grammar grammar = GoGrammar.create();
32 | parser = Parser.builder(grammar).withLexer(lexer).build();
33 | goCodes = new ArrayList<>();
34 | try {
35 | parseGoCode();
36 | } catch (IOException e) {
37 | // TODO Auto-generated catch block
38 | e.printStackTrace();
39 | }
40 | }
41 |
42 | public void parseGoCode() throws IOException {
43 | Files.list(new File(CoverageSensor.class.getResource("/grammar").getFile()).toPath()).forEach(path -> {
44 | try {
45 | BufferedReader reader = new BufferedReader(new FileReader(path.toFile()));
46 | String sCurrentLine;
47 | StringBuilder sb = new StringBuilder();
48 | while ((sCurrentLine = reader.readLine()) != null) {
49 | sb.append(sCurrentLine + "\n");
50 | }
51 | goCodes.add(sb.toString());
52 | } catch (IOException e) {
53 | // TODO Auto-generated catch block
54 | e.printStackTrace();
55 | }
56 | });
57 |
58 | }
59 |
60 | @Test
61 | public void ok() {
62 | for (String s : goCodes) {
63 | System.out.println(s);
64 | new ParserAssert(parser).matches(s);
65 | }
66 | }
67 |
68 | }
69 |
--------------------------------------------------------------------------------
/src/test/java/fr/univartois/sonargo/core/language/GoLanguageTest.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright 2017 - Université d'Artois
3 | *
4 | * This file is part of SonarQube Golang plugin (sonar-golang).
5 | *
6 | * Sonar-golang is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU Lesser General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * Sonar-golang is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with Sonar-golang. If not, see .
18 | *
19 | * Contributors:
20 | * Thibault Falque (thibault_falque@ens.univ-artois.fr)
21 | *******************************************************************************/
22 | package fr.univartois.sonargo.core.language;
23 |
24 | import static org.junit.Assert.assertEquals;
25 | import static org.junit.Assert.assertFalse;
26 | import static org.junit.Assert.assertTrue;
27 |
28 | import java.util.Arrays;
29 |
30 | import org.junit.Test;
31 |
32 | import fr.univartois.sonargo.core.language.GoLanguage;
33 |
34 | public class GoLanguageTest {
35 |
36 | @Test
37 | public void test() {
38 | GoLanguage go = new GoLanguage();
39 | assertTrue(go.hasValidSuffixes("test.go"));
40 | assertFalse(go.hasValidSuffixes("test.xml"));
41 | String[] def = { "go" };
42 |
43 | assertEquals(Arrays.asList(def), Arrays.asList(go.getFileSuffixes()));
44 | }
45 |
46 | }
47 |
--------------------------------------------------------------------------------
/src/test/java/fr/univartois/sonargo/core/language/GoLexerTest.java:
--------------------------------------------------------------------------------
1 | package fr.univartois.sonargo.core.language;
2 |
3 | import static com.sonar.sslr.api.GenericTokenType.IDENTIFIER;
4 | import static com.sonar.sslr.test.lexer.LexerMatchers.hasToken;
5 | import static fr.univartois.sonargo.core.language.GoLexer.Literals.FLOAT;
6 | import static fr.univartois.sonargo.core.language.GoLexer.Literals.INTEGER;
7 | import static org.junit.Assert.assertThat;
8 | import static org.junit.Assert.assertTrue;
9 |
10 | import java.util.regex.Matcher;
11 | import java.util.regex.Pattern;
12 |
13 | import org.junit.Test;
14 |
15 | import com.sonar.sslr.impl.Lexer;
16 |
17 | public class GoLexerTest {
18 | Lexer lexer = GoLexer.create();
19 | private Pattern pattern;
20 | private Matcher matcher;
21 |
22 | @Test
23 | public void lexIdentifiers() {
24 | assertThat(lexer.lex("abc"), hasToken("abc", IDENTIFIER));
25 | assertThat(lexer.lex("abc0"), hasToken("abc0", IDENTIFIER));
26 | assertThat(lexer.lex("abc_0"), hasToken("abc_0", IDENTIFIER));
27 | assertThat(lexer.lex("i"), hasToken("i", IDENTIFIER));
28 | }
29 |
30 | @Test
31 | public void lexKeyword() {
32 | assertThat(lexer.lex("int"), hasToken("int", GoLexer.Keyword.INT));
33 | assertThat(lexer.lex("int32"), hasToken("int32", GoLexer.Keyword.INT32));
34 | assertThat(lexer.lex("int64"), hasToken("int64", GoLexer.Keyword.INT64));
35 | }
36 |
37 | @Test
38 | public void lexIntegers() {
39 |
40 | assertThat(lexer.lex("01"), hasToken("01", INTEGER));
41 | assertThat(lexer.lex("1"), hasToken("1", INTEGER));
42 | assertThat(lexer.lex("0x1F"), hasToken("0x1F", INTEGER));
43 | assertThat(lexer.lex("0x1e"), hasToken("0x1e", INTEGER));
44 | }
45 |
46 | @Test
47 | public void lexFloat() {
48 |
49 | final String[] array = { "0.", "72.40", "072.40", "2.71828", "1.e+0", "6.67428e-11", "1E6", ".25", ".12345E+5"
50 |
51 | };
52 |
53 | pattern = Pattern.compile(GoLexer.Literals.FLOAT.getValue());
54 | matcher = pattern.matcher("1.1");
55 | assertTrue(matcher.matches());
56 | matcher = pattern.matcher("1.0");
57 | assertTrue(matcher.matches());
58 | matcher = pattern.matcher("1.0e+10");
59 | assertTrue(matcher.matches());
60 | matcher = pattern.matcher("1.0e-10");
61 | assertTrue(matcher.matches());
62 | matcher = pattern.matcher("1.0E-10");
63 | assertTrue(matcher.matches());
64 | matcher = pattern.matcher("1.0E+10");
65 | assertTrue(matcher.matches());
66 | matcher = pattern.matcher("1e-10");
67 | assertTrue(matcher.matches());
68 | matcher = pattern.matcher("1e+10");
69 | assertTrue(matcher.matches());
70 | matcher = pattern.matcher(".1e+10");
71 | assertTrue(matcher.matches());
72 | matcher = pattern.matcher(".1e-10");
73 | assertTrue(matcher.matches());
74 | matcher = pattern.matcher(".1");
75 | assertTrue(matcher.matches());
76 |
77 | for (final String s : array) {
78 | matcher = pattern.matcher(s);
79 | assertTrue(matcher.matches());
80 | }
81 |
82 | assertThat(lexer.lex("1.0"), hasToken("1.0", FLOAT));
83 |
84 | }
85 |
86 | }
87 |
--------------------------------------------------------------------------------
/src/test/java/fr/univartois/sonargo/core/language/GoQualityProfileTest.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright 2017 - Université d'Artois
3 | *
4 | * This file is part of SonarQube Golang plugin (sonar-golang).
5 | *
6 | * Sonar-golang is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU Lesser General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * Sonar-golang is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with Sonar-golang. If not, see .
18 | *
19 | * Contributors:
20 | * Thibault Falque (thibault_falque@ens.univ-artois.fr)
21 | *******************************************************************************/
22 | package fr.univartois.sonargo.core.language;
23 |
24 | import static org.junit.Assert.assertEquals;
25 | import static org.junit.Assert.assertFalse;
26 | import static org.junit.Assert.assertTrue;
27 |
28 | import java.io.IOException;
29 | import java.util.Properties;
30 | import java.util.function.Predicate;
31 |
32 | import org.junit.Test;
33 | import org.sonar.api.profiles.RulesProfile;
34 | import org.sonar.api.rules.ActiveRule;
35 | import org.sonar.api.utils.ValidationMessages;
36 |
37 | import fr.univartois.sonargo.core.language.GoQualityProfile;
38 |
39 | public class GoQualityProfileTest {
40 | private GoQualityProfile goprofile = new GoQualityProfile();
41 |
42 | @Test
43 | public void testLoadingQualityProfile() {
44 |
45 | RulesProfile rule = goprofile.createProfile(ValidationMessages.create());
46 | assertFalse(rule.getActiveRules().isEmpty());
47 | Properties prop = new Properties();
48 |
49 | try {
50 | prop.load(GoQualityProfileTest.class.getResourceAsStream(GoQualityProfile.PROFILE_PATH));
51 | Predicate super Object> predicate = s -> Boolean.TRUE.equals(Boolean.parseBoolean((String) s));
52 | assertEquals(prop.values().stream().filter(predicate).count(), rule.getActiveRules().size());
53 |
54 | for (ActiveRule r : rule.getActiveRules()) {
55 | assertTrue(r.isEnabled());
56 | assertTrue(r.getRule().isEnabled());
57 | }
58 |
59 | } catch (IOException e) {
60 | e.printStackTrace();
61 | }
62 |
63 | assertTrue(rule.getDefaultProfile());
64 | }
65 |
66 | }
67 |
--------------------------------------------------------------------------------
/src/test/java/fr/univartois/sonargo/core/metrics/GoMetricSensorTest.java:
--------------------------------------------------------------------------------
1 | package fr.univartois.sonargo.core.metrics;
2 |
3 | import static org.junit.Assert.assertEquals;
4 | import static org.junit.Assert.assertNotNull;
5 |
6 | import java.util.Map;
7 |
8 | import org.junit.Before;
9 | import org.junit.Test;
10 | import org.sonar.api.measures.CoreMetrics;
11 | import org.sonar.api.measures.Metric;
12 |
13 | import fr.univartois.sonargo.AbstractSonarTest;
14 | import fr.univartois.sonargo.TestUtils;
15 |
16 | public class GoMetricSensorTest extends AbstractSonarTest {
17 | @Before
18 | @Override
19 | public void init() {
20 | init(TestUtils.getProjectDir());
21 | }
22 |
23 | @Test
24 | public void testExecute() {
25 | GoMetricSensor sensor = new GoMetricSensor();
26 | sensor.execute(testerContext);
27 | Map, Integer> measures = sensor.getMeasures();
28 | assertNotNull(measures);
29 | assertEquals(new Integer(7), measures.get(CoreMetrics.NCLOC));
30 | }
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/src/test/java/fr/univartois/sonargo/core/rules/EvalTest.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright 2017 - Université d'Artois
3 | *
4 | * This file is part of SonarQube Golang plugin (sonar-golang).
5 | *
6 | * Sonar-golang is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU Lesser General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * Sonar-golang is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with Sonar-golang. If not, see .
18 | *
19 | * Contributors:
20 | * Thibault Falque (thibault_falque@ens.univ-artois.fr)
21 | *******************************************************************************/
22 | package fr.univartois.sonargo.core.rules;
23 |
24 | import static org.jbehave.core.io.CodeLocations.codeLocationFromClass;
25 |
26 | import java.util.List;
27 |
28 | import org.jbehave.core.configuration.Configuration;
29 | import org.jbehave.core.configuration.MostUsefulConfiguration;
30 | import org.jbehave.core.io.StoryFinder;
31 | import org.jbehave.core.junit.JUnitStories;
32 | import org.jbehave.core.reporters.Format;
33 | import org.jbehave.core.reporters.StoryReporterBuilder;
34 | import org.jbehave.core.steps.InjectableStepsFactory;
35 | import org.jbehave.core.steps.InstanceStepsFactory;
36 | import org.junit.runner.RunWith;
37 |
38 | import de.codecentric.jbehave.junit.monitoring.JUnitReportingRunner;
39 |
40 | @RunWith(JUnitReportingRunner.class)
41 | public class EvalTest extends JUnitStories {
42 |
43 | public EvalTest() {
44 | configuredEmbedder().embedderControls().doGenerateViewAfterStories(false).doIgnoreFailureInStories(false)
45 | .doIgnoreFailureInView(false).doVerboseFailures(true);
46 | }
47 |
48 | @Override
49 | public Configuration configuration() {
50 | return new MostUsefulConfiguration()
51 | // CONSOLE reporting
52 | .useStoryReporterBuilder(new StoryReporterBuilder().withDefaultFormats().withFormats(Format.CONSOLE));
53 | }
54 |
55 | // Here we specify the steps classes
56 | @Override
57 | public InjectableStepsFactory stepsFactory() {
58 | // varargs, can have more that one steps classes
59 | return new InstanceStepsFactory(configuration(), new ReportEvalStoryTest());
60 | }
61 |
62 | @Override
63 | protected List storyPaths() {
64 | return new StoryFinder().findPaths(codeLocationFromClass(this.getClass()), "**/*.story", "**/excluded*.story");
65 | }
66 | }
--------------------------------------------------------------------------------
/src/test/java/fr/univartois/sonargo/core/rules/GoErrorTest.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright 2017 - Université d'Artois
3 | *
4 | * This file is part of SonarQube Golang plugin (sonar-golang).
5 | *
6 | * Sonar-golang is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU Lesser General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * Sonar-golang is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with Sonar-golang. If not, see .
18 | *
19 | * Contributors:
20 | * Thibault Falque (thibault_falque@ens.univ-artois.fr)
21 | *******************************************************************************/
22 | package fr.univartois.sonargo.core.rules;
23 |
24 | import static org.junit.Assert.assertEquals;
25 | import static org.junit.Assert.assertFalse;
26 | import static org.junit.Assert.assertTrue;
27 |
28 | import org.junit.Test;
29 |
30 | import fr.univartois.sonargo.core.rules.GoError;
31 |
32 | public class GoErrorTest {
33 |
34 | @Test
35 | public void testInitAndEqualityGoError() {
36 | GoError error = new GoError(10, "un message", "warning", "test.go");
37 | GoError error2 = new GoError(10, "un message", "warning", "test.go");
38 | GoError error3 = new GoError(10, "un message 2", "warning", "test.go");
39 | assertEquals(error.hashCode(), error2.hashCode());
40 | assertTrue(error.equals(error2));
41 | assertFalse(error.equals(error3));
42 | assertEquals(10, error.getLine());
43 | assertEquals("un message", error.getMessage());
44 | assertEquals("warning", error.getSeverity());
45 | assertEquals("test.go", error.getFilePath());
46 |
47 | assertEquals("GoError [line=10, message=un message, severity=warning, filePath=test.go]", error.toString());
48 |
49 | }
50 |
51 | }
52 |
--------------------------------------------------------------------------------
/src/test/java/fr/univartois/sonargo/core/rules/GoLintIssueLoaderSendorTest.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright 2017 - Université d'Artois
3 | *
4 | * This file is part of SonarQube Golang plugin (sonar-golang).
5 | *
6 | * Sonar-golang is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU Lesser General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * Sonar-golang is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with Sonar-golang. If not, see .
18 | *
19 | * Contributors:
20 | * Thibault Falque (thibault_falque@ens.univ-artois.fr)
21 | *******************************************************************************/
22 | package fr.univartois.sonargo.core.rules;
23 |
24 | import static org.junit.Assert.assertNotNull;
25 | import static org.mockito.Mockito.mock;
26 |
27 | import java.io.File;
28 |
29 | import org.junit.Before;
30 | import org.junit.Test;
31 | import org.sonar.api.batch.fs.internal.DefaultFileSystem;
32 | import org.sonar.api.batch.sensor.SensorDescriptor;
33 | import org.sonar.api.config.Settings;
34 |
35 | import fr.univartois.sonargo.core.rules.GoLintIssueLoaderSensor;
36 |
37 | public class GoLintIssueLoaderSendorTest {
38 | private DefaultFileSystem fileSystem;
39 | private GoLintIssueLoaderSensor sensor;
40 |
41 | @Before
42 | public void setUp() {
43 | fileSystem = new DefaultFileSystem((File) null);
44 | sensor = new GoLintIssueLoaderSensor(new Settings(), fileSystem);
45 | }
46 |
47 | @Test
48 | public void describe() {
49 | SensorDescriptor sensorDescriptor = mock(SensorDescriptor.class);
50 |
51 | assertNotNull(sensorDescriptor);
52 | assertNotNull(sensor);
53 |
54 | }
55 |
56 | }
57 |
--------------------------------------------------------------------------------
/src/test/java/fr/univartois/sonargo/core/rules/GoLintRulesDefinitionTest.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright 2017 - Université d'Artois
3 | *
4 | * This file is part of SonarQube Golang plugin (sonar-golang).
5 | *
6 | * Sonar-golang is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU Lesser General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * Sonar-golang is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with Sonar-golang. If not, see .
18 | *
19 | * Contributors:
20 | * Thibault Falque (thibault_falque@ens.univ-artois.fr)
21 | *******************************************************************************/
22 | package fr.univartois.sonargo.core.rules;
23 |
24 | import static org.junit.Assert.assertEquals;
25 | import static org.junit.Assert.assertNotNull;
26 |
27 | import org.junit.Test;
28 | import org.sonar.api.server.rule.RulesDefinition;
29 |
30 | import fr.univartois.sonargo.core.language.GoLanguage;
31 |
32 | public class GoLintRulesDefinitionTest {
33 | @Test
34 | public void testForVersion6() {
35 | GoLintRulesDefinition definition = new GoLintRulesDefinition();
36 | RulesDefinition.Context context = new RulesDefinition.Context();
37 | definition.define(context);
38 | RulesDefinition.Repository repository = context.repository(GoLintRulesDefinition.REPO_KEY);
39 |
40 | assertEquals(GoLintRulesDefinition.REPO_NAME, repository.name());
41 | assertEquals(GoLanguage.KEY, repository.language());
42 | GoKeyRule.init();
43 | assertEquals(GoKeyRule.getProp().size(), repository.rules().size());
44 |
45 | for (Object key : GoKeyRule.getProp().keySet()) {
46 | assertNotNull(repository.rule((String) key));
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/test/java/fr/univartois/sonargo/core/rules/ReportEvalStoryTest.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright 2017 - Université d'Artois
3 | *
4 | * This file is part of SonarQube Golang plugin (sonar-golang).
5 | *
6 | * Sonar-golang is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU Lesser General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * Sonar-golang is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with Sonar-golang. If not, see .
18 | *
19 | * Contributors:
20 | * Thibault Falque (thibault_falque@ens.univ-artois.fr)
21 | *******************************************************************************/
22 | package fr.univartois.sonargo.core.rules;
23 |
24 | import static org.hamcrest.CoreMatchers.equalTo;
25 | import static org.junit.Assert.assertThat;
26 |
27 | import org.jbehave.core.annotations.Given;
28 | import org.jbehave.core.annotations.Then;
29 | import org.jbehave.core.annotations.When;
30 |
31 | import fr.univartois.sonargo.core.rules.GoError;
32 | import fr.univartois.sonargo.core.rules.GoKeyRule;
33 |
34 | public class ReportEvalStoryTest {
35 | private String eval;
36 |
37 | @Given("Given a Key finder")
38 | public void newInterpreter() {
39 | GoKeyRule.init();
40 | }
41 |
42 | @When("the expression entered is $expression")
43 | public void eval(String expression) {
44 | eval = GoKeyRule.getKeyFromError(new GoError(10, expression, null, null));
45 |
46 | }
47 |
48 | @Then("the result should be $expectedValue")
49 | public void checkValue(String expectedValue) {
50 | assertThat(String.valueOf(eval), equalTo(expectedValue));
51 | System.out.println(String.valueOf(eval));
52 | }
53 |
54 | }
55 |
--------------------------------------------------------------------------------
/src/test/java/fr/univartois/sonargo/core/rules/expression.story:
--------------------------------------------------------------------------------
1 | Some expression violation
2 |
3 | Narrative:
4 | Our plugin should be able to
5 | find a key for message.
6 |
7 | Scenario: find key of message
8 |
9 | Given Given a Key finder
10 |
11 | When the expression entered is
12 | Then the result should be
13 |
14 | Examples:
15 |
16 | |expression |result|
17 | |exported type Foo should have comment or be unexported|golint:ExportedHaveComment|
18 | |comment on exported type Foo should be of the form "Foo ..."|golint:FormComment|
19 | |comment on exported type Foo should be of the form "Foo..."|golint:FormComment|
20 | |comment on exported method Foo.Bar should be of the form "Foo.Bar ..."|golint:FormComment|
21 | |don't use ALL_CAPS in Go names; use CamelCase|golint:AllCaps|
22 | |don't use an underscore in package name|golint:UnderscoreInPackageName|
23 | |don't use leading k in Go names; var kFoo should be Foo|golint:LeadingK|
24 | |don't use underscores in Go names; var foo_bar should be fooBar|golint:UnderscoreInGoName|
25 | |error should be the last type when returning multiple items|golint:ErrorLastReturn|
26 | |error strings should not be capitalized or end with punctuation or a newline|golint:ErrorEndString|
27 | |error var err should have name of the form errFo|golint:ErrorVarName|
28 | |exported method FooMethod returns unexported type unexportedType, which can be annoying to use|golint:AnnoyingUseExportedType|
29 | |if block ends with a return statement, so drop this else and outdent its block|golint:IfBlockReturn|
30 | |package comment should be of the form "Package..."|golint:PackageCommentForm|
31 | |package comment should not have leading space|golint:PackageCommentSpace|
32 | |receiver name a should be consistent with previous receiver name b for bar|golint:ReceiverNameConsistent|
33 | |receiver name should be a reflection of its identity; don't use generic names such as "this" or "self"|golint:ReceiverNameReflection|
34 | |receiver name should not be an underscore|golint:ReceiverNameNotUnderscore|
35 | |should drop = 0 from declaration of var myZeroInt; it is the zero value|golint:DropAssignment|
36 | |should drop = nil from declaration of var myPtr; it is the zero value|golint:DropAssignment|
37 | |should have a package comment, unless it's in another file for this package|golint:HavePackageComment|
38 | |should not use basic type int8 as key in context.WithValue|golint:NotUseBasicType|
39 | |should not use basic type int16 as key in context.WithValue|golint:NotUseBasicType|
40 | |should not use basic type int32 as key in context.WithValue|golint:NotUseBasicType|
41 | |should not use basic type uint8 as key in context.WithValue|golint:NotUseBasicType|
42 | |should not use basic type uintptr as key in context.WithValue|golint:NotUseBasicType|
43 | |should not use dot imports|golint:NotUseDotImport|
44 | |should omit 2nd value from range; this loop is equivalent to `for x := range ...`|golint:Omit2ndValueFromRange|
45 | |should omit type int from declaration of var myZeroInt; it will be inferred from the right-hand side|golint:OmitType|
46 | |should replace x=x+1 with x++|golint:ReplaceLintIncDec|
47 | |should replace t.Errorf(fmt.Sprintf(...)) with t.Errorf(...)|golint:ReplaceSprintf|
48 | |var Serverhttp should be ServerHTTP|golint:Initialisms|
49 | |func name will be used as foo.FooMulti by other packages, and that stutters; consider calling this Multi|golint:PackageNames|
50 | |a blank import should be only in a main or test package, or have a comment justifying it|golint:BlankImport|
51 | |comment on exported type Foo should be of the form "Foo ..." (with optional leading article)|golint:CommentExportedType|
52 | |context.Context should be the first parameter of a function|golint:ContextContextFirstArg|
53 | |exported method FooMethod should have comment or be unexported|golint:ExportedHaveComment|
54 | |exported const FooType should have comment (or a comment on this block) or be unexported|golint:ExportedHaveComment2|
55 | |exported const Hello4 should have its own declaration|golint:ExportedDeclaration|//more info https://github.com/go-lang-plugin-org/go-lang-idea-plugin/issues/2049
56 | |var timeoutSecs is of type time.Second; don't use unit-specific suffix Secs|golint:SpecificSuffix|
57 | |cyclomatic complexity 11 of function main() is high (> 10)|gocyclo:CyclomaticComplexity|
58 | |error return value not checked (os.MkdirAll("./tmp/build", os.FileMode(0755)))|errcheck:ValueNotChecked|
59 | |error return value not checked (util.Save(jpegimage.(*image.NRGBA), "png_"+nameWithoutExtension+".png"))|errcheck:ValueNotChecked|
60 | |error return value not checked (route(r))|errcheck:ValueNotChecked|
61 | |error return value not checked (core.NewConfiguration(ConfigName, ConfigPath).ReadInConfig())|errcheck:ValueNotChecked|
62 | |unnecessary conversion|unconvert:UnnecessaryConversion|
63 | |unused struct field projectblackwhitego.ImageService.req|structcheck:UnusedStructField|
64 | |exported method BaseGS1.CodingSet should have comment or be unexported|golint:ExportedHaveComment|
65 | |exported method Rule.CodingSet should have comment or be unexported|golint:ExportedHaveComment|
66 | |struct field Id should be ID|golint:StructFieldInitialisms|
67 | |unreachable code|vet:Unreachable|
68 | |declaration of "configuration" shadows declaration at line.go:142|vet:Shadow|
69 | |declaration of "err" shadows declaration at tcp_client_test.go:155|vet:Shadow|
70 | |possible misuse of unsafe.Pointer|vet:Misuse|
71 | |NotificationEventsHandler passes lock by value: sync.WaitGroup contains sync.noCopy|vet:Lock|
72 | |a message error not found|null|
--------------------------------------------------------------------------------
/src/test/java/fr/univartois/sonargo/core/settings/GoPropertiesTest.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright 2017 - Université d'Artois
3 | *
4 | * This file is part of SonarQube Golang plugin (sonar-golang).
5 | *
6 | * Sonar-golang is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU Lesser General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * Sonar-golang is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with Sonar-golang. If not, see .
18 | *
19 | * Contributors:
20 | * Thibault Falque (thibault_falque@ens.univ-artois.fr)
21 | *******************************************************************************/
22 | package fr.univartois.sonargo.core.settings;
23 |
24 | import static org.junit.Assert.assertEquals;
25 |
26 | import java.util.List;
27 |
28 | import org.junit.Test;
29 | import org.sonar.api.config.PropertyDefinition;
30 |
31 | public class GoPropertiesTest {
32 |
33 | @Test
34 | public void test() {
35 | List l = GoProperties.getProperties();
36 | assertEquals(5, l.size());
37 | assertEquals(GoProperties.REPORT_PATH_DEFAULT, l.get(0).defaultValue());
38 | assertEquals(GoProperties.COVERAGE_REPORT_PATH_DEFAULT, l.get(1).defaultValue());
39 | assertEquals(GoProperties.JUNIT_REPORT_PATH_DEFAULT, l.get(2).defaultValue());
40 |
41 | }
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/src/test/java/fr/univartois/sonargo/coverage/CoverageSensorTest.java:
--------------------------------------------------------------------------------
1 | package fr.univartois.sonargo.coverage;
2 |
3 | import static org.junit.Assert.assertEquals;
4 | import static org.junit.Assert.assertNotNull;
5 | import static org.junit.Assert.assertTrue;
6 |
7 | import java.io.BufferedReader;
8 | import java.io.File;
9 | import java.io.FileNotFoundException;
10 | import java.io.FileReader;
11 | import java.io.IOException;
12 | import java.nio.file.Path;
13 | import java.nio.file.Paths;
14 | import java.util.HashMap;
15 | import java.util.Map;
16 | import java.util.stream.Stream;
17 |
18 | import org.junit.Before;
19 | import org.junit.Test;
20 | import org.sonar.api.batch.fs.internal.DefaultInputFile;
21 | import org.sonar.api.batch.sensor.coverage.CoverageType;
22 | import org.sonar.api.utils.log.Logger;
23 | import org.sonar.api.utils.log.Loggers;
24 |
25 | import com.google.common.collect.ImmutableMap;
26 |
27 | import fr.univartois.sonargo.AbstractSonarTest;
28 | import fr.univartois.sonargo.TestUtils;
29 | import fr.univartois.sonargo.core.language.GoLanguage;
30 |
31 | public class CoverageSensorTest extends AbstractSonarTest {
32 | private static final Logger LOGGER = Loggers.get(CoverageSensorTest.class);
33 |
34 | @Before
35 | @Override
36 | public void init() {
37 | init(TestUtils.getCoverageBaseDir());
38 | }
39 |
40 | @Test
41 | public void testCreateStream() {
42 | final CoverageSensor sensor = new CoverageSensor();
43 | try (Stream paths = sensor.createStream(testerContext)) {
44 |
45 | assertNotNull(paths);
46 |
47 | } catch (final IOException e) {
48 | // TODO Auto-generated catch block
49 | e.printStackTrace();
50 | }
51 | }
52 |
53 | @Test
54 | public void testExcludedPathProperty() {
55 | final CoverageSensor sensor = new CoverageSensor();
56 | boolean check = sensor.isAnExcludedPath(Paths.get(fileSystem.baseDir().getAbsolutePath(), "vendor/test"),
57 | testerContext);
58 | assertTrue(check);
59 | }
60 |
61 | @Test
62 | public void testIgnoreFileStream() {
63 | final CoverageSensor sensor = new CoverageSensor();
64 | Stream paths;
65 | try {
66 | paths = sensor.createStream(testerContext);
67 | assertEquals(33, paths.count());
68 |
69 | } catch (IOException e) {
70 | // TODO Auto-generated catch block
71 | e.printStackTrace();
72 | }
73 |
74 | }
75 |
76 | private void initFile() {
77 | String[] listFile = { "util/util.go", "mathutil/mathutil.go", "pixel/pixel.go",
78 | "mathutil/filewithnocoverage.go", "issue60/a.go", "issue61/simplelinecomment.go",
79 | "issue61/multilinecomment.go", "issue61/typestruct.go" };
80 |
81 | BufferedReader reader;
82 | try {
83 |
84 | for (int i = 0; i < listFile.length; i++) {
85 | System.out.println(listFile[i]);
86 | reader = new BufferedReader(new FileReader(
87 | new File(CoverageSensor.class.getResource("/coverage/" + listFile[i]).getFile())));
88 |
89 | String sCurrentLine;
90 |
91 | StringBuilder sb = new StringBuilder();
92 | while ((sCurrentLine = reader.readLine()) != null) {
93 | sb.append(sCurrentLine + "\n");
94 | }
95 |
96 | testerContext.fileSystem().add(new DefaultInputFile("myProjectKey", listFile[i])
97 | .setLanguage(GoLanguage.KEY).initMetadata(sb.toString()));
98 |
99 | }
100 |
101 | } catch (FileNotFoundException e) {
102 | // TODO Auto-generated catch block
103 | e.printStackTrace();
104 | } catch (IOException e) {
105 | // TODO Auto-generated catch block
106 | e.printStackTrace();
107 | }
108 | }
109 |
110 | @Test
111 | public void testExecution() {
112 | final CoverageSensor sensor = new CoverageSensor();
113 | initFile();
114 | sensor.execute(testerContext);
115 |
116 | Map> map = new HashMap<>();
117 | map.put("myProjectKey:mathutil/mathutil.go", ImmutableMap.of(7, 1));
118 | map.put("myProjectKey:pixel/pixel.go", ImmutableMap.of(21, 0, 37, 0));
119 |
120 | Map testValuesMap = new HashMap<>();
121 |
122 | testValuesMap.put(3, null);
123 | testValuesMap.put(1, null);
124 | testValuesMap.put(4, null);
125 | testValuesMap.put(8, 0);
126 | testValuesMap.put(12, 0);
127 |
128 | map.put("myProjectKey:mathutil/filewithnocoverage.go", testValuesMap);
129 | map.put("myProjectKey:issue60/a.go", ImmutableMap.of(8, 0, 9, 0));
130 | Map testValuesMap2 = new HashMap<>();
131 | testValuesMap2.put(1, null);
132 | testValuesMap2.put(2, null);
133 | testValuesMap2.put(3, null);
134 | testValuesMap2.put(4, null);
135 | testValuesMap2.put(5, null);
136 | testValuesMap2.put(6, null);
137 | testValuesMap2.put(8, 0);
138 | testValuesMap2.put(9, 0);
139 | testValuesMap2.put(11, null);
140 | map.put("myProjectKey:issue61/simplelinecomment.go", testValuesMap2);
141 |
142 | Map testValuesMap3 = new HashMap<>();
143 |
144 | for (int i = 1; i <= 20; i++) {
145 | testValuesMap3.put(i, null);
146 | }
147 | testValuesMap3.put(26, null);
148 | testValuesMap3.put(27, null);
149 | testValuesMap3.put(28, null);
150 | testValuesMap3.put(30, 0);
151 | testValuesMap3.put(31, 0);
152 |
153 | map.put("myProjectKey:issue61/multilinecomment.go", testValuesMap3);
154 |
155 | Map testValuesMap4 = new HashMap<>();
156 | for (int i = 6; i <= 48; i++) {
157 | testValuesMap4.put(i, null);
158 | }
159 | map.put("myProjectKey:issue61/typestruct.go", testValuesMap4);
160 | map.forEach((key, mapValue) -> {
161 | mapValue.forEach((line, value) -> {
162 | assertEquals("line " + line + " " + key, value, testerContext.lineHits(key, CoverageType.UNIT, line));
163 | });
164 | });
165 |
166 | }
167 |
168 | }
169 |
--------------------------------------------------------------------------------
/src/test/java/fr/univartois/sonargo/gotest/FunctionFinderTest.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package fr.univartois.sonargo.gotest;
5 |
6 | import static org.junit.Assert.assertEquals;
7 | import static org.junit.Assert.assertTrue;
8 |
9 | import java.io.File;
10 | import java.nio.file.Paths;
11 | import java.util.Map;
12 | import java.util.Set;
13 |
14 | import org.junit.Before;
15 | import org.junit.Test;
16 | import org.sonar.api.utils.log.Logger;
17 | import org.sonar.api.utils.log.Loggers;
18 |
19 | import fr.univartois.sonargo.AbstractSonarTest;
20 | import fr.univartois.sonargo.TestUtils;
21 |
22 | /**
23 | * @author thibault
24 | *
25 | */
26 | public class FunctionFinderTest extends AbstractSonarTest {
27 | private static final Logger LOGGER = Loggers.get(FunctionFinderTest.class);
28 |
29 | @Before
30 | @Override
31 | public void init() {
32 | init(TestUtils.getTestBaseDir());
33 | }
34 |
35 | @Test
36 | public void testSearchInFile() {
37 | String path = new File(TestUtils.getTestBaseDir().baseDir(), "test_test.go").getAbsolutePath();
38 | LOGGER.info("testSearchInFile " + path);
39 | FunctionFinder f = new FunctionFinder(testerContext);
40 | f.searchFunctionInFile(Paths.get(path));
41 | Map result = f.getResult();
42 | Set expected = new java.util.HashSet();
43 | expected.add("TestEasyDef");
44 | expected.add("TestSpaceDef");
45 | expected.add("TestNoSpaceDef");
46 | expected.add("TestTwoLines1");
47 | expected.add("TestTwoLines2");
48 | expected.add("TestNested");
49 | expected.add("TestSuite");
50 | assertEquals(expected, result.keySet());
51 |
52 | }
53 |
54 | @Test
55 | public void testSearchFunction() {
56 | LOGGER.info("testSearchFunction " + testerContext.fileSystem().baseDir());
57 | FunctionFinder f = new FunctionFinder(testerContext);
58 | Map nameFunction = f.searchFunction();
59 |
60 | assertTrue(nameFunction.containsKey("TestAverage"));
61 |
62 | }
63 |
64 | }
65 |
--------------------------------------------------------------------------------
/src/test/java/fr/univartois/sonargo/highlighter/ColorizerTest.java:
--------------------------------------------------------------------------------
1 | package fr.univartois.sonargo.highlighter;
2 |
3 | import static org.junit.Assert.assertEquals;
4 | import static org.junit.Assert.assertFalse;
5 |
6 | import java.io.File;
7 | import java.nio.charset.StandardCharsets;
8 | import java.util.List;
9 |
10 | import org.junit.Before;
11 | import org.junit.Test;
12 | import org.sonar.api.batch.fs.internal.DefaultInputFile;
13 | import org.sonar.api.batch.fs.internal.FileMetadata;
14 | import org.sonar.api.batch.sensor.highlighting.TypeOfText;
15 |
16 | import fr.univartois.sonargo.AbstractSonarTest;
17 | import fr.univartois.sonargo.TestUtils;
18 |
19 | public class ColorizerTest extends AbstractSonarTest {
20 | private File file;
21 | private DefaultInputFile inputFile;
22 |
23 | @Override
24 | @Before
25 | public void init() {
26 | init(TestUtils.getColorizeDir());
27 |
28 | file = new File(testerContext.fileSystem().baseDir(), "/test.go");
29 | inputFile = new DefaultInputFile("moduleKey", file.getName())
30 | .initMetadata(new FileMetadata().readMetadata(file, StandardCharsets.UTF_8));
31 |
32 | testerContext.fileSystem().add(inputFile);
33 | }
34 |
35 | @Test
36 | public void testColorize() {
37 |
38 | file = new File(testerContext.fileSystem().baseDir(), "/test.go");
39 | inputFile = new DefaultInputFile("moduleKey", file.getName())
40 | .initMetadata(new FileMetadata().readMetadata(file, StandardCharsets.UTF_8));
41 |
42 | testerContext.fileSystem().add(inputFile);
43 |
44 | final Colorizer c = new Colorizer(testerContext);
45 | c.colorize(inputFile);
46 | final String componentKey = "moduleKey:" + file.getName();
47 |
48 | assertEquals(TypeOfText.KEYWORD, testerContext.highlightingTypeAt(componentKey, 1, 1).get(0));
49 | assertEquals(TypeOfText.KEYWORD, testerContext.highlightingTypeAt(componentKey, 3, 3).get(0));
50 | }
51 |
52 | @Test
53 | public void testBug1() {
54 |
55 | file = new File(testerContext.fileSystem().baseDir(), "/testbug1.go");
56 | inputFile = new DefaultInputFile("moduleKey", file.getName())
57 | .initMetadata(new FileMetadata().readMetadata(file, StandardCharsets.UTF_8));
58 |
59 | testerContext.fileSystem().add(inputFile);
60 |
61 | final Colorizer c = new Colorizer(testerContext);
62 | c.colorize(inputFile);
63 |
64 | checkOnRange(1, 0, 3, TypeOfText.KEYWORD); // var
65 | checkOnRange(1, 13, 6, TypeOfText.KEYWORD); // string
66 | checkOnRange(1, 23, 12, TypeOfText.STRING); // "test\"other"
67 |
68 | }
69 |
70 | private void checkOnRange(int line, int start, int length, TypeOfText typeOfText) {
71 | final String componentKey = "moduleKey:" + file.getName();
72 |
73 | List found;
74 |
75 | for (int column = start; column < start + length; column++) {
76 | System.out.println(line + " " + column);
77 | found = testerContext.highlightingTypeAt(componentKey, line, column);
78 | assertFalse(found.isEmpty());
79 | assertEquals(typeOfText, found.get(0));
80 | }
81 |
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/src/test/resources/coverage/.ignoredfile:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uartois/sonar-golang/c57c5baba1b546642bfdf56d6be8d4ef06edcbf8/src/test/resources/coverage/.ignoredfile
--------------------------------------------------------------------------------
/src/test/resources/coverage/.sonar/test:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uartois/sonar-golang/c57c5baba1b546642bfdf56d6be8d4ef06edcbf8/src/test/resources/coverage/.sonar/test
--------------------------------------------------------------------------------
/src/test/resources/coverage/issue60/a.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | )
6 |
7 | func main() {
8 | foo()
9 | fmt.Println("vim-go")
10 | }
--------------------------------------------------------------------------------
/src/test/resources/coverage/issue61/multilinecomment.go:
--------------------------------------------------------------------------------
1 | /*
2 | Exemple from: https://golang.org/doc/effective_go.html#commentary
3 | Package regexp implements a simple library for regular expressions.
4 |
5 | The syntax of the regular expressions accepted is:
6 |
7 | regexp:
8 | concatenation { '|' concatenation }
9 | concatenation:
10 | { closure }
11 | closure:
12 | term [ '*' | '+' | '?' ]
13 | term:
14 | '^'
15 | '$'
16 | '.'
17 | character
18 | '[' [ '^' ] character-ranges ']'
19 | '(' regexp ')'
20 | */
21 | package regexp
22 |
23 | import (
24 | "fmt"
25 | )
26 | /* Compile parses a regular expression and returns, if successful,
27 | a Regexp that can be used to match against text.
28 | */
29 | func Compile(str string) (*Regexp, error) {func main() {
30 | foo()
31 | fmt.Println("vim-go")
32 | }
33 |
34 |
--------------------------------------------------------------------------------
/src/test/resources/coverage/issue61/simplelinecomment.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | )
6 | //a simle line comment
7 | func main() {
8 | foo()
9 | fmt.Println("vim-go")
10 | }
11 | //a simle line comment
12 | func secondFunction(){
13 | test();
14 | }
--------------------------------------------------------------------------------
/src/test/resources/coverage/issue61/typestruct.go:
--------------------------------------------------------------------------------
1 | package issue61
2 |
3 | func main(){
4 |
5 | }
6 | // An empty struct.
7 | struct {}
8 |
9 | // A struct with 6 fields.
10 | struct {
11 | x, y int
12 | u float32
13 | _ float32 // padding
14 | A *[]int
15 | F func()
16 | }
17 |
18 | interface {
19 | Read(b Buffer) bool
20 | Write(b Buffer) bool
21 | Close()
22 | }
23 |
24 | // A struct with 6 fields.
25 | type test struct {
26 | x, y int
27 | u float32
28 | _ float32 // padding
29 | A *[]int
30 | }
31 |
32 |
33 | type ReadWriter interface {
34 | Read(b Buffer) bool
35 | Write(b Buffer) bool
36 | }
37 |
38 | type File interface {
39 | ReadWriter // same as adding the methods of ReadWriter
40 | Locker // same as adding the methods of Locker
41 | Close()
42 | }
43 |
44 | type LockedFile interface {
45 | Locker
46 | File // illegal: Lock, Unlock not unique
47 | Lock() // illegal: Lock not unique
48 | }
--------------------------------------------------------------------------------
/src/test/resources/coverage/mathutil/coverage.out:
--------------------------------------------------------------------------------
1 | mode: set
2 | projectblackwhitego/mathutil/mathutil.go:6.34,8.2 1 1
3 |
--------------------------------------------------------------------------------
/src/test/resources/coverage/mathutil/coverage.out.xml:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uartois/sonar-golang/c57c5baba1b546642bfdf56d6be8d4ef06edcbf8/src/test/resources/coverage/mathutil/coverage.out.xml
--------------------------------------------------------------------------------
/src/test/resources/coverage/mathutil/coverage.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/src/test/resources/coverage/mathutil/filewithnocoverage.go:
--------------------------------------------------------------------------------
1 | package mathutil
2 |
3 |
4 | import "math"
5 |
6 |
7 | func function(){
8 | return 1;
9 | }
10 |
11 | func SqrtUint32(x uint32) uint32 {
12 | return uint32(math.Ceil(math.Sqrt(float64(x))))
13 | }
--------------------------------------------------------------------------------
/src/test/resources/coverage/mathutil/mathutil.go:
--------------------------------------------------------------------------------
1 | package mathutil
2 |
3 | import "math"
4 |
5 | //SqrtUint32 Permet de faire une racine carré sur un uint32
6 | func SqrtUint32(x uint32) uint32 {
7 | return uint32(math.Ceil(math.Sqrt(float64(x))))
8 | }
9 |
--------------------------------------------------------------------------------
/src/test/resources/coverage/mathutil/mathutil_test.go:
--------------------------------------------------------------------------------
1 | package mathutil
2 |
3 | import (
4 | "math"
5 | "testing"
6 | )
7 |
8 | func TestSqrtUint32(t *testing.T) {
9 | result1 := SqrtUint32(4)
10 | result2 := math.Sqrt(4.0)
11 |
12 | if uint32(result2) != result1 {
13 | t.Error(
14 | "For 4 and 4.0",
15 | "expected ", 2,
16 | "got", result1,
17 | )
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/test/resources/coverage/pixel/coverage.out:
--------------------------------------------------------------------------------
1 | mode: set
2 | projectblackwhitego/pixel/pixel.go:20.41,22.2 1 0
3 | projectblackwhitego/pixel/pixel.go:23.56,26.2 2 0
4 | projectblackwhitego/pixel/pixel.go:27.49,34.2 1 0
5 | projectblackwhitego/pixel/pixel.go:36.47,38.2 1 0
6 |
--------------------------------------------------------------------------------
/src/test/resources/coverage/pixel/coverage.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
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 |
--------------------------------------------------------------------------------
/src/test/resources/coverage/pixel/pixel.go:
--------------------------------------------------------------------------------
1 | package pixel
2 |
3 | import (
4 | "image"
5 | "image/color"
6 | "projectblackwhitego/util"
7 | )
8 |
9 | type Pixel struct {
10 | R uint32
11 | G uint32
12 | B uint32
13 | A uint32
14 | }
15 |
16 | type PixelImage struct {
17 | imageRGBA *image.Image
18 | }
19 |
20 | func NewPixel(r, g, b, a uint32) *Pixel {
21 | return &Pixel{r, g, b, a}
22 | }
23 | func NewPixelImage(bounds image.Rectangle) *PixelImage {
24 | img := image.Image(image.NewNRGBA(bounds))
25 | return &PixelImage{&img}
26 | }
27 | func (pi *PixelImage) Set(x, y int, pix *Pixel) {
28 | (*pi.imageRGBA).(*image.NRGBA).Set(x, y, color.NRGBA{
29 | util.Uint32toUint8(pix.R),
30 | util.Uint32toUint8(pix.G),
31 | util.Uint32toUint8(pix.B),
32 | util.Uint32toUint8(pix.A),
33 | })
34 | }
35 |
36 | func (pi *PixelImage) GetImage() *image.Image {
37 | return pi.imageRGBA
38 | }
39 |
--------------------------------------------------------------------------------
/src/test/resources/coverage/pixel/pixel_test.go:
--------------------------------------------------------------------------------
1 | package pixel
2 |
--------------------------------------------------------------------------------
/src/test/resources/coverage/test:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uartois/sonar-golang/c57c5baba1b546642bfdf56d6be8d4ef06edcbf8/src/test/resources/coverage/test
--------------------------------------------------------------------------------
/src/test/resources/coverage/test.git/test:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uartois/sonar-golang/c57c5baba1b546642bfdf56d6be8d4ef06edcbf8/src/test/resources/coverage/test.git/test
--------------------------------------------------------------------------------
/src/test/resources/coverage/util/cover.out:
--------------------------------------------------------------------------------
1 | mode: set
2 | projectblackwhitego/util/util.go:30.33,31.11 1 0
3 | projectblackwhitego/util/util.go:32.2,33.16 1 0
4 | projectblackwhitego/util/util.go:34.2,35.15 1 0
5 | projectblackwhitego/util/util.go:36.2,37.15 1 0
6 | projectblackwhitego/util/util.go:38.2,39.16 1 0
7 | projectblackwhitego/util/util.go:40.2,41.15 1 0
8 | projectblackwhitego/util/util.go:42.2,43.23 1 0
9 | projectblackwhitego/util/util.go:53.24,54.11 1 1
10 | projectblackwhitego/util/util.go:57.2,57.10 1 0
11 | projectblackwhitego/util/util.go:54.11,56.3 1 1
12 | projectblackwhitego/util/util.go:61.24,62.11 1 1
13 | projectblackwhitego/util/util.go:65.2,65.10 1 1
14 | projectblackwhitego/util/util.go:62.11,64.3 1 0
15 | projectblackwhitego/util/util.go:68.38,70.2 1 0
16 | projectblackwhitego/util/util.go:73.61,75.32 1 1
17 | projectblackwhitego/util/util.go:79.2,82.25 4 1
18 | projectblackwhitego/util/util.go:91.2,91.14 1 1
19 | projectblackwhitego/util/util.go:75.32,77.3 1 0
20 | projectblackwhitego/util/util.go:82.25,83.26 1 1
21 | projectblackwhitego/util/util.go:83.26,86.37 3 1
22 | projectblackwhitego/util/util.go:86.37,88.5 1 0
23 | projectblackwhitego/util/util.go:95.49,97.16 2 1
24 | projectblackwhitego/util/util.go:100.2,101.17 2 1
25 | projectblackwhitego/util/util.go:105.2,105.17 1 1
26 | projectblackwhitego/util/util.go:97.16,99.3 1 0
27 | projectblackwhitego/util/util.go:101.17,103.3 1 0
28 | projectblackwhitego/util/util.go:108.54,110.2 1 0
29 | projectblackwhitego/util/util.go:131.68,133.16 2 0
30 | projectblackwhitego/util/util.go:162.2,162.12 1 0
31 | projectblackwhitego/util/util.go:134.2,136.42 2 0
32 | projectblackwhitego/util/util.go:145.3,145.18 1 0
33 | projectblackwhitego/util/util.go:151.2,152.27 1 0
34 | projectblackwhitego/util/util.go:153.2,154.57 1 0
35 | projectblackwhitego/util/util.go:155.2,156.87 1 0
36 | projectblackwhitego/util/util.go:157.2,158.27 1 0
37 | projectblackwhitego/util/util.go:159.2,160.29 1 0
38 | projectblackwhitego/util/util.go:136.42,137.22 1 0
39 | projectblackwhitego/util/util.go:137.22,143.5 1 0
40 | projectblackwhitego/util/util.go:145.18,147.4 1 0
41 | projectblackwhitego/util/util.go:147.4,149.4 1 0
42 | projectblackwhitego/util/util.go:167.57,180.9 4 0
43 | projectblackwhitego/util/util.go:184.2,185.16 2 0
44 | projectblackwhitego/util/util.go:188.2,190.33 2 0
45 | projectblackwhitego/util/util.go:180.9,182.3 1 0
46 | projectblackwhitego/util/util.go:185.16,187.3 1 0
47 | projectblackwhitego/util/util.go:193.40,195.16 2 0
48 | projectblackwhitego/util/util.go:198.2,198.24 1 0
49 | projectblackwhitego/util/util.go:201.2,201.18 1 0
50 | projectblackwhitego/util/util.go:195.16,197.3 1 0
51 | projectblackwhitego/util/util.go:198.24,200.3 1 0
52 | projectblackwhitego/util/util.go:204.39,206.16 2 0
53 | projectblackwhitego/util/util.go:209.2,211.16 3 0
54 | projectblackwhitego/util/util.go:214.2,214.29 1 0
55 | projectblackwhitego/util/util.go:220.2,220.12 1 0
56 | projectblackwhitego/util/util.go:206.16,208.3 1 0
57 | projectblackwhitego/util/util.go:211.16,213.3 1 0
58 | projectblackwhitego/util/util.go:214.29,216.17 2 0
59 | projectblackwhitego/util/util.go:216.17,218.4 1 0
60 |
--------------------------------------------------------------------------------
/src/test/resources/coverage/util/coverage.out.xml:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uartois/sonar-golang/c57c5baba1b546642bfdf56d6be8d4ef06edcbf8/src/test/resources/coverage/util/coverage.out.xml
--------------------------------------------------------------------------------
/src/test/resources/coverage/util/coverage.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
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 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
--------------------------------------------------------------------------------
/src/test/resources/coverage/util/util.go:
--------------------------------------------------------------------------------
1 | package util
2 |
3 | import (
4 | "errors"
5 | "image"
6 | "image/gif"
7 | "image/jpeg"
8 | "image/png"
9 | "io"
10 | "os"
11 | "path/filepath"
12 | "strings"
13 |
14 | "golang.org/x/image/bmp"
15 | "golang.org/x/image/tiff"
16 | )
17 |
18 | // Format is an image file format.
19 | type Format int
20 |
21 | // Image file formats.
22 | const (
23 | JPEG Format = iota
24 | PNG
25 | GIF
26 | TIFF
27 | BMP
28 | )
29 |
30 | func (f Format) String() string {
31 | switch f {
32 | case JPEG:
33 | return "JPEG"
34 | case PNG:
35 | return "PNG"
36 | case GIF:
37 | return "GIF"
38 | case TIFF:
39 | return "TIFF"
40 | case BMP:
41 | return "BMP"
42 | default:
43 | return "Unsupported"
44 | }
45 | }
46 |
47 | var (
48 | // ErrUnsupportedFormat means the given image format (or file extension) is unsupported.
49 | ErrUnsupportedFormat = errors.New("imaging: unsupported image format")
50 | )
51 |
52 | func falseSquare(a int) int {
53 | return a
54 | }
55 |
56 | //Min retourne le min
57 | func Min(a, b int) int {
58 | if a < b {
59 | return a
60 | }
61 | return b
62 | }
63 |
64 | //Max retourne le max
65 | func Max(a, b int) int {
66 | if a > b {
67 | return a
68 | }
69 | return b
70 | }
71 |
72 | func Uint32toUint8(val uint32) uint8 {
73 | return uint8(val >> 8)
74 | }
75 |
76 | //CompareImage calcule le nombre de pixel de différence entre deux images
77 | func CompareImage(img1 *image.Image, img2 *image.Image) int {
78 |
79 | if img1 == nil || img2 == nil {
80 | return -1
81 | }
82 |
83 | w := (*img1).Bounds().Dx()
84 | h := (*img1).Bounds().Dy()
85 | var count int
86 | for y := 0; y < h; y++ {
87 | for x := 0; x < w; x++ {
88 | r, g, b, _ := (*img1).At(x, y).RGBA()
89 | r2, g2, b2, _ := (*img2).At(x, y).RGBA()
90 | if r != r2 || g != g2 || b != b2 {
91 | count++
92 | }
93 | }
94 | }
95 | return count
96 | }
97 |
98 | //OpenPng permet d'ouvrir un PNG
99 | func OpenPng(name string) (*image.Image, error) {
100 | f, err := os.Open(name)
101 | if err != nil {
102 | return nil, err
103 | }
104 | in, err2 := png.Decode(f)
105 | if err2 != nil {
106 | return nil, err2
107 | }
108 |
109 | return &in, nil
110 | }
111 |
112 | func IsInBoundaries(img *image.NRGBA, x, y int) bool {
113 | return x >= 0 && x < (*img).Bounds().Dx() && y >= 0 && y < (*img).Bounds().Dy()
114 | }
115 |
116 | // //WritePng permet d'écrire un PNG
117 | // func WritePng(img *image.NRGBA, name string) {
118 | // fout, err := os.OpenFile(name, os.O_WRONLY|os.O_CREATE, 0600)
119 | // if err != nil {
120 | // log.Fatal(err)
121 | // }
122 | // defer fout.Close()
123 | //
124 | // if err := png.Encode(fout, img); err != nil {
125 | // fout.Close()
126 | // log.Fatal(err)
127 | // }
128 | //
129 | // if err := fout.Close(); err != nil {
130 | // log.Fatal(err)
131 | // }
132 | // }
133 |
134 | //WritePng permet d'écrire un PNG
135 | func WriteImage(w io.Writer, img image.Image, format Format) error {
136 | var err error
137 | switch format {
138 | case JPEG:
139 | var rgba *image.RGBA
140 | if nrgba, ok := img.(*image.NRGBA); ok {
141 | if nrgba.Opaque() {
142 | rgba = &image.RGBA{
143 | Pix: nrgba.Pix,
144 | Stride: nrgba.Stride,
145 | Rect: nrgba.Rect,
146 | }
147 | }
148 | }
149 | if rgba != nil {
150 | err = jpeg.Encode(w, rgba, &jpeg.Options{Quality: 95})
151 | } else {
152 | err = jpeg.Encode(w, img, &jpeg.Options{Quality: 95})
153 | }
154 |
155 | case PNG:
156 | err = png.Encode(w, img)
157 | case GIF:
158 | err = gif.Encode(w, img, &gif.Options{NumColors: 256})
159 | case TIFF:
160 | err = tiff.Encode(w, img, &tiff.Options{Compression: tiff.Deflate, Predictor: true})
161 | case BMP:
162 | err = bmp.Encode(w, img)
163 | default:
164 | err = ErrUnsupportedFormat
165 | }
166 | return err
167 | }
168 |
169 | // Save saves the image to file with the specified filename.
170 | // The format is determined from the filename extension: "jpg" (or "jpeg"), "png", "gif", "tif" (or "tiff") and "bmp" are supported.
171 | func Save(img image.Image, filename string) (err error) {
172 | formats := map[string]Format{
173 | ".jpg": JPEG,
174 | ".jpeg": JPEG,
175 | ".png": PNG,
176 | ".tif": TIFF,
177 | ".tiff": TIFF,
178 | ".bmp": BMP,
179 | ".gif": GIF,
180 | }
181 |
182 | ext := strings.ToLower(filepath.Ext(filename))
183 | f, ok := formats[ext]
184 | if !ok {
185 | return ErrUnsupportedFormat
186 | }
187 |
188 | file, err := os.Create(filename)
189 | if err != nil {
190 | return err
191 | }
192 | defer file.Close()
193 |
194 | return WriteImage(file, img, f)
195 | }
196 |
197 | func Exists(path string) (bool, error) {
198 | _, err := os.Stat(path)
199 | if err == nil {
200 | return true, nil
201 | }
202 | if os.IsNotExist(err) {
203 | return false, nil
204 | }
205 | return true, err
206 | }
207 |
208 | func RemoveContents(dir string) error {
209 | d, err := os.Open(dir)
210 | if err != nil {
211 | return err
212 | }
213 | defer d.Close()
214 | names, err := d.Readdirnames(-1)
215 | if err != nil {
216 | return err
217 | }
218 | for _, name := range names {
219 | err = os.RemoveAll(filepath.Join(dir, name))
220 | if err != nil {
221 | return err
222 | }
223 | }
224 | return nil
225 | }
226 |
--------------------------------------------------------------------------------
/src/test/resources/coverage/util/util2.go:
--------------------------------------------------------------------------------
1 | package util
2 |
--------------------------------------------------------------------------------
/src/test/resources/coverage/util/util2_test.go:
--------------------------------------------------------------------------------
1 | package util
2 |
3 | import "testing"
4 |
5 | func TestSkipped2(t *testing.T) {
6 | t.SkipNow()
7 | }
8 |
9 | func TestFailure(t *testing.T) {
10 | t.FailNow()
11 | }
12 |
--------------------------------------------------------------------------------
/src/test/resources/coverage/util/util_test.go:
--------------------------------------------------------------------------------
1 | package util
2 |
3 | import (
4 | "log"
5 | "testing"
6 | )
7 |
8 | func TestSkipped(t *testing.T) {
9 | t.SkipNow()
10 | }
11 |
12 | func TestFalseSquare(t *testing.T) {
13 | out := falseSquare(5)
14 |
15 | if out != 25 {
16 | t.Error(
17 | "For 5",
18 | "expected", "25",
19 | "got", out,
20 | )
21 | }
22 |
23 | }
24 |
25 | func TestMin(t *testing.T) {
26 | out := Min(5, 9)
27 |
28 | if out != 5 {
29 | t.Error(
30 | "For 5,9",
31 | "expected", "5",
32 | "got", out,
33 | )
34 | }
35 |
36 | }
37 |
38 | func TestMax(t *testing.T) {
39 | out := Max(5, 9)
40 |
41 | if out != 9 {
42 | t.Error(
43 | "For 5,9",
44 | "expected", "9",
45 | "got", out,
46 | )
47 | }
48 |
49 | }
50 |
51 | func TestCompare(t *testing.T) {
52 | img1, err := OpenPng("../imagetest/Image47.png")
53 | if err != nil {
54 | log.Fatal("erreur test compare")
55 | return
56 | }
57 |
58 | count := CompareImage(img1, img1)
59 |
60 | if count != 0 {
61 | t.Error(
62 | "For Image47.png",
63 | "expected 0",
64 | "got", count,
65 | )
66 | }
67 | }
68 |
69 | func TestCompare2(t *testing.T) {
70 | img1, err := OpenPng("../imagetest/Image47.png")
71 | img2, err2 := OpenPng("../imagetest/Image47.png")
72 |
73 | if err != nil || err2 != nil {
74 | log.Fatal(err, " ", err2)
75 | return
76 | }
77 |
78 | count := CompareImage(img1, img2)
79 |
80 | if count != 0 {
81 | t.Error(
82 | "For Image47.png",
83 | "expected 0",
84 | "got", count,
85 | )
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/src/test/resources/coverage/vendor/fileexcludedinvendordirectory.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uartois/sonar-golang/c57c5baba1b546642bfdf56d6be8d4ef06edcbf8/src/test/resources/coverage/vendor/fileexcludedinvendordirectory.txt
--------------------------------------------------------------------------------
/src/test/resources/gotest/test1_test.go:
--------------------------------------------------------------------------------
1 | func TestAverage(t *testing.T){
2 |
3 | }
4 |
--------------------------------------------------------------------------------
/src/test/resources/gotest/test2_test.go:
--------------------------------------------------------------------------------
1 | func TestAverage(t *testing.T){
2 |
3 | }
4 |
--------------------------------------------------------------------------------
/src/test/resources/gotest/test_test.go:
--------------------------------------------------------------------------------
1 | package test
2 |
3 | import (
4 | "github.com/stretchr/testify/assert"
5 | )
6 |
7 | func IAmNotATest(t *testing.T) {
8 | // do something
9 | }
10 |
11 | func TestEasyDef(t *testing.T) {
12 | assert.True(t, true, "Should match")
13 | }
14 |
15 | func TestSpaceDef (t *testing.T) {
16 | assert.True(t, true, "Should match")
17 | }
18 |
19 | func TestNoSpaceDef(t *testing.T){
20 | assert.True(t, true, "Should match")
21 | }
22 |
23 | func TestTwoLines1 (t *testing.T)
24 | {
25 | assert.True(t, true, "Should match")
26 | }
27 |
28 | func
29 | TestTwoLines2 (t *testing.T) {
30 | assert.True(t, true, "Should match")
31 | }
32 |
33 | func TestNested(t *testing.T) {
34 | t.Parallel()
35 | t.Run("match", func(t *testing.T) {
36 | assert.True(t, true, "Should match")
37 | })
38 | t.Run("nomatch", func(t *testing.T) {
39 | assert.True(t, true, "Should match")
40 | })
41 | }
42 |
43 | func (suite *ExampleTestSuite) TestSuite() {
44 | suite.Equal(5, suite.VariableThatShouldStartAtFive)
45 | }
46 |
--------------------------------------------------------------------------------
/src/test/resources/grammar/constant_expressions.go:
--------------------------------------------------------------------------------
1 | const a = 2 + 3.0 // a == 5.0 (untyped floating-point constant)
2 | const b = 15 / 4 // b == 3 (untyped integer constant)
3 | const c = 15 / 4.0 // c == 3.75 (untyped floating-point constant)
4 | const Θ float64 = 3/2 // Θ == 1.0 (type float64, 3/2 is integer division)
5 | const Π float64 = 3/2. // Π == 1.5 (type float64, 3/2. is float division)
6 | const d = 1 << 3.0 // d == 8 (untyped integer constant)
7 | const e = 1.0 << 3 // e == 8 (untyped integer constant)
8 | const f = int32(1) << 33 // illegal (constant 8589934592 overflows int32)
9 | const g = float64(2) >> 1 // illegal (float64(2) is a typed floating-point constant)
10 | const h = "foo" > "bar" // h == true (untyped boolean constant)
11 | const j = true // j == true (untyped boolean constant)
12 | const k = 'w' + 1 // k == 'x' (untyped rune constant)
13 | const l = "hi" // l == "hi" (untyped string constant)
14 | const m = string(k) // m == "x" (type string)
15 | const Σ = 1 - 0.707i // (untyped complex constant)
16 | const Δ = Σ + 2.0e-4 // (untyped complex constant)
17 | const Φ = iota*1i - 1/1i // (untyped complex constant)
18 |
--------------------------------------------------------------------------------
/src/test/resources/grammar/import_complex_definition.go:
--------------------------------------------------------------------------------
1 | import (
2 | "package1"
3 | "package2"
4 | "package2"
5 | )
6 |
--------------------------------------------------------------------------------
/src/test/resources/grammar/import_simple_definition.go:
--------------------------------------------------------------------------------
1 | import "apackage"
2 |
--------------------------------------------------------------------------------
/src/test/resources/grammar/package_definition.go:
--------------------------------------------------------------------------------
1 | package testpackage
2 |
--------------------------------------------------------------------------------
/src/test/resources/grammar/var_definition.go:
--------------------------------------------------------------------------------
1 | var test int = 5
2 | var test2 float32 = 8.6
3 | var test3 string = "a string"
4 |
5 | var test4 int
6 | var test5 float64
7 | var test6 string
8 |
9 |
10 | // https://golang.org/ref/spec#Variables
11 |
12 | var x interface{} // x is nil and has static type interface{}
13 | var v *T // v has value nil, static type *T
14 | x = 42 // x has value 42 and dynamic type int
15 | x = v // x has value (*T)(nil) and dynamic type *T
16 |
--------------------------------------------------------------------------------
/src/test/resources/grammar/var_fast_definition.go:
--------------------------------------------------------------------------------
1 | test := 1.0
2 | test2 := "a string"
3 | test3 := 1
--------------------------------------------------------------------------------
/src/test/resources/highlighter/test.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 |
6 | func oneFunction() {
7 | fmt.Println("do something")
8 | }
9 |
10 | func oneFunctionWithParameter(a int) {
11 | fmt.Println("do something")
12 | }
13 |
14 | func oneFunctionWithParameters(a, b int, c float32) {
15 | fmt.Println("do something")
16 | }
17 |
18 | func oneFunctionWithParametersAndReturn(a, b int, c float32) int {
19 | fmt.Println("do something")
20 | }
21 | func oneFunctionWithParametersAndReturns(a, b int, c float32) (int, float32, string) {
22 | fmt.Println("do something")
23 | }
24 |
--------------------------------------------------------------------------------
/src/test/resources/highlighter/testbug1.go:
--------------------------------------------------------------------------------
1 | var testBug1 string = "test\"other"
2 | var testBug1_2 string = "stuff\"other"
3 |
--------------------------------------------------------------------------------
/src/test/resources/key.properties:
--------------------------------------------------------------------------------
1 | ###############################################################################
2 | # Copyright 2017 - Université d'Artois
3 | #
4 | # This file is part of SonarQube Golang plugin (sonar-golang).
5 | #
6 | # Sonar-golang is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU Lesser General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 | #
11 | # Sonar-golang is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU Lesser General Public License for more details.
15 | #
16 | # You should have received a copy of the GNU Lesser General Public License
17 | # along with Sonar-golang. If not, see .
18 | #
19 | # Contributors:
20 | # Thibault Falque (thibault_falque@ens.univ-artois.fr)
21 | ###############################################################################
22 | #golint\:ExportedType=exported type [a-zA-Z0-9]+ should have comment or be unexported
23 | golint\:FormComment=comment on exported [a-zA-Z0-9]+ [a-zA-Z0-9\.]+ should be of the form "[a-zA-Z\.]+ *\t*..."
24 | golint\:AllCaps=don't use ALL_CAPS in Go names; use CamelCase
25 | golint\:UnderscoreInPackageName=don't use an underscore in package name
26 | golint\:LeadingK=don't use leading k in Go names; [a-zA-Z0-9]+ [a-zA-Z0-9]+ should be [a-zA-Z0-9]+
27 | golint\:UnderscoreInGoName=don't use underscores in Go names; [a-zA-Z0-9]+ [a-zA-Z0-9_]+ should be [a-zA-Z0-9]+
28 | golint\:ErrorLastReturn=error should be the last type when returning multiple items
29 | golint\:ErrorEndString=error strings should not be capitalized or end with punctuation or a newline
30 | golint\:ErrorVarName=error var [a-zA-Z0-9]+ should have name of the form [a-zA-Z0-9]+
31 | golint\:AnnoyingUseExportedType=exported [a-zA-Z0-9]+ [a-zA-Z0-9]+ returns unexported type [a-zA-Z0-9]+, which can be annoying to use
32 | golint\:IfBlockReturn=if block ends with a return statement, so drop this else and outdent its block
33 | golint\:PackageCommentForm=package comment should be of the form \"[a-zA-Z0-9]+...\"
34 | golint\:PackageCommentSpace=package comment should not have leading space
35 | golint\:ReceiverNameConsistent=receiver name [a-zA-Z0-9]+ should be consistent with previous receiver name [a-zA-Z0-9]+ for [a-zA-Z0-9]+
36 | golint\:ReceiverNameReflection=receiver name should be a reflection of its identity; don't use generic names such as \"this\" or \"self\"
37 | golint\:ReceiverNameNotUnderscore=receiver name should not be an underscore
38 | golint\:DropAssignment=should drop = [a-zA-Z0-9]+ from declaration of var [a-zA-Z0-9]+; it is the zero value
39 | golint\:HavePackageComment=should have a package comment, unless it's in another file for this package
40 | golint\:NotUseBasicType=should not use basic type [a-zA-Z0-9]+ as key in context.WithValue
41 | golint\:NotUseDotImport=should not use dot imports
42 | golint\:Omit2ndValueFromRange=should omit 2nd value from range; this loop is equivalent to `for [a-zA-Z0-9]+ := range ...`
43 | golint\:OmitType=should omit type [a-zA-Z0-9]+ from declaration of var [a-zA-Z0-9]+; it will be inferred from the right-hand side
44 | golint\:ReplaceLintIncDec=should replace [a-zA-Z0-9\-\+=]+ with [a-zA-Z0-9\-\+]+
45 | golint\:ReplaceSprintf=should replace [a-zA-Z0-9\.]+\\(fmt.Sprintf\\(...\\)\\) with [a-zA-Z0-9]+.Errorf\\(...\\)
46 | golint\:Initialisms=[a-zA-Z0-9]+ [a-zA-Z0-9]+ should be [a-zA-Z0-9]+
47 | golint\:PackageNames=[a-zA-Z0-9]+ name will be used as [a-zA-Z0-9]+.[a-zA-Z0-9]+ by other packages, and that stutters; consider calling this [a-zA-Z0-9]+
48 | golint\:BlankImport=a blank import should be only in a main or test package, or have a comment justifying it
49 | golint\:CommentExportedType=comment on exported type [a-zA-Z0-9]+ should be of the form "[a-zA-Z0-9]+ ..." \\(with optional leading article\\)
50 | golint\:ContextContextFirstArg=context.Context should be the first parameter of a function
51 | golint\:ExportedHaveComment=exported [a-zA-Z0-9]+ [a-zA-Z0-9\.]+ should have comment or be unexported
52 | golint\:ExportedHaveComment2=exported [a-zA-Z0-9\.]+ [a-zA-Z0-9\.]+ should have comment[\(\) a-zA-Z0-9]+ or be unexported
53 | golint\:ExportedDeclaration=exported [a-zA-Z0-9]+ [a-zA-Z0-9]+ should have its own declaration
54 | golint\:SpecificSuffix=var [a-zA-Z0-9]+ is of type [a-zA-Z0-9\.]+; don't use unit-specific suffix [a-zA-Z0-9]+
55 | golint\:StructFieldInitialisms=struct field [a-zA-Z0-9]+ should be [a-zA-Z0-9]+
56 | gocyclo\:CyclomaticComplexity=cyclomatic complexity [0-9]+ of function [a-zA-Z0-9]+\\(\\) is high \\(> 10\\)
57 | errcheck\:ValueNotChecked=error return value not checked .*
58 | unconvert\:UnnecessaryConversion=unnecessary conversion
59 | structcheck\:UnusedStructField=unused struct field \\w+[\\w\\.]*
60 | gosimple\:ChannelInsteadSelect=
61 | ineffassign\:IneffectualAssignment=ineffectual assignment to [a-zA-Z0-9]+
62 | gas\:UnhandledErrors=Errors unhandled\.,LOW,HIGH
63 | goimports\:FileNotImported=file is not goimported
64 | vet\:Unreachable=unreachable code
65 | vet\:Shadow=declaration of "[A-Za-z0-9\.]+" shadows declaration at [A-Za-z0-9_\-]+.go:[0-9]+
66 | vet\:Misuse=possible misuse of unsafe.Pointer
67 | gas\:SQLFormatting=SQL string formatting,MEDIUM,HIGH
68 | gas\:SQLConcatenation=SQL string concatenation,MEDIUM,HIGH
69 | gas\:RSAKeyLength=RSA keys should be at least 2048 bits,MEDIUM,HIGH
70 | gas\:UnsafeCall=Use of unsafe calls should be audited,LOW,HIGH
71 | gas\:UnescapedHTMLTemplates=this method will not auto-escape HTML\. Verify data is well formed\.,MEDIUM,LOW
72 | gas\:WeakCrypto=Use of weak cryptographic primitive,HIGH,HIGH
73 | vet\:Lock=[A-Za-z0-9\.]+ passes lock by value: [A-Za-z0-9\.]+ contains [A-Za-z0-9\.]+
74 | vet\:FormatingPrintfFamily=possible formatting directive in [A-Za-z0-9\.]+ call
75 |
--------------------------------------------------------------------------------
/src/test/resources/profile.properties:
--------------------------------------------------------------------------------
1 | ###############################################################################
2 | # Copyright 2017 - Université d'Artois
3 | #
4 | # This file is part of SonarQube Golang plugin (sonar-golang).
5 | #
6 | # Sonar-golang is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU Lesser General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 | #
11 | # Sonar-golang is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU Lesser General Public License for more details.
15 | #
16 | # You should have received a copy of the GNU Lesser General Public License
17 | # along with Sonar-golang. If not, see .
18 | #
19 | # Contributors:
20 | # Thibault Falque (thibault_falque@ens.univ-artois.fr)
21 | ###############################################################################
22 | #golint\:ExportedType=true
23 | golint\:FormComment=true
24 | golint\:AllCaps=true
25 | golint\:UnderscoreInPackageName=true
26 | golint\:LeadingK=true
27 | golint\:UnderscoreInGoName=true
28 | golint\:ErrorLastReturn=true
29 | golint\:ErrorEndString=true
30 | golint\:ErrorVarName=true
31 | golint\:AnnoyingUseExportedType=true
32 | golint\:IfBlockReturn=true
33 | golint\:PackageCommentForm=true
34 | golint\:PackageCommentSpace=true
35 | golint\:ReceiverNameConsistent=true
36 | golint\:ReceiverNameReflection=true
37 | golint\:ReceiverNameNotUnderscore=true
38 | golint\:DropAssignment=true
39 | golint\:HavePackageComment=true
40 | golint\:NotUseBasicType=true
41 | golint\:NotUseDotImport=true
42 | golint\:Omit2ndValueFromRange=true
43 | golint\:OmitType=true
44 | golint\:ReplaceLintIncDec=true
45 | golint\:ReplaceSprintf=true
46 | golint\:Initialisms=true
47 | golint\:PackageNames=true
48 | golint\:BlankImport=true
49 | golint\:CommentExportedType=true
50 | golint\:ContextContextFirstArg=true
51 | golint\:ExportedHaveComment=true
52 | golint\:ExportedHaveComment2=true
53 | golint\:ExportedDeclaration=true
54 | golint\:SpecificSuffix=true
55 | golint\:StructFieldInitialisms=true
56 | gocyclo\:CyclomaticComplexity=true
57 | errcheck\:ValueNotChecked=true
58 | unconvert\:UnnecessaryConversion=true
59 | structcheck\:UnusedStructField=true
60 | gosimple\:ChannelInsteadSelect=true
61 | ineffassign\:IneffectualAssignment=true
62 | gas\:UnhandledErrors=true
63 | goimports\:FileNotImported=true
64 | gas\:SQLFormatting=true
65 | vet\:Shadow=true
66 | gas\:SQLConcatenation=true
67 | gas\:RSAKeyLength=true
68 | gas\:UnsafeCall=true
69 | gas\:UnescapedHTMLTemplates=true
70 | gas\:WeakCrypto=true
71 | vet\:Unreachable=true
72 | vet\:Misuse=true
73 | vet\:Lock=true
74 | vet\:FormatingPrintfFamily=true
75 |
--------------------------------------------------------------------------------
/src/test/resources/project/package1.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "math"
4 |
5 | //SqrtUint32 Permet de faire une racine carré sur un uint32
6 | func SqrtUint32(x uint32) uint32 {
7 | return uint32(math.Ceil(math.Sqrt(float64(x))))
8 | }
9 |
--------------------------------------------------------------------------------
/src/test/resources/project/package1_test.go:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uartois/sonar-golang/c57c5baba1b546642bfdf56d6be8d4ef06edcbf8/src/test/resources/project/package1_test.go
--------------------------------------------------------------------------------
/src/test/resources/project/test.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uartois/sonar-golang/c57c5baba1b546642bfdf56d6be8d4ef06edcbf8/src/test/resources/project/test.py
--------------------------------------------------------------------------------