Compare commits
23 Commits
1.0.8.post
...
1.0.8.post
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3d2b8d3762 | ||
|
|
da9fa475e8 | ||
|
|
93d2046c98 | ||
|
|
fa7eaf0769 | ||
|
|
cad73c4711 | ||
|
|
5621ba99f6 | ||
|
|
c49468e294 | ||
|
|
bec5f9234d | ||
|
|
4e50b8d03f | ||
|
|
e74a53e3bf | ||
|
|
ef7469f35b | ||
|
|
9e5f0de5c4 | ||
|
|
99f38741fd | ||
|
|
eee2bf551c | ||
|
|
01ce809823 | ||
|
|
4ab70409a0 | ||
|
|
7b9752a17a | ||
|
|
879a7ca03d | ||
|
|
bd3389aeb2 | ||
|
|
886a22bef2 | ||
|
|
e9355471ba | ||
|
|
3bbbe946a1 | ||
|
|
cc2f6353ac |
101
Jenkinsfile
vendored
101
Jenkinsfile
vendored
@@ -6,7 +6,13 @@
|
||||
// You should have received a copy of the license along with this
|
||||
// work. If not, see <https://creativecommons.org/licenses/by-nc-sa/4.0/>.
|
||||
|
||||
|
||||
import groovy.xml.XmlUtil
|
||||
import static javax.xml.xpath.XPathConstants.*
|
||||
import javax.xml.xpath.*
|
||||
import groovy.xml.DOMBuilder
|
||||
import groovy.xml.dom.DOMCategory
|
||||
import java.math.RoundingMode
|
||||
import java.math.BigDecimal
|
||||
|
||||
// configurable settings:
|
||||
// use to send email if workflow problem
|
||||
@@ -28,6 +34,11 @@ def _MkDocsWebURL = "dabauto--mkdocs-web.dmz.chacha.home/mkdocs-web/"
|
||||
def _MkDocsWebCredentials = "2c5b684e-3787-4b37-8aca-b3dd4a383fe2"
|
||||
def _PypiCredentials = "Pypi"
|
||||
|
||||
|
||||
def badge_coverage = addEmbeddableBadgeConfiguration(id: "coverage", subject: "coverage")
|
||||
def badge_maintainability = addEmbeddableBadgeConfiguration(id: "maintainability", subject: "maintainability")
|
||||
def badge_quality = addEmbeddableBadgeConfiguration(id: "quality", subject: "quality score")
|
||||
|
||||
// commands Helper: /!\ Made for GITEA /!\
|
||||
String determineRepoUserName() {
|
||||
return scm.getUserRemoteConfigs()[0].getUrl().tokenize('/')[3].split("\\.")[0]
|
||||
@@ -63,6 +74,46 @@ String ExtractBaseVersion(inVersion) {
|
||||
return matcher[0][1]
|
||||
}
|
||||
|
||||
int GetCoverageValue(String CoverageFilePath,String XPath)
|
||||
{
|
||||
//File file = new File(CoverageFilePath)
|
||||
//coverageReportRaw = file.getText('UTF-8')
|
||||
coverageReportRaw = readFile(CoverageFilePath)
|
||||
coverageReport = DOMBuilder.parse(new StringReader(coverageReportRaw), false, false)
|
||||
coverageReportRoot = coverageReport.documentElement
|
||||
|
||||
def xpath = XPathFactory.newInstance().newXPath()
|
||||
res = xpath.evaluate(XPath,coverageReportRoot,NUMBER)
|
||||
return res
|
||||
}
|
||||
|
||||
String getColorScale(BigDecimal value)
|
||||
{
|
||||
if( value >9) { return "Goldenrod"}
|
||||
else if( value >6) { return "seagreen"}
|
||||
else if( value >4) { return "orange"}
|
||||
else if( value >2) { return "darkred"}
|
||||
else { return "dimgrey"}
|
||||
}
|
||||
|
||||
String getColorScale_reversed(BigDecimal value)
|
||||
{
|
||||
if( value >9) { return "dimgrey"}
|
||||
else if( value >6) { return "darkred"}
|
||||
else if( value >4) { return "orange"}
|
||||
else if( value >2) { return "seagreen"}
|
||||
else { return "Goldenrod"}
|
||||
}
|
||||
|
||||
int GetCoverageValue_lines_valid(String CoverageFilePath) { return GetCoverageValue(CoverageFilePath,"/coverage/@lines-valid") }
|
||||
int GetCoverageValue_lines_covered(String CoverageFilePath) { return GetCoverageValue(CoverageFilePath,"/coverage/@lines-covered") }
|
||||
int GetCoverageValue_line_rate(String CoverageFilePath) { return GetCoverageValue(CoverageFilePath,"/coverage/@line-rate") }
|
||||
int GetCoverageValue_branches_valid(String CoverageFilePath) { return GetCoverageValue(CoverageFilePath,"/coverage/@branches-valid") }
|
||||
int GetCoverageValue_branches_covered(String CoverageFilePath) { return GetCoverageValue(CoverageFilePath,"/coverage/@branches-covered") }
|
||||
int GetCoverageValue_branch_rate(String CoverageFilePath) { return GetCoverageValue(CoverageFilePath,"/coverage/@branch-rate") }
|
||||
int GetCoverageValue_complexity(String CoverageFilePath) { return GetCoverageValue(CoverageFilePath,"/coverage/@complexity") }
|
||||
|
||||
|
||||
pipeline {
|
||||
|
||||
// for Docker based build (preferable)
|
||||
@@ -324,7 +375,7 @@ pipeline {
|
||||
def wheelPath = findFiles(glob: "**/dist/*.whl")[0]
|
||||
echo "wheel artifact path: $wheelPath"
|
||||
// install the package, with *test* optionnal packages, as user
|
||||
sh(". ~/TEST_ENV/bin/activate && pip install --find-links dist/ ${PY_PROJECT_NAME} .[test,coverage-check,quality-check,type-check,doc-gen]")
|
||||
sh(". ~/TEST_ENV/bin/activate && pip install --find-links dist/ ${PY_PROJECT_NAME} .[test,coverage-check,quality-check,type-check,doc-gen,complexity-check]")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -334,6 +385,14 @@ pipeline {
|
||||
steps {
|
||||
dir("gitrepo") {
|
||||
sh(". ~/TEST_ENV/bin/activate && python -m helpers --type-check --quality-check")
|
||||
script {
|
||||
def jsonObj = readJSON file: "helpers-results/quality_check/metrics.json"
|
||||
quality_score = new BigDecimal(jsonObj["GlobalScore"])
|
||||
sz_quality_score = quality_score.setScale(2, RoundingMode.HALF_EVEN).toString()
|
||||
badge_quality.setStatus(sz_quality_score)
|
||||
badge_quality.setColor(getColorScale(quality_score))
|
||||
}
|
||||
sh(". ~/TEST_ENV/bin/activate && python -m helpers --complexity-check")
|
||||
}
|
||||
}
|
||||
post {
|
||||
@@ -388,6 +447,14 @@ pipeline {
|
||||
style: 'stackedArea',
|
||||
keepRecords: true,
|
||||
numBuilds: ''])
|
||||
|
||||
plot([ csvFileName: 'plot-4ceb9ee2-ca78-11ed-afa1-0242ac120002.csv',
|
||||
csvSeries: [[ file: 'gitrepo/helpers-results/complexity_check/MI.csv', inclusionFlag: 'INCLUDE_BY_STRING',exclusionValues: 'MeanMaintainability', url: '']],
|
||||
group: 'metrics',
|
||||
title: 'maintainability',
|
||||
style: 'stackedArea',
|
||||
keepRecords: true,
|
||||
numBuilds: ''])
|
||||
}
|
||||
}
|
||||
|
||||
@@ -400,6 +467,36 @@ pipeline {
|
||||
println unit_test_full_name__html
|
||||
unit_test_full_name__xml=findFiles(glob: "helpers-results/unit_test_full/*.xml")[0].getName()
|
||||
println unit_test_full_name__xml
|
||||
|
||||
coverage_report_path = "helpers-results/unit_test_coverage/test_coverage.xml"
|
||||
println GetCoverageValue_lines_valid(coverage_report_path)
|
||||
println GetCoverageValue_lines_covered(coverage_report_path)
|
||||
println GetCoverageValue_line_rate(coverage_report_path)
|
||||
println GetCoverageValue_branches_valid(coverage_report_path)
|
||||
println GetCoverageValue_branches_covered(coverage_report_path)
|
||||
println GetCoverageValue_branch_rate(coverage_report_path)
|
||||
println GetCoverageValue_complexity(coverage_report_path)
|
||||
|
||||
full_rate = new BigDecimal( 10*(GetCoverageValue_line_rate(coverage_report_path) + GetCoverageValue_branch_rate(coverage_report_path)) / 2 )
|
||||
sz_full_rate = full_rate.setScale(2, RoundingMode.HALF_EVEN).toString()
|
||||
badge_coverage.setStatus(sz_full_rate)
|
||||
badge_coverage.setColor(getColorScale(full_rate))
|
||||
|
||||
//complexity = new BigDecimal( 10*GetCoverageValue_complexity(coverage_report_path))
|
||||
//sz_complexity = complexity.setScale(2, RoundingMode.HALF_EVEN).toString()
|
||||
//badge_complexity.setStatus(sz_complexity)
|
||||
//badge_quality.setColor(getColorScale_reversed(complexity))
|
||||
|
||||
//badge_maintainability
|
||||
records = readCSV file: 'helpers-results/complexity_check/MI.csv'
|
||||
maintainability = records[1][1]
|
||||
badge_maintainability.setStatus(maintainability)
|
||||
|
||||
if ( maintainability == 'D') { badge_maintainability.setColor( "dimgrey")}
|
||||
else if( maintainability == 'C') { badge_maintainability.setColor( "darkred")}
|
||||
else if( maintainability == 'B') { badge_maintainability.setColor( "orange")}
|
||||
else if( maintainability == 'A') { badge_maintainability.setColor( "seagreen")}
|
||||
else if( maintainability == 'A+') { badge_maintainability.setColor( "Goldenrod")}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||
|
||||

|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ if __package__ == "helpers":
|
||||
from .unit_test import unit_test
|
||||
from .doc_gen import doc_gen
|
||||
from .changelog_gen import changelog_gen
|
||||
from .complexity_check import complexity_check
|
||||
else:
|
||||
# when calling the __main__.py file (from IDE)
|
||||
from helpers.types_check import types_check
|
||||
@@ -30,6 +31,7 @@ else:
|
||||
from helpers.unit_test import unit_test
|
||||
from helpers.doc_gen import doc_gen
|
||||
from helpers.changelog_gen import changelog_gen
|
||||
from helpers.complexity_check import complexity_check
|
||||
|
||||
logging.getLogger().setLevel(logging.INFO)
|
||||
|
||||
@@ -59,6 +61,8 @@ if __name__ == "__main__":
|
||||
|
||||
parser.add_argument("-clg", "--changelog-gen", dest="changeloggen", action="store_true", help="enable changelog generation")
|
||||
|
||||
parser.add_argument("-cpc", "--complexity-check", dest="complexitycheck", action="store_true", help="enable complexity check")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
##################################
|
||||
@@ -73,6 +77,7 @@ if __name__ == "__main__":
|
||||
# args.docgen = True
|
||||
# args.docgenpdf = True
|
||||
# args.changeloggen = True
|
||||
# args.complexitycheck = True
|
||||
|
||||
helpers = []
|
||||
if args.typecheck == True:
|
||||
@@ -102,6 +107,9 @@ if __name__ == "__main__":
|
||||
if args.changeloggen == True:
|
||||
helpers.append(changelog_gen)
|
||||
|
||||
if args.complexitycheck == True:
|
||||
helpers.append(complexity_check)
|
||||
|
||||
for helper in helpers:
|
||||
helper.set_context(project_rootdir_path, pyproject)
|
||||
helper.reset_result_dir()
|
||||
|
||||
70
helpers/complexity_check.py
Normal file
70
helpers/complexity_check.py
Normal file
@@ -0,0 +1,70 @@
|
||||
# pyChaChaDummyProject (c) by chacha
|
||||
#
|
||||
# pyChaChaDummyProject is licensed under a
|
||||
# Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International Unported License.
|
||||
#
|
||||
# You should have received a copy of the license along with this
|
||||
# work. If not, see <https://creativecommons.org/licenses/by-nc-sa/4.0/>.
|
||||
|
||||
from __future__ import annotations
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
# from pathlib import Path
|
||||
# import os
|
||||
import statistics
|
||||
import csv
|
||||
from json import loads as JSON_LOADS
|
||||
from radon.complexity import cc_rank, SCORE
|
||||
from radon.cli import Config
|
||||
from radon.cli.harvest import CCHarvester, HCHarvester, MIHarvester
|
||||
|
||||
from .helper_base import helper_withresults_base
|
||||
from pprint import pprint
|
||||
|
||||
|
||||
class complexity_check(helper_withresults_base):
|
||||
@classmethod
|
||||
def do_job(cls):
|
||||
config = Config(
|
||||
exclude="__init__\.py",
|
||||
ignore=None,
|
||||
order=SCORE,
|
||||
show_closures=False,
|
||||
no_assert=True,
|
||||
min="A",
|
||||
max="F",
|
||||
multi=False,
|
||||
)
|
||||
|
||||
h = MIHarvester([str(_) for _ in sorted((cls.project_rootdir_path / "src").rglob("*.py"))], config).as_json()
|
||||
res = JSON_LOADS(h)
|
||||
|
||||
with open(cls.get_result_dir() / "MI.json", "w", newline="") as oFile:
|
||||
oFile.write(h)
|
||||
|
||||
mean = statistics.mean(_["mi"] for _ in res.values())
|
||||
|
||||
if mean >= 65:
|
||||
rank = "A+"
|
||||
elif mean >= 20:
|
||||
rank = "A"
|
||||
elif mean >= 10:
|
||||
rank = "B"
|
||||
else:
|
||||
rank = "C"
|
||||
|
||||
RES_MI = {"MeanMaintainability": mean, "MaintainabilityIndex": rank}
|
||||
with open(cls.get_result_dir() / "MI.csv", "w", newline="") as oFile:
|
||||
writer = csv.DictWriter(oFile, fieldnames=RES_MI.keys())
|
||||
writer.writeheader()
|
||||
writer.writerow(RES_MI)
|
||||
|
||||
config = Config(exclude=None, ignore=None, order=SCORE, show_closures=False, no_assert=True, min="A", max="F", multi=False)
|
||||
h = CCHarvester([str(_) for _ in sorted((cls.project_rootdir_path / "src").rglob("*.py"))], config).as_json()
|
||||
with open(cls.get_result_dir() / "CC.json", "w", newline="") as oFile:
|
||||
oFile.write(h)
|
||||
|
||||
config = Config(exclude=None, ignore=None, order=SCORE, show_closures=False, no_assert=True, min="A", max="F", by_function=None)
|
||||
h = HCHarvester([str(_) for _ in sorted((cls.project_rootdir_path / "src").rglob("*.py"))], config).as_json()
|
||||
with open(cls.get_result_dir() / "HC.json", "w", newline="") as oFile:
|
||||
oFile.write(h)
|
||||
@@ -31,8 +31,6 @@ class doc_gen(helper_withresults_base):
|
||||
|
||||
@classmethod
|
||||
def do_job(cls):
|
||||
print(cls.project_rootdir_path)
|
||||
print()
|
||||
|
||||
# create doc root dir
|
||||
doc_path = cls.project_rootdir_path / "docs"
|
||||
|
||||
@@ -60,6 +60,7 @@ class quality_check(helper_withresults_base):
|
||||
with redirect_stdout(StdOutput):
|
||||
pylint_Run(
|
||||
[
|
||||
"--load-plugins=pylint.extensions.mccabe",
|
||||
"--output-format=json,parseable",
|
||||
"--disable=invalid-name",
|
||||
"--ignore=_version.py",
|
||||
|
||||
@@ -12,7 +12,6 @@ build-backend = "setuptools.build_meta"
|
||||
|
||||
[tool.setuptools_scm]
|
||||
version_scheme= "post-release"
|
||||
# tag_regex="^(?:v)?(?P<version>\\d+\\.\\d+\\.\\d+)([\\.\\-\\+])?(?:.*)?"
|
||||
|
||||
[project]
|
||||
name = "pygitversionhelper"
|
||||
@@ -57,6 +56,7 @@ Tracker = "https://chacha.ddns.net/gitea/chacha/pygitversionhelper/issue
|
||||
[project.optional-dependencies]
|
||||
test = ["junitparser>=2.8","junit2html>=30.1","xmlrunner>=1.7","mypy>=0.99" ]
|
||||
coverage-check = ["coverage>=7.0"]
|
||||
complexity-check = ["radon>=5.1"]
|
||||
quality-check = ["pylint>=2.15","pylint-json2html>=0.4","pandas>=1.5"]
|
||||
type-check = ["mypy[reports]>=0.99" ]
|
||||
doc-gen = ["mkdocs>=1.4.0", "mkdocs-material>=8.5", "mkdocs-localsearch>=0.9.0", "mkdocstrings[python]>=0.19", "mkdocs-with-pdf>=0.9.3","pyyaml>=6.0","pymdown-extensions>=9","mkdocs-markdownextradata-plugin","mkdocs-mermaid2-plugin"]
|
||||
|
||||
Reference in New Issue
Block a user