Compare commits

...

28 Commits

Author SHA1 Message Date
cbb2527f4e Merge pull request 'Update Jenkinsfile' (#41) from dev into master
Reviewed-on: https://chacha.ddns.net/gitea/chacha/pygitversionhelper/pulls/41
new-tag:1.3.6
2024-10-12 17:31:23 +02:00
490bc400cb Update Jenkinsfile 2024-10-12 16:42:52 +02:00
00882db033 Merge pull request 'dev' (#40) from dev into master
Reviewed-on: https://chacha.ddns.net/gitea/chacha/pygitversionhelper/pulls/40
new-tag:1.3.5
2023-11-06 16:13:04 +01:00
cclecle
5dc86907b6 update from last project template 2023-11-06 15:05:27 +00:00
cclecle
ce7d23f44b split quality & types .launch scripts 2023-11-06 15:01:10 +00:00
eb5bbc2900 Merge pull request 'chore: remove useless data dir' (#39) from dev into master
Reviewed-on: https://chacha.ddns.net/gitea/chacha/pygitversionhelper/pulls/39
new-tag:1.3.4
2023-09-30 01:54:47 +02:00
cclecle
deb9b618d1 chore: remove useless data dir
fix: correct function doc (Google docstrings)
fix: add py.tyed to dist
2023-09-30 00:18:40 +01:00
7c48c8c55e Merge pull request 'fix: switch to pypi version of chacha-cicd-helper' (#38) from dev into master
Reviewed-on: https://chacha.ddns.net/gitea/chacha/pygitversionhelper/pulls/38
new-tag:1.3.3
2023-09-30 00:54:11 +02:00
cclecle
7198f9309d fix: switch to pypi version of chacha-cicd-helper 2023-09-29 23:50:35 +01:00
ac1535e02d Merge pull request 'chore: switch from helpers to chacha_cicd_helper' (#37) from dev into master
Reviewed-on: https://chacha.ddns.net/gitea/chacha/pygitversionhelper/pulls/37
new-tag:1.3.2
2023-09-30 00:07:14 +02:00
cclecle
068e834f7c chore: switch from helpers to chacha_cicd_helper 2023-09-29 23:03:48 +01:00
8049477a5c Merge pull request 'chore: dummy change' (#36) from dev into master
Reviewed-on: https://chacha.ddns.net/gitea/chacha/pygitversionhelper/pulls/36
new-tag:1.3.1
2023-09-24 20:31:09 +02:00
cclecle
d430907f12 chore: dummy change 2023-09-24 19:27:16 +01:00
a87a717b9e Merge pull request 'feat: add py.typed for mypy' (#35) from dev into master
Reviewed-on: https://chacha.ddns.net/gitea/chacha/pygitversionhelper/pulls/35
2023-09-24 20:24:51 +02:00
cclecle
0be71a4c3c feat: add py.typed for mypy 2023-09-24 19:21:29 +01:00
ca7a69ae76 Merge pull request 'dev' (#34) from dev into master
Reviewed-on: https://chacha.ddns.net/gitea/chacha/pygitversionhelper/pulls/34
new-tag:1.3.0
2023-09-24 20:18:10 +02:00
cclecle
114aa31115 cicd: add "--enable-incomplete-feature=Unpack" 2023-09-24 19:13:34 +01:00
cclecle
facd431c59 update docgen & cicd tools 2023-09-24 18:56:29 +01:00
d4b90b1f91 Merge pull request 'Fix title' (#33) from dev into master
Reviewed-on: https://chacha.ddns.net/gitea/chacha/pygitversionhelper/pulls/33
new-tag: 1.2.2
2023-03-28 02:39:04 +02:00
cclecle
a07bcc37c4 Fix title 2023-03-28 01:09:46 +01:00
ac70d4dde4 Merge pull request 'beautify jenkins file' (#32) from dev into master
Reviewed-on: https://chacha.ddns.net/gitea/chacha/pygitversionhelper/pulls/32
new-tag: 1.2.1
2023-03-28 02:05:30 +02:00
cclecle
0d1e981b6b beautify jenkins file 2023-03-28 01:01:10 +01:00
6e1c60ee53 Merge pull request 'dev' (#31) from dev into master
Reviewed-on: https://chacha.ddns.net/gitea/chacha/pygitversionhelper/pulls/31
newt-tag: 1.2.1
2023-03-28 01:55:24 +02:00
cclecle
b01779dd06 add missing parentheses 2023-03-28 00:50:43 +01:00
cclecle
f7ec5d98a7 fix changelog multiline 2023-03-28 00:45:48 +01:00
cclecle
82d4b1bd70 fix: remove useless printf in getMessagesSinceTag() 2023-03-28 00:45:00 +01:00
cclecle
880fa29bbd try to get changelog before tag creation 2023-03-28 00:35:00 +01:00
cclecle
7347106694 test printing changelog parts 2023-03-28 00:21:37 +01:00
24 changed files with 192 additions and 861 deletions

106
Jenkinsfile vendored
View File

@@ -26,7 +26,7 @@ def _bPreRelease = false
def _bDraft = false def _bDraft = false
// release content / changelog management // release content / changelog management
def _bAutoChangelog = true //Not supported yet def _bAutoChangelog = true //Not supported yet
def _ReleaseContent_Title = "_CI/CD Automatic Release_" def _ReleaseContent_Title = "# _CI/CD Automatic Release_"
def bPushMasterOnPypi = true def bPushMasterOnPypi = true
// full rebuild toogle // full rebuild toogle
def _bFullRebuilt = true def _bFullRebuilt = true
@@ -148,6 +148,7 @@ pipeline {
PY_PROJECT_NAME = "__NOTSET__" PY_PROJECT_NAME = "__NOTSET__"
PY_PROJECT_VERSION = "__NOTSET__" PY_PROJECT_VERSION = "__NOTSET__"
PY_PROJECT_VERSION_STRIPPED = "__NOTSET__" PY_PROJECT_VERSION_STRIPPED = "__NOTSET__"
CHANGELOG = "__NOTSET__"
} }
stages { stages {
@@ -182,8 +183,12 @@ pipeline {
sh("virtualenv --pip=embed --setuptools=embed --wheel=embed --no-periodic-update --activators bash,python TEST_ENV") sh("virtualenv --pip=embed --setuptools=embed --wheel=embed --no-periodic-update --activators bash,python TEST_ENV")
sh("virtualenv --pip=embed --setuptools=embed --wheel=embed --no-periodic-update --activators bash,python TOOLS_ENV") sh("virtualenv --pip=embed --setuptools=embed --wheel=embed --no-periodic-update --activators bash,python TOOLS_ENV")
sh(". ~/BUILD_ENV/bin/activate && pip install --upgrade setuptools build pip copier jinja2-slug toml") sh(". ~/BUILD_ENV/bin/activate && pip install --upgrade setuptools build pip")
sh(". ~/BUILD_ENV/bin/activate && pip install --upgrade 'copier==9.*' jinja2-slug toml")
sh(". ~/TEST_ENV/bin/activate && pip install --upgrade pip")
sh(". ~/TOOLS_ENV/bin/activate && pip install --upgrade pip")
sh(". ~/TOOLS_ENV/bin/activate && pip install simple_rest_client requests twine packaging") sh(". ~/TOOLS_ENV/bin/activate && pip install simple_rest_client requests twine packaging")
script { script {
@@ -215,6 +220,32 @@ pipeline {
withCredentials([usernamePassword(credentialsId: _SCMCredentials, passwordVariable: 'GIT_PASSWORD', usernameVariable: 'GIT_USERNAME')]) { withCredentials([usernamePassword(credentialsId: _SCMCredentials, passwordVariable: 'GIT_PASSWORD', usernameVariable: 'GIT_USERNAME')]) {
sh("git remote set-url origin https://${GIT_USERNAME}:${GIT_PASSWORD}@chacha.ddns.net/gitea/${_PROJECT_USER_NAME}/${_PROJECT_NAME}.git") sh("git remote set-url origin https://${GIT_USERNAME}:${GIT_PASSWORD}@chacha.ddns.net/gitea/${_PROJECT_USER_NAME}/${_PROJECT_NAME}.git")
} }
CHANGELOG = sh(script: """#!/bin/sh -
|. ~/TOOLS_ENV/bin/activate
|exec python - << '__EOWRAPPER__'
|
|import re
|
|try:
| from pychangelogfactory import ChangelogFactory
|except ImportError:
| from src.pychangelogfactory import ChangelogFactory
|
|try:
| from pygitversionhelper import gitversionhelper
|except ImportError:
| from src.pygitversionhelper import gitversionhelper
|
|
|LastTag=gitversionhelper.tag.getLastTag(same_branch=True)
|CommitHistory=gitversionhelper.commit.getMessagesSinceTag(LastTag, merged_output=True, ignore_merged=True)
|Changelog = ChangelogFactory(CommitHistory).RenderFullChangelog(include_unknown=True)
|print(Changelog.replace("\\n","\\n\\n"))
|
|__EOWRAPPER__
""".stripMargin(),
returnStdout: true).trim()
if(_GIT_BRANCH=="master") { if(_GIT_BRANCH=="master") {
if(sh(returnStdout: true, script: "git tag --points-at HEAD").trim().isEmpty()) { if(sh(returnStdout: true, script: "git tag --points-at HEAD").trim().isEmpty()) {
@@ -314,7 +345,7 @@ pipeline {
|'''.strip() |'''.strip()
| |
|import copier |import copier
|copier.run_auto("./", "../_gitrepo",vcs_ref="HEAD",use_prereleases=True,defaults=True,cleanup_on_error=False) |copier.run_copy("./", "../_gitrepo",vcs_ref="HEAD",use_prereleases=True,defaults=True,cleanup_on_error=False,unsafe=True)
| |
|__EOWRAPPER__ |__EOWRAPPER__
""".stripMargin()) """.stripMargin())
@@ -382,31 +413,39 @@ pipeline {
stage("CheckCode") { stage("CheckCode") {
steps { steps {
dir("gitrepo") { dir("gitrepo") {
sh(". ~/TEST_ENV/bin/activate && python -m helpers --type-check --quality-check") sh(". ~/TEST_ENV/bin/activate && python -m chacha_cicd_helper --typecheck --qualitycheck")
script { script {
def jsonObj = readJSON file: "helpers-results/quality_check/metrics.json" def jsonObj = readJSON file: "helpers-results/cl_quality_check/metrics.json"
quality_score = new BigDecimal(jsonObj["GlobalScore"]) quality_score = new BigDecimal(jsonObj["GlobalScore"])
sz_quality_score = quality_score.setScale(2, RoundingMode.HALF_EVEN).toString() sz_quality_score = quality_score.setScale(2, RoundingMode.HALF_EVEN).toString()
badge_quality.setStatus(sz_quality_score) badge_quality.setStatus(sz_quality_score)
badge_quality.setColor(getColorScale(quality_score)) badge_quality.setColor(getColorScale(quality_score))
} }
sh(". ~/TEST_ENV/bin/activate && python -m helpers --complexity-check") sh(". ~/TEST_ENV/bin/activate && python -m chacha_cicd_helper --complexitycheck")
} }
} }
post { post {
always { always {
dir("gitrepo") { dir("gitrepo") {
publishCoverage adapters: [cobertura(mergeToOneReport: true, path: "helpers-results/types_check/cobertura.xml")] //publish coverage
junit 'helpers-results/types_check/junit.xml' recordCoverage( sourceDirectories: [[path: 'src']],
tools: [[parser: 'COBERTURA', pattern: 'helpers-results/cl_types_check/cobertura.xml']],
id: 'COBERTURA', name: 'COBERTURA Coverage',
sourceCodeRetention: 'EVERY_BUILD',)
//add type check to junit result set
junit 'helpers-results/cl_types_check/junit.xml'
//publish html reports files
publishHTML([ publishHTML([
reportDir: "helpers-results/quality_check", reportDir: "helpers-results/cl_quality_check",
reportFiles: "report.html", reportFiles: "report.html",
reportName: "quality-report", reportName: "quality-report",
allowMissing: false, allowMissing: false,
alwaysLinkToLastBuild: true, alwaysLinkToLastBuild: true,
keepAll: true]) keepAll: true])
publishHTML([ publishHTML([
reportDir: "helpers-results/types_check", reportDir: "helpers-results/cl_types_check",
reportFiles: "index.html", reportFiles: "index.html",
reportName: "types_check", reportName: "types_check",
allowMissing: false, allowMissing: false,
@@ -420,7 +459,7 @@ pipeline {
steps { steps {
plot([ csvFileName: 'plot-df7f03dc-8146-11ed-a1eb-0242ac120002.csv', plot([ csvFileName: 'plot-df7f03dc-8146-11ed-a1eb-0242ac120002.csv',
csvSeries: [[ file: 'gitrepo/helpers-results/quality_check/metrics_GlobalScore.csv', inclusionFlag: 'OFF', url: '']], csvSeries: [[ file: 'gitrepo/helpers-results/cl_quality_check/metrics_GlobalScore.csv', inclusionFlag: 'OFF', url: '']],
group: 'metrics', group: 'metrics',
title: 'code quality score', title: 'code quality score',
style: 'line', style: 'line',
@@ -430,7 +469,7 @@ pipeline {
yaxisMinimum: '0']) yaxisMinimum: '0'])
plot([ csvFileName: 'plot-c731cc84-8145-11ed-a1eb-0242ac120002.csv', plot([ csvFileName: 'plot-c731cc84-8145-11ed-a1eb-0242ac120002.csv',
csvSeries: [[ file: 'gitrepo/helpers-results/quality_check/metrics_rawpercent.csv', inclusionFlag: 'OFF', url: '']], csvSeries: [[ file: 'gitrepo/helpers-results/cl_quality_check/metrics_rawpercent.csv', inclusionFlag: 'OFF', url: '']],
group: 'metrics', group: 'metrics',
title: 'code composition (%)', title: 'code composition (%)',
style: 'stackedArea', style: 'stackedArea',
@@ -440,7 +479,7 @@ pipeline {
yaxisMinimum: '0']) yaxisMinimum: '0'])
plot([ csvFileName: 'plot-cac33982-8145-11ed-a1eb-0242ac120002.csv', plot([ csvFileName: 'plot-cac33982-8145-11ed-a1eb-0242ac120002.csv',
csvSeries: [[ file: 'gitrepo/helpers-results/quality_check/metrics_Statistics.csv', inclusionFlag: 'OFF', url: '']], csvSeries: [[ file: 'gitrepo/helpers-results/cl_quality_check/metrics_Statistics.csv', inclusionFlag: 'OFF', url: '']],
group: 'metrics', group: 'metrics',
title: 'general statistics', title: 'general statistics',
style: 'line', style: 'line',
@@ -448,7 +487,7 @@ pipeline {
numBuilds: '']) numBuilds: ''])
plot([ csvFileName: 'plot-cddaced2-8145-11ed-a1eb-0242ac120002.csv', plot([ csvFileName: 'plot-cddaced2-8145-11ed-a1eb-0242ac120002.csv',
csvSeries: [[ file: 'gitrepo/helpers-results/quality_check/metrics_MessagesCat.csv', inclusionFlag: 'OFF', url: '']], csvSeries: [[ file: 'gitrepo/helpers-results/cl_quality_check/metrics_MessagesCat.csv', inclusionFlag: 'OFF', url: '']],
group: 'metrics', group: 'metrics',
title: 'quality warnings', title: 'quality warnings',
style: 'stackedArea', style: 'stackedArea',
@@ -456,7 +495,7 @@ pipeline {
numBuilds: '']) numBuilds: ''])
plot([ csvFileName: 'plot-4ceb9ee2-ca78-11ed-afa1-0242ac120002.csv', 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: '']], csvSeries: [[ file: 'gitrepo/helpers-results/cl_complexity_check/MI.csv', inclusionFlag: 'INCLUDE_BY_STRING',exclusionValues: 'MeanMaintainability', url: '']],
group: 'metrics', group: 'metrics',
title: 'maintainability', title: 'maintainability',
style: 'stackedArea', style: 'stackedArea',
@@ -468,14 +507,14 @@ pipeline {
stage("RunUnitTests") { stage("RunUnitTests") {
steps { steps {
dir("gitrepo") { dir("gitrepo") {
sh(". ~/TEST_ENV/bin/activate && python -m helpers --unit-test --coverage-check") sh(". ~/TEST_ENV/bin/activate && python -m chacha_cicd_helper --unittest --coveragecheck")
script { script {
unit_test_full_name__html=findFiles(glob: "helpers-results/unit_test_full/*.html")[0].getName() unit_test_full_name__html=findFiles(glob: "helpers-results/cl_unit_test_full/*.html")[0].getName()
println unit_test_full_name__html println unit_test_full_name__html
unit_test_full_name__xml=findFiles(glob: "helpers-results/unit_test_full/*.xml")[0].getName() unit_test_full_name__xml=findFiles(glob: "helpers-results/cl_unit_test_full/*.xml")[0].getName()
println unit_test_full_name__xml println unit_test_full_name__xml
coverage_report_path = "helpers-results/unit_test_coverage/test_coverage.xml" coverage_report_path = "helpers-results/cl_unit_test_coverage/test_coverage.xml"
println GetCoverageValue_lines_valid(coverage_report_path) println GetCoverageValue_lines_valid(coverage_report_path)
println GetCoverageValue_lines_covered(coverage_report_path) println GetCoverageValue_lines_covered(coverage_report_path)
println GetCoverageValue_line_rate(coverage_report_path) println GetCoverageValue_line_rate(coverage_report_path)
@@ -490,7 +529,7 @@ pipeline {
badge_coverage.setColor(getColorScale(full_rate)) badge_coverage.setColor(getColorScale(full_rate))
//badge_maintainability //badge_maintainability
records = readCSV file: 'helpers-results/complexity_check/MI.csv' records = readCSV file: 'helpers-results/cl_complexity_check/MI.csv'
maintainability = records[1][1] maintainability = records[1][1]
badge_maintainability.setStatus(maintainability) badge_maintainability.setStatus(maintainability)
@@ -505,11 +544,11 @@ pipeline {
post { post {
always { always {
dir("gitrepo") { dir("gitrepo") {
junit 'helpers-results/unit_test/*.xml' junit 'helpers-results/cl_unit_test/*.xml'
// using cobertura format (= coverage xml format) // using cobertura format (= coverage xml format)
publishCoverage adapters: [cobertura(mergeToOneReport: true, path: "helpers-results/unit_test_coverage/test_coverage.xml")] recordCoverage(tools: [[parser: 'COBERTURA', pattern: 'helpers-results/cl_unit_test_coverage/test_coverage.xml']])
publishHTML([ publishHTML([
reportDir: "helpers-results/unit_test_coverage", reportDir: "helpers-results/cl_unit_test_coverage",
reportFiles: "index.html", reportFiles: "index.html",
reportName: "coverage-report-html", reportName: "coverage-report-html",
allowMissing: false, allowMissing: false,
@@ -517,7 +556,7 @@ pipeline {
keepAll: true]) keepAll: true])
publishHTML([ publishHTML([
reportDir: "helpers-results/unit_test_full", reportDir: "helpers-results/cl_unit_test_full",
reportFiles: unit_test_full_name__html, reportFiles: unit_test_full_name__html,
reportName: "test-reports-full", reportName: "test-reports-full",
allowMissing: false, allowMissing: false,
@@ -531,15 +570,14 @@ pipeline {
stage("GenDOC") { stage("GenDOC") {
steps { steps {
dir("gitrepo") { dir("gitrepo") {
//--doc-gen-pdf sh(". ~/TEST_ENV/bin/activate && python -m chacha_cicd_helper --docgen --docgenpdf")
sh(". ~/TEST_ENV/bin/activate && python -m helpers --doc-gen --doc-gen-pdf")
} }
} }
post { post {
always { always {
dir("gitrepo") { dir("gitrepo") {
publishHTML([ publishHTML([
reportDir: "helpers-results/doc_gen/site", reportDir: "helpers-results/cl_doc_gen/site",
reportFiles: "index.html", reportFiles: "index.html",
reportName: "doc-html", reportName: "doc-html",
allowMissing: false, allowMissing: false,
@@ -571,10 +609,6 @@ pipeline {
|from simple_rest_client.api import API |from simple_rest_client.api import API
|from simple_rest_client.resource import Resource |from simple_rest_client.resource import Resource
| |
|try:
| from pychangelogfactory import ChangelogFactory
|except ImportError:
| from src.pychangelogfactory import ChangelogFactory
| |
|try: |try:
| from pygitversionhelper import gitversionhelper | from pygitversionhelper import gitversionhelper
@@ -623,9 +657,7 @@ pipeline {
| + "\\n" \\ | + "\\n" \\
| + "Reference documentation: [mkdocs page](https://chacha.ddns.net/mkdocs-web/${_PROJECT_USER_NAME}/${PY_PROJECT_NAME}/${_GIT_BRANCH}/${PY_PROJECT_VERSION_STRIPPED}/) " | + "Reference documentation: [mkdocs page](https://chacha.ddns.net/mkdocs-web/${_PROJECT_USER_NAME}/${PY_PROJECT_NAME}/${_GIT_BRANCH}/${PY_PROJECT_VERSION_STRIPPED}/) "
| |
|LastTag=gitversionhelper.tag.getLastTag(same_branch=True) |Changelog='''${CHANGELOG}'''
|CommitHistory=gitversionhelper.commit.getMessagesSinceTag(LastTag, merged_output=True, ignore_merged=True)
|Changelog = ChangelogFactory(CommitHistory).RenderFullChangelog(include_unknown=True)
| |
|ReleaseContent = ReleaseContent + "\\n"+ "\\n"+ "## Changelog:\\n" + Changelog |ReleaseContent = ReleaseContent + "\\n"+ "\\n"+ "## Changelog:\\n" + Changelog
| |
@@ -650,11 +682,11 @@ pipeline {
| |
|data = { |data = {
| "name": "Documentation (pdf)", | "name": "Documentation (pdf)",
| 'attachment': ("${PY_PROJECT_NAME}_${PY_PROJECT_VERSION}_UserManual.pdf", open("helpers-results/doc_gen/site/pdf/manual.pdf", 'rb')), | 'attachment': ("${PY_PROJECT_NAME}_${PY_PROJECT_VERSION}_UserManual.pdf", open("helpers-results/cl_doc_gen/site/pdf/manual.pdf", 'rb')),
|} |}
|GiteaApi.assets.post("${_PROJECT_USER_NAME}","${PY_PROJECT_NAME}",new_release_id,files=data) |GiteaApi.assets.post("${_PROJECT_USER_NAME}","${PY_PROJECT_NAME}",new_release_id,files=data)
| |
|shutil.make_archive("doc", 'zip', "helpers-results/doc_gen/site") |shutil.make_archive("doc", 'zip', "helpers-results/cl_doc_gen/site")
|reqData={ |reqData={
| "SECRET": "${MKDOCSTOKEN}", | "SECRET": "${MKDOCSTOKEN}",
| "USER": "${_PROJECT_USER_NAME}", | "USER": "${_PROJECT_USER_NAME}",

View File

@@ -2,14 +2,15 @@
<launchConfiguration type="org.python.pydev.debug.regularLaunchConfigurationType"> <launchConfiguration type="org.python.pydev.debug.regularLaunchConfigurationType">
<booleanAttribute key="org.eclipse.debug.core.ATTR_FORCE_SYSTEM_CONSOLE_ENCODING" value="false"/> <booleanAttribute key="org.eclipse.debug.core.ATTR_FORCE_SYSTEM_CONSOLE_ENCODING" value="false"/>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS"> <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
<listEntry value="/${project_name}/helpers"/> <listEntry value="/pygitversionhelper/helpers_proxy"/>
</listAttribute> </listAttribute>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES"> <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
<listEntry value="2"/> <listEntry value="2"/>
</listAttribute> </listAttribute>
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="${project_loc}/helpers"/> <stringAttribute key="org.eclipse.debug.ui.ATTR_CONSOLE_ENCODING" value="UTF-8"/>
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="${workspace_loc:pygitversionhelper/helpers_proxy}"/>
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_OTHER_WORKING_DIRECTORY" value=""/> <stringAttribute key="org.eclipse.ui.externaltools.ATTR_OTHER_WORKING_DIRECTORY" value=""/>
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_TOOL_ARGUMENTS" value="--complexity-check"/> <stringAttribute key="org.eclipse.ui.externaltools.ATTR_TOOL_ARGUMENTS" value="--complexitycheck"/>
<stringAttribute key="org.python.pydev.debug.ATTR_INTERPRETER" value="__default"/> <stringAttribute key="org.python.pydev.debug.ATTR_INTERPRETER" value="__default"/>
<stringAttribute key="org.python.pydev.debug.ATTR_PROJECT" value="pygitversionhelper"/> <stringAttribute key="org.python.pydev.debug.ATTR_PROJECT" value="pygitversionhelper"/>
<stringAttribute key="process_factory_id" value="org.python.pydev.debug.processfactory.PyProcessFactory"/> <stringAttribute key="process_factory_id" value="org.python.pydev.debug.processfactory.PyProcessFactory"/>

View File

@@ -2,17 +2,15 @@
<launchConfiguration type="org.python.pydev.debug.regularLaunchConfigurationType"> <launchConfiguration type="org.python.pydev.debug.regularLaunchConfigurationType">
<booleanAttribute key="org.eclipse.debug.core.ATTR_FORCE_SYSTEM_CONSOLE_ENCODING" value="false"/> <booleanAttribute key="org.eclipse.debug.core.ATTR_FORCE_SYSTEM_CONSOLE_ENCODING" value="false"/>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS"> <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
<listEntry value="/${project_name}/helpers"/> <listEntry value="/pygitversionhelper/helpers_proxy"/>
</listAttribute> </listAttribute>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES"> <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
<listEntry value="2"/> <listEntry value="2"/>
</listAttribute> </listAttribute>
<mapAttribute key="org.eclipse.debug.core.environmentVariables"> <stringAttribute key="org.eclipse.debug.ui.ATTR_CONSOLE_ENCODING" value="UTF-8"/>
<mapEntry key="PATH" value="C:\Program Files\GTK3-Runtime Win64\bin"/> <stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="${workspace_loc:pygitversionhelper/helpers_proxy}"/>
</mapAttribute>
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="${project_loc}/helpers"/>
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_OTHER_WORKING_DIRECTORY" value=""/> <stringAttribute key="org.eclipse.ui.externaltools.ATTR_OTHER_WORKING_DIRECTORY" value=""/>
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_TOOL_ARGUMENTS" value="--doc-gen --doc-gen-pdf"/> <stringAttribute key="org.eclipse.ui.externaltools.ATTR_TOOL_ARGUMENTS" value="--docgen --docgenpdf"/>
<stringAttribute key="org.python.pydev.debug.ATTR_INTERPRETER" value="__default"/> <stringAttribute key="org.python.pydev.debug.ATTR_INTERPRETER" value="__default"/>
<stringAttribute key="org.python.pydev.debug.ATTR_PROJECT" value="pygitversionhelper"/> <stringAttribute key="org.python.pydev.debug.ATTR_PROJECT" value="pygitversionhelper"/>
<stringAttribute key="process_factory_id" value="org.python.pydev.debug.processfactory.PyProcessFactory"/> <stringAttribute key="process_factory_id" value="org.python.pydev.debug.processfactory.PyProcessFactory"/>

View File

@@ -2,14 +2,15 @@
<launchConfiguration type="org.python.pydev.debug.regularLaunchConfigurationType"> <launchConfiguration type="org.python.pydev.debug.regularLaunchConfigurationType">
<booleanAttribute key="org.eclipse.debug.core.ATTR_FORCE_SYSTEM_CONSOLE_ENCODING" value="false"/> <booleanAttribute key="org.eclipse.debug.core.ATTR_FORCE_SYSTEM_CONSOLE_ENCODING" value="false"/>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS"> <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
<listEntry value="/${project_name}/helpers"/> <listEntry value="/pygitversionhelper/helpers_proxy"/>
</listAttribute> </listAttribute>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES"> <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
<listEntry value="2"/> <listEntry value="2"/>
</listAttribute> </listAttribute>
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="${project_loc}/helpers"/> <stringAttribute key="org.eclipse.debug.ui.ATTR_CONSOLE_ENCODING" value="UTF-8"/>
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="${workspace_loc:pygitversionhelper/helpers_proxy}"/>
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_OTHER_WORKING_DIRECTORY" value=""/> <stringAttribute key="org.eclipse.ui.externaltools.ATTR_OTHER_WORKING_DIRECTORY" value=""/>
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_TOOL_ARGUMENTS" value="--type-check --quality-check"/> <stringAttribute key="org.eclipse.ui.externaltools.ATTR_TOOL_ARGUMENTS" value="--qualitycheck"/>
<stringAttribute key="org.python.pydev.debug.ATTR_INTERPRETER" value="__default"/> <stringAttribute key="org.python.pydev.debug.ATTR_INTERPRETER" value="__default"/>
<stringAttribute key="org.python.pydev.debug.ATTR_PROJECT" value="pygitversionhelper"/> <stringAttribute key="org.python.pydev.debug.ATTR_PROJECT" value="pygitversionhelper"/>
<stringAttribute key="process_factory_id" value="org.python.pydev.debug.processfactory.PyProcessFactory"/> <stringAttribute key="process_factory_id" value="org.python.pydev.debug.processfactory.PyProcessFactory"/>

View File

@@ -2,14 +2,15 @@
<launchConfiguration type="org.python.pydev.debug.regularLaunchConfigurationType"> <launchConfiguration type="org.python.pydev.debug.regularLaunchConfigurationType">
<booleanAttribute key="org.eclipse.debug.core.ATTR_FORCE_SYSTEM_CONSOLE_ENCODING" value="false"/> <booleanAttribute key="org.eclipse.debug.core.ATTR_FORCE_SYSTEM_CONSOLE_ENCODING" value="false"/>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS"> <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
<listEntry value="/${project_name}/helpers"/> <listEntry value="/pygitversionhelper/helpers_proxy"/>
</listAttribute> </listAttribute>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES"> <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
<listEntry value="2"/> <listEntry value="2"/>
</listAttribute> </listAttribute>
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="${project_loc}/helpers"/> <stringAttribute key="org.eclipse.debug.ui.ATTR_CONSOLE_ENCODING" value="UTF-8"/>
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="${workspace_loc:pygitversionhelper/helpers_proxy}"/>
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_OTHER_WORKING_DIRECTORY" value=""/> <stringAttribute key="org.eclipse.ui.externaltools.ATTR_OTHER_WORKING_DIRECTORY" value=""/>
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_TOOL_ARGUMENTS" value="--changelog-gen"/> <stringAttribute key="org.eclipse.ui.externaltools.ATTR_TOOL_ARGUMENTS" value="--typecheck"/>
<stringAttribute key="org.python.pydev.debug.ATTR_INTERPRETER" value="__default"/> <stringAttribute key="org.python.pydev.debug.ATTR_INTERPRETER" value="__default"/>
<stringAttribute key="org.python.pydev.debug.ATTR_PROJECT" value="pygitversionhelper"/> <stringAttribute key="org.python.pydev.debug.ATTR_PROJECT" value="pygitversionhelper"/>
<stringAttribute key="process_factory_id" value="org.python.pydev.debug.processfactory.PyProcessFactory"/> <stringAttribute key="process_factory_id" value="org.python.pydev.debug.processfactory.PyProcessFactory"/>

View File

@@ -2,14 +2,15 @@
<launchConfiguration type="org.python.pydev.debug.regularLaunchConfigurationType"> <launchConfiguration type="org.python.pydev.debug.regularLaunchConfigurationType">
<booleanAttribute key="org.eclipse.debug.core.ATTR_FORCE_SYSTEM_CONSOLE_ENCODING" value="false"/> <booleanAttribute key="org.eclipse.debug.core.ATTR_FORCE_SYSTEM_CONSOLE_ENCODING" value="false"/>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS"> <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
<listEntry value="/${project_name}/helpers"/> <listEntry value="/pygitversionhelper/helpers_proxy"/>
</listAttribute> </listAttribute>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES"> <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
<listEntry value="2"/> <listEntry value="2"/>
</listAttribute> </listAttribute>
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="${project_loc}/helpers"/> <stringAttribute key="org.eclipse.debug.ui.ATTR_CONSOLE_ENCODING" value="UTF-8"/>
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="${workspace_loc:pygitversionhelper/helpers_proxy}"/>
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_OTHER_WORKING_DIRECTORY" value=""/> <stringAttribute key="org.eclipse.ui.externaltools.ATTR_OTHER_WORKING_DIRECTORY" value=""/>
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_TOOL_ARGUMENTS" value="--unit-test --coverage-check"/> <stringAttribute key="org.eclipse.ui.externaltools.ATTR_TOOL_ARGUMENTS" value="--unittest --coveragecheck"/>
<stringAttribute key="org.python.pydev.debug.ATTR_INTERPRETER" value="__default"/> <stringAttribute key="org.python.pydev.debug.ATTR_INTERPRETER" value="__default"/>
<stringAttribute key="org.python.pydev.debug.ATTR_PROJECT" value="pygitversionhelper"/> <stringAttribute key="org.python.pydev.debug.ATTR_PROJECT" value="pygitversionhelper"/>
<stringAttribute key="process_factory_id" value="org.python.pydev.debug.processfactory.PyProcessFactory"/> <stringAttribute key="process_factory_id" value="org.python.pydev.debug.processfactory.PyProcessFactory"/>

View File

@@ -135,6 +135,6 @@ kwargs available to this function:
There is unfortunately some technical limitation : There is unfortunately some technical limitation :
* MultiThreading and async behavior is not tested. * MultiThreading and async behavior is not tested / supported.
* Multiple tag on the same commit is not supported. * Multiple tag on the same commit is not supported.
* Branch filter when searching for a version is only tested with -no-ff strategy * Branch filter when searching for a version is only tested with -no-ff strategy

1
helpers/.gitignore vendored
View File

@@ -1 +0,0 @@
/.mypy_cache/

View File

@@ -1,7 +0,0 @@
# 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/>.

View File

@@ -1,116 +0,0 @@
# 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 tomli
import argparse
import os
import logging
import sys
if __package__ == "helpers":
# when calling the module from: > python -m helpers
from .types_check import types_check
from .quality_check import quality_check
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
from helpers.quality_check import quality_check
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)
if __name__ == "__main__":
project_rootdir_path = Path(__file__).parent.parent.absolute()
with open(project_rootdir_path / "pyproject.toml", mode="rb") as fp:
pyproject = tomli.load(fp)
parser = argparse.ArgumentParser(
prog="continuous-integration-helper", description="A tiny set of scripts to help continous integration on python"
)
parser.add_argument("-tc", "--type-check", dest="typecheck", action="store_true", help="enable static typing check")
parser.add_argument("-ut", "--unit-test", dest="unittest", action="store_true", help="enable unit-test")
parser.add_argument(
"-cc", "--coverage-check", dest="coveragecheck", action="store_true", help="enable unit-test coverage check (requires unit-test)"
)
parser.add_argument("-qc", "--quality-check", dest="qualitycheck", action="store_true", help="enable code quality check")
parser.add_argument("-dg", "--doc-gen", dest="docgen", action="store_true", help="enable documentation generation using MkDoc")
parser.add_argument(
"-pdf", "--doc-gen-pdf", dest="docgenpdf", action="store_true", help="enable pdf documentation export (requires doc-gen)"
)
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()
##################################
# Dev / Debug forced toogles
#
# --------------------------------
#
# args.typecheck = True
# args.qualitycheck = True
# args.unittest = True
# args.coveragecheck = True
# args.docgen = True
# args.docgenpdf = True
# args.changeloggen = True
# args.complexitycheck = True
helpers = []
if args.typecheck == True:
helpers.append(types_check)
if args.unittest == True:
helpers.append(unit_test)
if args.coveragecheck == True:
if args.unittest == True:
unit_test.enable_coverage_check = True
else:
raise RuntimeError("unit-test is required to enable coverage-check")
if args.qualitycheck == True:
helpers.append(quality_check)
if args.docgen == True:
helpers.append(doc_gen)
if args.docgenpdf == True:
if args.docgen == True:
doc_gen.enable_gen_pdf = True
else:
raise RuntimeError("doc-gen is required to enable doc-gen-pdf")
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()
helper.do_job()

View File

@@ -1,23 +0,0 @@
# 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 datetime
from .helper_base import helper_base
class changelog_gen(helper_base):
@classmethod
def do_job(cls):
pass

View File

@@ -1,69 +0,0 @@
# 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
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)

View File

@@ -1,98 +0,0 @@
# 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
import shutil
import os
import sys
import subprocess
from pathlib import Path
from distutils.dir_util import copy_tree
import yaml
try:
from yaml import CLoader as Loader, CDumper as Dumper
except ImportError:
from yaml import Loader, Dumper
from .helper_base import helper_withresults_base
class doc_gen(helper_withresults_base):
enable_gen_pdf: bool = False
@classmethod
def do_job(cls):
# create doc root dir
doc_path = cls.project_rootdir_path / "docs"
cls._reset_dir(doc_path)
site_path = cls.get_result_dir() / "site"
cls._reset_dir(site_path)
# copy files from main project dir
shutil.copyfile(str(cls.project_rootdir_path / "README.md"), str(doc_path / "README.md"))
shutil.copyfile(str(cls.project_rootdir_path / "LICENSE.md"), str(doc_path / "LICENSE.md"))
# copy files from static-doc dir
copy_tree(str(cls.project_rootdir_path / "docs-static"), str(doc_path))
# generating API doc + nav from python docstrings
reference_path = doc_path / "reference"
cls._reset_dir(reference_path)
for path in sorted((cls.project_rootdir_path / "src").rglob("*.py")):
module_path = path.relative_to(cls.project_rootdir_path / "src").with_suffix("")
doc_path = path.relative_to(cls.project_rootdir_path / "src").with_suffix(".md")
full_doc_path = Path(reference_path, doc_path)
parts = list(module_path.parts)
if parts[-1] == "__init__":
parts = parts[:-1]
elif parts[-1] == "__main__":
continue
cls._reset_dir(os.path.dirname(full_doc_path))
with open(full_doc_path, "w+") as fd:
identifier = "src." + ".".join(parts)
print("::: " + identifier, file=fd)
cmdopts = [f"{sys.executable}", "-m", "mkdocs", "-v", "build", "--site-dir", str(site_path), "--clean"]
# little hack here, to enable / disable pdf generation using own class config
# => reason is mkdocs seems to try loading the plugin even if we disable it, so we need to
# manually process the configuration file.
with open(cls.project_rootdir_path / "mkdocs.yml", "r") as mkdocsCfgFile:
mkdocsCfg = yaml.load(mkdocsCfgFile, Loader=yaml.Loader)
if "plugins" in mkdocsCfg:
mkdocsCfg["plugins"] = [_ for _ in mkdocsCfg["plugins"] if (not isinstance(_, dict) or "with-pdf" not in _.keys())]
if cls.enable_gen_pdf == True:
mkdocsCfg["plugins"].append(
{
"with-pdf": {
"cover_subtitle": "User Manual",
"cover_logo": str(cls.project_rootdir_path / "docs-static" / "Library.jpg"),
"verbose": False,
"exclude_pages": ["LICENSE"],
"output_path": str(site_path / "pdf" / "manual.pdf"),
}
}
)
with open(cls.project_rootdir_path / "mkdocs.yml", "w") as mkdocsCfgFile:
mkdocsCfgFile.write(yaml.dump(mkdocsCfg, Dumper=Dumper, default_flow_style=False, sort_keys=False))
res = cls.run_cmd(cmdopts)
print(res.decode())
print(" !! done")

View File

@@ -1,75 +0,0 @@
# 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 abc import ABC, abstractmethod
import os
from pathlib import Path
import subprocess
if TYPE_CHECKING: # Only imports the below statements during type checking
from typing import Union
class helper_base(ABC):
project_rootdir_path: Union[Path, None] = None
pyproject: Union[dict, None] = None
current_dir: Union[Path, None] = None
@classmethod
def set_context(cls, project_rootdir_path: Path, pyproject: dict):
cls.project_rootdir_path = project_rootdir_path
cls.pyproject = pyproject
cls.current_dir = Path(__file__).parent.absolute()
@classmethod
def get_result_dir(cls):
return None
@staticmethod
def _reset_dir(dirpath: Path):
dirpath = Path(dirpath)
if not os.path.exists(dirpath):
os.makedirs(dirpath)
[f.unlink() for f in Path(dirpath).glob("*") if f.is_file()]
@classmethod
def reset_result_dir(cls):
result_dir = cls.get_result_dir()
if result_dir != None:
cls._reset_dir(result_dir)
@classmethod
@abstractmethod
def do_job(cls):
raise NotImplementedError()
@classmethod
def run_cmd_(cls, cmdarray):
process = subprocess.run(cmdarray, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True, check=True)
return process.stdout
@classmethod
def run_cmd(cls, cmdarray, silent: bool = False):
p = subprocess.run(cmdarray, capture_output=True)
if not silent:
print(p.stdout.decode())
print(p.stderr.decode())
return p.stdout
class helper_withresults_base(helper_base):
helper_results_dir: Union[Path, None] = None
@classmethod
def get_result_dir(cls):
if cls.helper_results_dir == None:
cls.helper_results_dir = cls.__name__
return Path(__file__).parent.parent.absolute() / "helpers-results" / cls.helper_results_dir

View File

@@ -1,247 +0,0 @@
# 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 contextlib import redirect_stdout
from io import StringIO
import re
import json
from enum import Enum
from contextlib import suppress
import sys
import pandas
import csv
import copy
from pylint.lint import Run as pylint_Run
import pylint_json2html
from .helper_base import helper_withresults_base
class PyLintMetricNotFound(Warning):
pass
class quality_check(helper_withresults_base):
PylintMessageList = dict()
@classmethod
def GetPylintMessageList(cls):
Messagelist = dict()
regex = r"^:([a-zA-Z-]+) \(([^\)]+)\)"
for line in cls.run_cmd([sys.executable, "-m", "pylint", "--list-msgs"], True).splitlines():
if res := re.search(regex, line.decode()):
Messagelist[res.group(1)] = res.group(2)
cls.PylintMessageList = Messagelist
@staticmethod
def TryExtractPYReportMetric(line: str, tag: str):
regex = f"^(?:\|{tag}\s*\|)(\d+)(?=\s*|)"
if res := re.search(regex, line):
return float(res.group(1))
raise PyLintMetricNotFound()
@classmethod
def do_job(cls):
print("checking code quality ...")
cls.GetPylintMessageList()
RES_all = dict()
with StringIO() as StdOutput:
JsonContent = ""
with redirect_stdout(StdOutput):
pylint_Run(
[
"--load-plugins=pylint.extensions.mccabe",
"--output-format=json,parseable",
"--disable=invalid-name",
"--ignore=_version.py",
"--reports=y",
"--score=yes",
"--max-line-length=140",
"src." + cls.pyproject["project"]["name"],
],
exit=False,
)
with open(cls.get_result_dir() / "report.json", "w+", encoding="utf-8") as Outfile:
# hacky way of exctracting json + having overall score...
class TScanState(Enum):
TEXT_REPORT = 1
JSON_REPORT = 2
OTHER_REPORT_START = 3
OTHER_REPORT_STATISTICS = 4
OTHER_REPORT_METRICS = 5
OTHER_REPORT_DUPLICATION = 6
OTHER_REPORT_MESSAGES_CAT = 7
OTHER_REPORT_MESSAGES = 8
OTHER_REPORT_END = 99
RES_all["Statistics"] = dict()
RES_all["RawMetrics"] = dict()
RES_all["RawMetricsPercent"] = dict()
RES_all["Duplication"] = dict()
RES_all["MessagesCat"] = dict()
RES_all["Messages"] = dict()
RES_all["GlobalScore"] = -999
RES_all["NbAnalysedStatments"] = -999
RES_all["NbAnalysedLines"] = -999
ScanState = TScanState.TEXT_REPORT
for line in StdOutput.getvalue().split("\n"):
print(line)
if ScanState == TScanState.TEXT_REPORT:
# ignoring this part, we need json
if line == "[":
JsonContent += line
ScanState = TScanState.JSON_REPORT
elif line == "[]":
JsonContent += line
ScanState = TScanState.OTHER_REPORT_START
elif ScanState == TScanState.JSON_REPORT:
JsonContent += line
if line == "]":
ScanState = TScanState.OTHER_REPORT_START
elif ScanState == TScanState.OTHER_REPORT_START:
if res := re.search(r"^(\d+)(?= statements analysed.)", line):
RES_all["NbAnalysedStatments"] = float(res.group(1))
if line == "Statistics by type":
ScanState = TScanState.OTHER_REPORT_STATISTICS
elif ScanState == TScanState.OTHER_REPORT_STATISTICS:
if res := re.search(r"^(\d+)(?= lines have been analyzed)", line):
RES_all["NbAnalysedLines"] = float(res.group(1))
elif line == "Raw metrics":
ScanState = TScanState.OTHER_REPORT_METRICS
else:
with suppress(PyLintMetricNotFound):
RES_all["Statistics"]["module"] = cls.TryExtractPYReportMetric(line, "module")
with suppress(PyLintMetricNotFound):
RES_all["Statistics"]["class"] = cls.TryExtractPYReportMetric(line, "class")
with suppress(PyLintMetricNotFound):
RES_all["Statistics"]["method"] = cls.TryExtractPYReportMetric(line, "method")
with suppress(PyLintMetricNotFound):
RES_all["Statistics"]["function"] = cls.TryExtractPYReportMetric(line, "function")
elif ScanState == TScanState.OTHER_REPORT_METRICS:
if line == "Duplication":
RES_all["RawMetricsPercent"]["code"] = RES_all["RawMetrics"]["code"] / RES_all["NbAnalysedLines"]
RES_all["RawMetricsPercent"]["docstring"] = RES_all["RawMetrics"]["docstring"] / RES_all["NbAnalysedLines"]
RES_all["RawMetricsPercent"]["comment"] = RES_all["RawMetrics"]["comment"] / RES_all["NbAnalysedLines"]
RES_all["RawMetricsPercent"]["empty"] = RES_all["RawMetrics"]["empty"] / RES_all["NbAnalysedLines"]
ScanState = TScanState.OTHER_REPORT_DUPLICATION
else:
with suppress(PyLintMetricNotFound):
RES_all["RawMetrics"]["code"] = cls.TryExtractPYReportMetric(line, "code")
with suppress(PyLintMetricNotFound):
RES_all["RawMetrics"]["docstring"] = cls.TryExtractPYReportMetric(line, "docstring")
with suppress(PyLintMetricNotFound):
RES_all["RawMetrics"]["comment"] = cls.TryExtractPYReportMetric(line, "comment")
with suppress(PyLintMetricNotFound):
RES_all["RawMetrics"]["empty"] = cls.TryExtractPYReportMetric(line, "empty")
elif ScanState == TScanState.OTHER_REPORT_DUPLICATION:
if line == "Messages by category":
ScanState = TScanState.OTHER_REPORT_MESSAGES_CAT
else:
with suppress(PyLintMetricNotFound):
RES_all["Duplication"]["NbDupLines"] = cls.TryExtractPYReportMetric(line, "nb duplicated lines")
with suppress(PyLintMetricNotFound):
RES_all["Duplication"]["PersentDuplicatedLines"] = cls.TryExtractPYReportMetric(
line, "percent duplicated lines"
)
elif ScanState == TScanState.OTHER_REPORT_MESSAGES_CAT:
if line == "Messages":
ScanState = TScanState.OTHER_REPORT_MESSAGES
else:
with suppress(PyLintMetricNotFound):
RES_all["MessagesCat"]["Convention"] = cls.TryExtractPYReportMetric(line, "convention")
with suppress(PyLintMetricNotFound):
RES_all["MessagesCat"]["Refactor"] = cls.TryExtractPYReportMetric(line, "refactor")
with suppress(PyLintMetricNotFound):
RES_all["MessagesCat"]["Warning"] = cls.TryExtractPYReportMetric(line, "warning")
with suppress(PyLintMetricNotFound):
RES_all["MessagesCat"]["Error"] = cls.TryExtractPYReportMetric(line, "error")
elif ScanState == TScanState.OTHER_REPORT_MESSAGES:
# approx match because the number of '-' depend on screen width..
if line.startswith("--------"):
ScanState = TScanState.OTHER_REPORT_END
else:
for PylintMessage in cls.PylintMessageList.keys():
with suppress(PyLintMetricNotFound):
RES_all["Messages"][PylintMessage] = cls.TryExtractPYReportMetric(line, PylintMessage)
elif ScanState == TScanState.OTHER_REPORT_END:
if res := re.search(r"(?<=Your code has been rated at )(\d+(?:\.\d+)?)/10", line):
RES_all["GlobalScore"] = float(res.group(1))
print(RES_all["GlobalScore"])
else:
raise RuntimeError("Invalid ScanState")
Outfile.write(JsonContent)
with open(cls.get_result_dir() / "metrics.json", "w") as json_file:
json.dump(RES_all, json_file)
# exporting all Data in one csv, unused atm because jenkins seems not able to select columns from csv an keep displaying all...
# => to export a working full csv we need to a 'flat' dict (no more nested dict)
RES_all_trim = copy.deepcopy(RES_all)
del RES_all_trim["Messages"]
flat_RES_all = pandas.json_normalize(RES_all_trim, sep="_").to_dict(orient="records")[0]
with open(cls.get_result_dir() / "metrics.csv", "w", newline="") as csv_file:
writer = csv.DictWriter(csv_file, fieldnames=flat_RES_all.keys())
writer.writeheader()
writer.writerow(flat_RES_all)
# splited csv exports for jenkins plots: RawMetricsPercent
RES_all_percent = RES_all["RawMetricsPercent"]
with open(cls.get_result_dir() / "metrics_rawpercent.csv", "w", newline="") as csv_file:
writer = csv.DictWriter(csv_file, fieldnames=RES_all_percent.keys())
writer.writeheader()
writer.writerow(RES_all_percent)
# splited csv exports for jenkins plots: Statistics + Duplication + NbAnalysedStatments + NbAnalysedLines
RES_all_stats = copy.deepcopy(RES_all["Statistics"])
RES_all_stats["NbDupLines"] = RES_all["Duplication"]["NbDupLines"]
RES_all_stats["PersentDuplicatedLines"] = RES_all["Duplication"]["PersentDuplicatedLines"]
RES_all_stats["NbAnalysedStatments"] = RES_all["NbAnalysedStatments"]
RES_all_stats["NbAnalysedLines"] = RES_all["NbAnalysedLines"]
with open(cls.get_result_dir() / "metrics_Statistics.csv", "w", newline="") as csv_file:
writer = csv.DictWriter(csv_file, fieldnames=RES_all_stats.keys())
writer.writeheader()
writer.writerow(RES_all_stats)
# splited csv exports for jenkins plots: Statistics + Duplication
RES_all_MessagesCat = RES_all["MessagesCat"]
with open(cls.get_result_dir() / "metrics_MessagesCat.csv", "w", newline="") as csv_file:
writer = csv.DictWriter(csv_file, fieldnames=RES_all_MessagesCat.keys())
writer.writeheader()
writer.writerow(RES_all_MessagesCat)
# splited csv exports for jenkins plots: GlobalScore
RES_GlobalScore = {"GlobalScore": RES_all["GlobalScore"]}
with open(cls.get_result_dir() / "metrics_GlobalScore.csv", "w", newline="") as csv_file:
writer = csv.DictWriter(csv_file, fieldnames=RES_GlobalScore.keys())
writer.writeheader()
writer.writerow(RES_GlobalScore)
# converting the report using pylint_json2html (/!\ internal API, but as their is no leading '_' ...)
with open(cls.get_result_dir() / "report.html", "w+", encoding="utf-8") as Outfile:
raw_data = json.loads(JsonContent)
report = pylint_json2html.Report(raw_data)
Outfile.write(report.render())
print("Done")

View File

@@ -1,61 +0,0 @@
# 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
from mypy import api
from .helper_base import helper_withresults_base
class types_check(helper_withresults_base):
JUnitReportName = "junit.xml"
@classmethod
def do_job(cls):
print("checking code typing ...")
result = api.run(
[ # project path
"-p",
"src." + cls.pyproject["project"]["name"],
# analysis configuration
# "--show-traceback",
"--explicit-package-bases",
# "--strict-equality",
# "--check-untyped-defs",
"--enable-incomplete-feature=Unpack",
# reports generation
"--cobertura-xml-report",
str(cls.get_result_dir()),
"--html-report",
str(cls.get_result_dir()),
"--txt-report",
str(cls.get_result_dir()),
"--xml-report",
str(cls.get_result_dir()),
"--junit-xml",
str(cls.get_result_dir()) + "/" + cls.JUnitReportName,
]
)
if result[0]:
print("\nType checking report:\n")
print(result[0]) # stdout
# converting the report using pylint_json2html (/!\ internal API, but as their is no leading '_' ...)
with open(cls.get_result_dir() / "raw_eport.txt", "w+", encoding="utf-8") as Outfile:
Outfile.write(result[0])
if result[1]:
print("\nError report:\n")
print(result[1]) # stderr
print("\nExit status:", result[2])
print("Done")

View File

@@ -1,81 +0,0 @@
# 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 datetime
import unittest
import xmlrunner
from junitparser import JUnitXml
from junit2htmlreport import parser as junit2html_parser
from .helper_base import helper_withresults_base
class unit_test(helper_withresults_base):
enable_coverage_check: bool = False
enable_xml_export: bool = True
enable_full_xml_export: bool = True
FullReportName: str = "full_report"
CoverageReportName: str = "test_coverage"
@classmethod
def do_job(cls):
if cls.enable_coverage_check == True:
import coverage
# preparing unittest framework
test_loader = unittest.TestLoader()
if cls.enable_coverage_check == True:
# we start coverage now because module files discovery is part of the coverage measurement
CoverageReportPath = Path(str(cls.get_result_dir()) + "_coverage")
cls._reset_dir(CoverageReportPath)
cov = coverage.Coverage(cover_pylib=False, branch=True, source_pkgs=["src." + cls.pyproject["project"]["name"]])
cov.start()
package_tests = test_loader.discover(
start_dir=str(cls.project_rootdir_path / "test"), top_level_dir=str(cls.project_rootdir_path / "test")
)
if cls.enable_xml_export:
testRunner = xmlrunner.XMLTestRunner(output=str(str(cls.get_result_dir())))
else:
testRunner = unittest.TextTestRunner()
# running the test
testRunner.run(package_tests)
print("Test Finished")
if cls.enable_coverage_check == True:
cov.stop()
cov.save()
cov.html_report(directory=str(CoverageReportPath))
cov.xml_report(outfile=(CoverageReportPath / f"{cls.CoverageReportName}.xml"))
# computing results (Only if xml available)
if cls.enable_full_xml_export == True:
print("Full reports generation...")
FullReportPath = Path(str(cls.get_result_dir()) + "_full")
cls._reset_dir(FullReportPath)
FullJUnitReport = JUnitXml()
for fname in [fname for fname in os.listdir(cls.get_result_dir()) if fname.endswith(".xml")]:
FullJUnitReport += JUnitXml.fromfile(str(cls.get_result_dir() / fname))
current_datetime = datetime.datetime.utcnow().strftime("%Y%m%dT%H%M%SZ")
full_report_base_name = f'{cls.pyproject["project"]["name"]}-{cls.FullReportName}-{current_datetime}'
FullJUnitReport.write(str(FullReportPath / f"{full_report_base_name}.xml"))
report = junit2html_parser.Junit(FullReportPath / f"{full_report_base_name}.xml")
html = report.html()
with open(FullReportPath / f"{full_report_base_name}.html", "wb") as outfile:
outfile.write(html.encode("utf-8"))
print("Done")

View File

@@ -0,0 +1,5 @@
from chacha_cicd_helper.__main__ import fct_main
import sys
if __name__ == "__main__":
fct_main(sys.argv[1:])

View File

@@ -14,11 +14,11 @@ theme:
- navigation.tabs - navigation.tabs
- navigation.tabs.sticky - navigation.tabs.sticky
- navigation.footer - navigation.footer
- toc.integrate - navigation.path
- navigation.top - navigation.top
- navigation.section - navigation.section
- content.code.annotate - content.code.annotate
- navigation.prune - navigation.expand
- toc.follow - toc.follow
palette: palette:
- media: '(prefers-color-scheme: dark)' - media: '(prefers-color-scheme: dark)'
@@ -44,26 +44,30 @@ plugins:
default_handler: python default_handler: python
handlers: handlers:
python: python:
path:
- src
options: options:
filters: filters:
- '!^_[^_]' - '!^_[^_]'
inherited_members: true inherited_members: false
show_if_no_docstring: true show_if_no_docstring: true
show_signature_annotations: true show_signature_annotations: true
show_source: false show_source: false
show_category_heading: true show_category_heading: true
group_by_category: true group_by_category: true
docstring_section_style: spacy
show_root_full_path: false show_root_full_path: false
merge_init_into_class: true merge_init_into_class: true
separate_signature: true separate_signature: true
heading_level: 2
docstring_section_style: spacy
show_root_toc_entry: false
- with-pdf: - with-pdf:
cover_subtitle: User Manual cover_subtitle: User Manual
cover_logo: C:\Users\chacha\git\pygitversionhelper\docs-static\Library.jpg cover_logo: C:\Users\chacha\git\pygitversionhelper\docs-static\Library.jpg
verbose: false verbose: false
exclude_pages: exclude_pages:
- LICENSE - LICENSE
output_path: C:\Users\chacha\git\pygitversionhelper\helpers-results\doc_gen\site\pdf\manual.pdf output_path: C:\Users\chacha\git\pygitversionhelper\helpers-results\cl_doc_gen\site\pdf\manual.pdf
markdown_extensions: markdown_extensions:
- def_list - def_list
- tables - tables
@@ -110,8 +114,8 @@ markdown_extensions:
- footnotes - footnotes
- pymdownx.superfences - pymdownx.superfences
- pymdownx.emoji: - pymdownx.emoji:
emoji_index: !!python/name:materialx.emoji.twemoji emoji_index: !!python/name:materialx.emoji.twemoji ''
emoji_generator: !!python/name:materialx.emoji.to_svg emoji_generator: !!python/name:materialx.emoji.to_svg ''
extra: extra:
branch: master branch: master
repository: pygitversionhelper repository: pygitversionhelper

View File

@@ -46,7 +46,21 @@ include-package-data = true
where = ["src"] where = ["src"]
[tool.setuptools.package-data] [tool.setuptools.package-data]
"pygitversionhelper.data" = ["*.*"] "pysimpleini" = ["py.typed"]
# [[tool.mypy.overrides]]
# module = ""
# ignore_missing_imports = true
[tool.coverage.run]
cover_pylib = false
branch = true
data_file="helpers-results/cl_unit_test_raw_coverage/.coverage"
# debug = ["config","multiproc","process"]
parallel = true
concurrency = [
'thread'
]
[project.urls] [project.urls]
Homepage = "https://chacha.ddns.net/gitea/chacha/pygitversionhelper/" Homepage = "https://chacha.ddns.net/gitea/chacha/pygitversionhelper/"
@@ -54,13 +68,13 @@ Documentation = "https://chacha.ddns.net/mkdocs-web/chacha/pygitversionhelper/
Tracker = "https://chacha.ddns.net/gitea/chacha/pygitversionhelper/issues" Tracker = "https://chacha.ddns.net/gitea/chacha/pygitversionhelper/issues"
[project.optional-dependencies] [project.optional-dependencies]
test = ["junitparser>=2.8","junit2html>=30.1","xmlrunner>=1.7","mypy>=0.99" ] test = ["chacha_cicd_helper"]
coverage-check = ["coverage>=7.0"] coverage-check = ["chacha_cicd_helper"]
complexity-check = ["radon>=5.1"] complexity-check = ["chacha_cicd_helper"]
quality-check = ["pylint>=2.15","pylint-json2html>=0.4","pandas>=1.5"] quality-check = ["chacha_cicd_helper"]
type-check = ["mypy[reports]>=0.99" ] type-check = ["chacha_cicd_helper"]
doc-gen = ["mkdocs>=1.4.0", "mkdocs-material>=8.5","mkdocs-pymdownx-material-extras", "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"] doc-gen = ["chacha_cicd_helper"]
#[project.scripts] # [project.scripts]
#my-script = "my_package.module:function" # my-script = "my_package.module:function"

View File

@@ -1,7 +0,0 @@
# pygitversionhelper (c) by chacha
#
# pygitversionhelper 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/>.

View File

@@ -65,10 +65,12 @@ if TYPE_CHECKING:
def _exec(cmd: str, root: Optional[str | os.PathLike[str]] = None, raw: bool = False) -> str | List[str]: def _exec(cmd: str, root: Optional[str | os.PathLike[str]] = None, raw: bool = False) -> str | List[str]:
"""helper function to handle system cmd execution """helper function to handle system cmd execution
Args: Args:
cmd: command line to be executed cmd: command line to be executed
root: root directory where the command need to be executed root: root directory where the command need to be executed
raw: return bytes if True, str if False or None raw: return bytes if True, str if False or None
Returns: Returns:
a list of command's return lines or the raw output a list of command's return lines or the raw output
@@ -134,8 +136,10 @@ class gitversionhelper: # pylint: disable=too-few-public-methods
@classmethod @classmethod
def isDirty(cls) -> bool: def isDirty(cls) -> bool:
"""check if the repository is in dirty state """check if the repository is in dirty state
Returns: Returns:
True if it is dirty True if it is dirty
""" """
return bool(_exec("git status --short")) return bool(_exec("git status --short"))
@@ -151,21 +155,22 @@ class gitversionhelper: # pylint: disable=too-few-public-methods
@classmethod @classmethod
def getMessagesSinceTag(cls, tag: str, **kwargs: Unpack[TKwargs]) -> str | List[str]: def getMessagesSinceTag(cls, tag: str, **kwargs: Unpack[TKwargs]) -> str | List[str]:
"""Retrieve a commits message history from repository. """Retrieve a commits message history from repository.
Start from Latest found commit until the given tag. Start from Latest found commit until the given tag.
Args: Args:
tag: tag of the commit where search will stop tag (str): tag of the commit where search will stop
Keyword Arguments: Keyword Arguments:
kwargs/merged_output (bool): Output one single merged string kwargs/merged_output (bool): Output one single merged string
kwargs/same_branch (bool): Force searching only in the same branch kwargs/same_branch (bool): Force searching only in the same branch
kwargs/ignore_merged (bool): ignore merged commits kwargs/ignore_merged (bool): ignore merged commits
Returns: Returns:
the commit message the commit message
""" """
current_commit_id = cls.getLast(**kwargs) current_commit_id = cls.getLast(**kwargs)
print(f"current_commit_id = {current_commit_id}")
tag_commit_id = cls.getFromTag(tag) tag_commit_id = cls.getFromTag(tag)
print(f"tag_commit_id = {tag_commit_id}")
str_cmd: str str_cmd: str
if ("same_branch" in kwargs) and (kwargs["same_branch"] is True): if ("same_branch" in kwargs) and (kwargs["same_branch"] is True):
@@ -192,10 +197,13 @@ class gitversionhelper: # pylint: disable=too-few-public-methods
@classmethod @classmethod
def getMessage(cls, commit_hash: str) -> str: def getMessage(cls, commit_hash: str) -> str:
"""retrieve a commit message from repository """retrieve a commit message from repository
Args: Args:
commit_hash: id of the commit commit_hash: id of the commit
Returns: Returns:
the commit message the commit message
""" """
try: try:
res = _exec( res = _exec(
@@ -212,10 +220,13 @@ class gitversionhelper: # pylint: disable=too-few-public-methods
@classmethod @classmethod
def getFromTag(cls, tag: str) -> str: def getFromTag(cls, tag: str) -> str:
"""retrieve a commit from repository associated to a tag """retrieve a commit from repository associated to a tag
Args: Args:
tag: tag of the commit tag: tag of the commit
Returns: Returns:
the commit Id the commit Id
""" """
try: try:
res = _exec(f"git rev-list -n 1 {tag}") # ok res = _exec(f"git rev-list -n 1 {tag}") # ok
@@ -229,11 +240,14 @@ class gitversionhelper: # pylint: disable=too-few-public-methods
@classmethod @classmethod
def getLast(cls, **kwargs: Unpack[TKwargs]) -> str: def getLast(cls, **kwargs: Unpack[TKwargs]) -> str:
"""retrieve last commit from repository """retrieve last commit from repository
Keyword Arguments: Keyword Arguments:
kwargs/same_branch (bool): force searching only in the same branch kwargs/same_branch (bool): force searching only in the same branch
kwargs/ignore_merged (bool): ignore merged commits kwargs/ignore_merged (bool): ignore merged commits
Returns: Returns:
the commit Id the commit Id
""" """
str_cmd: str str_cmd: str
if ("same_branch" in kwargs) and (kwargs["same_branch"] is True): if ("same_branch" in kwargs) and (kwargs["same_branch"] is True):
@@ -278,12 +292,16 @@ class gitversionhelper: # pylint: disable=too-few-public-methods
@classmethod @classmethod
def getTags(cls, Sort: str = "taggerdate", **kwargs: Unpack[TKwargs]) -> List[str]: def getTags(cls, Sort: str = "taggerdate", **kwargs: Unpack[TKwargs]) -> List[str]:
"""retrieve all tags from a repository """retrieve all tags from a repository
Args: Args:
Sort: sorting constraints (git format) Sort: sorting constraints (git format)
Keyword Arguments: Keyword Arguments:
kwargs/same_branch (bool): force searching only in the same branch kwargs/same_branch (bool): force searching only in the same branch
Returns: Returns:
the tags list the tags list
""" """
if Sort not in cls.__validGitTagSort: if Sort not in cls.__validGitTagSort:
@@ -297,10 +315,13 @@ class gitversionhelper: # pylint: disable=too-few-public-methods
@classmethod @classmethod
def getLastTag(cls, **kwargs: Unpack[TKwargs]) -> str: def getLastTag(cls, **kwargs: Unpack[TKwargs]) -> str:
"""retrieve the Latest tag from a repository """retrieve the Latest tag from a repository
Keyword Arguments: Keyword Arguments:
kwargs/same_branch (bool): force searching only in the same branch kwargs/same_branch (bool): force searching only in the same branch
Returns: Returns:
the tag the tag
""" """
if ("same_branch" in kwargs) and (kwargs["same_branch"] is True): if ("same_branch" in kwargs) and (kwargs["same_branch"] is True):
res = _exec("git describe --tags --first-parent --abbrev=0") res = _exec("git describe --tags --first-parent --abbrev=0")
@@ -318,12 +339,16 @@ class gitversionhelper: # pylint: disable=too-few-public-methods
@classmethod @classmethod
def getDistanceFromTag(cls, tag: Optional[str] = None, **kwargs: Unpack[TKwargs]) -> int: def getDistanceFromTag(cls, tag: Optional[str] = None, **kwargs: Unpack[TKwargs]) -> int:
"""retrieve the distance between Latest commit and tag in the repository """retrieve the distance between Latest commit and tag in the repository
Arguments: Arguments:
tag: reference tag, if None the most recent one will be used tag: reference tag, if None the most recent one will be used
Keyword Arguments: Keyword Arguments:
kwargs/same_branch (bool): force searching only in the same branch kwargs/same_branch (bool): force searching only in the same branch
Returns: Returns:
the tag the tag
""" """
if tag is None: if tag is None:
tag = cls.getLastTag(**kwargs) tag = cls.getLastTag(**kwargs)
@@ -399,10 +424,13 @@ class gitversionhelper: # pylint: disable=too-few-public-methods
@classmethod @classmethod
def _getBumpDevStrategy(cls, **kwargs: Unpack[TKwargs]) -> str: def _getBumpDevStrategy(cls, **kwargs: Unpack[TKwargs]) -> str:
"""get selected bump_dev_strategy """get selected bump_dev_strategy
Keyword Arguments: Keyword Arguments:
kwargs/bump_dev_strategy (str): the given bump_dev_strategy (can be None) kwargs/bump_dev_strategy (str): the given bump_dev_strategy (can be None)
Returns: Returns:
Kwargs given bump_dev_strategy or the default one. Kwargs given bump_dev_strategy or the default one.
""" """
BumpDevStrategy: str = cls.DefaultBumpDevStrategy BumpDevStrategy: str = cls.DefaultBumpDevStrategy
@@ -416,10 +444,13 @@ class gitversionhelper: # pylint: disable=too-few-public-methods
@classmethod @classmethod
def _getBumpType(cls, **kwargs: Unpack[TKwargs]) -> str: def _getBumpType(cls, **kwargs: Unpack[TKwargs]) -> str:
"""get selected bump_type """get selected bump_type
Keyword Arguments: Keyword Arguments:
kwargs/bump_type (str): the given bump_type (can be None) kwargs/bump_type (str): the given bump_type (can be None)
Returns: Returns:
Kwargs given bump_type or the default one. Kwargs given bump_type or the default one.
""" """
BumpType: str = cls.DefaultBumpType BumpType: str = cls.DefaultBumpType
if "bump_type" in kwargs: if "bump_type" in kwargs:
@@ -433,13 +464,17 @@ class gitversionhelper: # pylint: disable=too-few-public-methods
self, amount: int = 1, **kwargs: Unpack[TKwargs] self, amount: int = 1, **kwargs: Unpack[TKwargs]
) -> gitversionhelper.version.MetaVersion | str: ) -> gitversionhelper.version.MetaVersion | str:
"""bump the version to the next one """bump the version to the next one
Args: Args:
amount: number of revision to bump amount: number of revision to bump
Keyword Arguments: Keyword Arguments:
kwargs/bump_type (str): the given bump_type (can be None) kwargs/bump_type (str): the given bump_type (can be None)
kwargs/bump_dev_strategy (str): the given bump_dev_strategy (can be None) kwargs/bump_dev_strategy (str): the given bump_dev_strategy (can be None)
Returns: Returns:
the bumped version the bumped version
""" """
BumpType: str = self._getBumpType(**kwargs) BumpType: str = self._getBumpType(**kwargs)
@@ -490,20 +525,26 @@ class gitversionhelper: # pylint: disable=too-few-public-methods
def doFormatVersion(self, **kwargs: Unpack[TKwargs]) -> str: def doFormatVersion(self, **kwargs: Unpack[TKwargs]) -> str:
"""output a formated version string """output a formated version string
Keyword Arguments: Keyword Arguments:
kwargs/output_format: output format to render ("Auto" or "PEP440" or "SemVer") kwargs/output_format: output format to render ("Auto" or "PEP440" or "SemVer")
Returns: Returns:
formated version string formated version string
""" """
return gitversionhelper.version.doFormatVersion(self, **kwargs) return gitversionhelper.version.doFormatVersion(self, **kwargs)
@classmethod @classmethod
def _getVersionStd(cls, **kwargs: Unpack[TKwargs]) -> gitversionhelper.version.MetaVersion.TVersionStd: def _getVersionStd(cls, **kwargs: Unpack[TKwargs]) -> gitversionhelper.version.MetaVersion.TVersionStd:
"""get selected version_std """get selected version_std
Keyword Arguments: Keyword Arguments:
kwargs/version_std (str): the given version_std (can be None) kwargs/version_std (str): the given version_std (can be None)
Returns: Returns:
Kwargs given version_std or the default one. Kwargs given version_std or the default one.
""" """
VersionStd: str = cls.DefaultInputFormat VersionStd: str = cls.DefaultInputFormat
if "version_std" in kwargs: if "version_std" in kwargs:
@@ -516,6 +557,7 @@ class gitversionhelper: # pylint: disable=too-few-public-methods
@classmethod @classmethod
def getCurrentVersion(cls, **kwargs: Unpack[TKwargs]) -> gitversionhelper.version.MetaVersion | str: def getCurrentVersion(cls, **kwargs: Unpack[TKwargs]) -> gitversionhelper.version.MetaVersion | str:
"""get the current version or bump depending of repository state. """get the current version or bump depending of repository state.
Keyword Arguments: Keyword Arguments:
kwargs/version_std (str): the given version_std (can be None) kwargs/version_std (str): the given version_std (can be None)
kwargs/same_branch (bool): force searching only in the same branch kwargs/same_branch (bool): force searching only in the same branch
@@ -523,8 +565,10 @@ class gitversionhelper: # pylint: disable=too-few-public-methods
kwargs/bump_type (str): the given bump_type (can be None) kwargs/bump_type (str): the given bump_type (can be None)
kwargs/bump_dev_strategy (str): the given bump_dev_strategy (can be None) kwargs/bump_dev_strategy (str): the given bump_dev_strategy (can be None)
kwargs/output_format (str): output format to render ("Auto" or "PEP440" or "SemVer") kwargs/output_format (str): output format to render ("Auto" or "PEP440" or "SemVer")
Returns: Returns:
the last version the last version
""" """
if gitversionhelper.repository.isDirty() is not False: if gitversionhelper.repository.isDirty() is not False:
raise gitversionhelper.repository.repositoryDirty("The repository is dirty and a current version can not be generated.") raise gitversionhelper.repository.repositoryDirty("The repository is dirty and a current version can not be generated.")
@@ -546,14 +590,17 @@ class gitversionhelper: # pylint: disable=too-few-public-methods
@classmethod @classmethod
def getCurrentFormatedVersion(cls, **kwargs: Unpack[TKwargs]) -> str: def getCurrentFormatedVersion(cls, **kwargs: Unpack[TKwargs]) -> str:
"""same as getCurrentVersion() with formated_output kwarg forced activated. """same as getCurrentVersion() with formated_output kwarg forced activated.
Keyword Arguments: Keyword Arguments:
kwargs/version_std (str): the given version_std (can be None) kwargs/version_std (str): the given version_std (can be None)
kwargs/same_branch (bool): force searching only in the same branch kwargs/same_branch (bool): force searching only in the same branch
kwargs/bump_type (str): the given bump_type (can be None) kwargs/bump_type (str): the given bump_type (can be None)
kwargs/bump_dev_strategy (str): the given bump_dev_strategy (can be None) kwargs/bump_dev_strategy (str): the given bump_dev_strategy (can be None)
kwargs/output_format (str): output format to render ("Auto" or "PEP440" or "SemVer") kwargs/output_format (str): output format to render ("Auto" or "PEP440" or "SemVer")
Returns: Returns:
the last version the last version
""" """
kwargs["formated_output"] = True kwargs["formated_output"] = True
return cast(str, cls.getCurrentVersion(**kwargs)) return cast(str, cls.getCurrentVersion(**kwargs))
@@ -563,12 +610,16 @@ class gitversionhelper: # pylint: disable=too-few-public-methods
cls, tag: str, **kwargs: Unpack[TKwargs] cls, tag: str, **kwargs: Unpack[TKwargs]
) -> gitversionhelper.version.MetaVersion: ) -> gitversionhelper.version.MetaVersion:
"""get version from tags. """get version from tags.
Arguments: Arguments:
tag: the tag to be parsed tag: the tag to be parsed
Keyword Arguments: Keyword Arguments:
kwargs/version_std (str): the given version_std (can be None) kwargs/version_std (str): the given version_std (can be None)
Returns: Returns:
MetaVersion object MetaVersion object
""" """
_m: Optional[re.Match[str]] _m: Optional[re.Match[str]]
VersionStd: gitversionhelper.version.MetaVersion.TVersionStd = cls._getVersionStd(**kwargs) VersionStd: gitversionhelper.version.MetaVersion.TVersionStd = cls._getVersionStd(**kwargs)
@@ -641,13 +692,16 @@ class gitversionhelper: # pylint: disable=too-few-public-methods
@classmethod @classmethod
def getLastVersion(cls, **kwargs: Unpack[TKwargs]) -> gitversionhelper.version.MetaVersion | str: # pylint: disable=R1260 def getLastVersion(cls, **kwargs: Unpack[TKwargs]) -> gitversionhelper.version.MetaVersion | str: # pylint: disable=R1260
"""get the last version from tags """get the last version from tags
Keyword Arguments: Keyword Arguments:
kwargs/version_std (str): the given version_std (can be None) kwargs/version_std (str): the given version_std (can be None)
kwargs/same_branch (bool): force searching only in the same branch kwargs/same_branch (bool): force searching only in the same branch
kwargs/formated_output (bool): output a formated version string kwargs/formated_output (bool): output a formated version string
kwargs/ignore_unknown_tags (bool): skip tags with not decoded versions (default to False) kwargs/ignore_unknown_tags (bool): skip tags with not decoded versions (default to False)
Returns: Returns:
the last version in MetaVersion object or string the last version in MetaVersion object or string
""" """
lastTag: str = cls.MetaVersion.raw lastTag: str = cls.MetaVersion.raw
cls.__versionReseted = False cls.__versionReseted = False
@@ -680,12 +734,16 @@ class gitversionhelper: # pylint: disable=too-few-public-methods
@classmethod @classmethod
def doFormatVersion(cls, inputversion: MetaVersion, **kwargs: Unpack[TKwargs]) -> str: def doFormatVersion(cls, inputversion: MetaVersion, **kwargs: Unpack[TKwargs]) -> str:
"""output a formated version string from a MetaVersion object """output a formated version string from a MetaVersion object
Keyword Arguments: Keyword Arguments:
kwargs/output_format (str): output format to render ("Auto" or "PEP440" or "SemVer") kwargs/output_format (str): output format to render ("Auto" or "PEP440" or "SemVer")
Args: Args:
inputversion: version to be rendered inputversion: version to be rendered
Returns: Returns:
formated version string formated version string
""" """
VersionStd = cls._getVersionStd(**kwargs) VersionStd = cls._getVersionStd(**kwargs)

View File

@@ -0,0 +1 @@
# PlaceHolder