1
0
mirror of https://github.com/CMiksche/gitea-auto-update synced 2025-12-10 16:07:23 +01:00

refactor: follow PEP standards

Follow Python Enhancement Proposals and add PyLint to enforce them.
This commit is contained in:
Christoph Miksche
2020-03-27 16:56:05 +01:00
parent ae8d54d018
commit b92496fc0d
11 changed files with 249 additions and 199 deletions

View File

@@ -8,4 +8,5 @@ install:
- pipenv install - pipenv install
script: script:
- gitlint - gitlint
- python tests.py - pylint setup.py gitea_auto_update
- python -m unittest

View File

@@ -7,3 +7,4 @@ All good contributions which add a new feature or close a issue will be accepted
1. Commit messages should follow the Angular Commit Message Format: https://github.com/angular/angular/blob/master/CONTRIBUTING.md#commit 1. Commit messages should follow the Angular Commit Message Format: https://github.com/angular/angular/blob/master/CONTRIBUTING.md#commit
2. New features should be added with a new function, if a new function is possible. 2. New features should be added with a new function, if a new function is possible.
3. Test-driven development (TDD) should be followed - this means you should always create unit tests for your function before you create the corresponding function. 3. Test-driven development (TDD) should be followed - this means you should always create unit tests for your function before you create the corresponding function.
4. You should use the linter

View File

@@ -11,6 +11,7 @@ packaging = "*"
fire = "*" fire = "*"
configparser = "*" configparser = "*"
gitlint = "*" gitlint = "*"
pylint = "*"
[requires] [requires]
python_version = "3.7" python_version = "3.7"

View File

@@ -67,9 +67,10 @@ The following instructions help you for developing.
* Clone this git repo * Clone this git repo
* Install pipenv: `pip install pipenv` * Install pipenv: `pip install pipenv`
* Install all dependencies: `pipenv install` * Install all dependencies: `pipenv install`
* You can run the tests with `python tests.py` * You can run the tests with `python -m unittest`
* You can run pylint with `pylint gitea_auto_update`
* After changes and commit, you can check if your commit message follows the contribution guidelines with `gitlint`. If there is a problem, gitlint will show you a error message. * After changes and commit, you can check if your commit message follows the contribution guidelines with `gitlint`. If there is a problem, gitlint will show you a error message.
* After pushing, you should check the build status which currently checks the tests and the commit message format. * After pushing, you should check the build status which currently checks the tests, pylint and the commit message format.
## Contributors ## Contributors

View File

@@ -1,24 +1,19 @@
''' '''
Gitea Auto Updater Gitea Auto Updater
Copyright 2018, 2019 The Gitea-Auto-Update Authors Copyright 2018, 2019, 2020 The Gitea-Auto-Update Authors
All rights reserved. All rights reserved.
License: GNU General Public License License: GNU General Public License
''' '''
import os import os
class Build:
def __init__(self, gtFile, sourceDir): def build_from_source(tag, gt_file, source_dir):
self.gtFile = gtFile """Function to build the new version from source"""
self.sourceDir = sourceDir os.chdir(source_dir)
os.system("git checkout master")
def fromSource(self, tag): os.system("git pull")
# Function to build the new version from source os.system("git checkout " + tag)
os.chdir(self.sourceDir) os.system('TAGS="bindata sqlite sqlite_unlock_notify" make generate build')
os.system("git checkout master") os.system("mv gitea " + gt_file)
os.system("git pull")
os.system("git checkout " + tag)
os.system('TAGS="bindata sqlite sqlite_unlock_notify" make generate build')
os.system("mv gitea " + self.gtFile)

View File

@@ -1,79 +1,91 @@
''' '''
Gitea Auto Updater Gitea Auto Updater
Copyright 2018, 2019 The Gitea-Auto-Update Authors Copyright 2018, 2019, 2020 The Gitea-Auto-Update Authors
All rights reserved. All rights reserved.
License: GNU General Public License License: GNU General Public License
''' '''
import requests
import os import os
import sys
import logging import logging
from shutil import which # from whichcraft import which from shutil import which # from whichcraft import which
import requests
def is_tool(name):
"""Function to check if tool is available"""
# Check whether `name` is on PATH and marked as executable.
return which(name) is not None
def download(url, file_name):
"""Function to download a file"""
# open in binary mode
with open(file_name, "wb") as file:
# get request
response = requests.get(url)
# write to file
file.write(response.content)
def sha_check():
"""Check sha for gitea file"""
return os.system("sha256sum -c gitea.xz.sha256 > /dev/null") == 0
class Download: class Download:
"""Class for downloading gitea"""
def __init__(self, tmpDir, githubVersion, githubVersionTag, gtSystem, gtFile): def __init__(self, tmp_dir, github_version_tag, gt_system, gt_file):
if not self.isTool("xz"): if not is_tool("xz"):
logging.error('Download: missing dependency: xz') logging.error('Download: missing dependency: xz')
quit() sys.exit()
self.tmpDir = tmpDir self.tmp_dir = tmp_dir
self.githubVersion = githubVersion self.github_version_tag = github_version_tag
self.githubVersionTag = githubVersionTag self.github_version = self.github_version_tag[1:]
self.gtSystem = gtSystem self.gt_system = gt_system
self.gtFile = gtFile self.gt_file = gt_file
self.downloadGiteaFiles() self.download_gitea_files()
self.checkAndExtract() self.check_and_extract()
def isTool(self, name): def download_gitea_files(self):
# Function to check if tool is available """Download gitea files"""
##Check whether `name` is on PATH and marked as executable.
return which(name) is not None
def download(self, url, fileName):
# Function to download a file
# open in binary mode
with open(fileName, "wb") as file:
# get request
response = requests.get(url)
# write to file
file.write(response.content)
def downloadGiteaFiles(self):
# Set download url # Set download url
gtDownload = 'https://github.com/go-gitea/gitea/releases/download/' + self.githubVersionTag + '/gitea-' + self.githubVersion + '-' + self.gtSystem + '.xz' gt_download = 'https://github.com/go-gitea/gitea/releases/download/' \
logging.info('Download: Gitea file: %s', gtDownload) + self.github_version_tag + '/gitea-' + self.github_version \
shaDownload = gtDownload + '.sha256' + '-' + self.gt_system + '.xz'
logging.info('Download: SHA file: %s', shaDownload) logging.info('Download: Gitea file: %s', gt_download)
sha_download = gt_download + '.sha256'
logging.info('Download: SHA file: %s', sha_download)
# Download file # Download file
logging.info('Download: downloading sha256 hashsum') logging.info('Download: downloading sha256 hashsum')
self.download(shaDownload, self.tmpDir + 'gitea.xz.sha256') download(sha_download, self.tmp_dir + 'gitea.xz.sha256')
logging.info('Download: downloading %s', self.githubVersionTag + 'gitea.xz') logging.info('Download: downloading %s', self.github_version_tag + 'gitea.xz')
self.tmpXz = self.tmpDir +'gitea-' + self.githubVersion + '-' + self.gtSystem + '.xz' self.tmp_xz = self.tmp_dir + 'gitea-' + self.github_version + '-' + self.gt_system + '.xz'
self.download(gtDownload, self.tmpXz) download(gt_download, self.tmp_xz)
def shaCheck(self): def extract_file(self):
return os.system("sha256sum -c gitea.xz.sha256 > /dev/null") == 0 """Extract gitea file"""
def extractFile(self):
logging.info('Download: sha ok, extracting file to location') logging.info('Download: sha ok, extracting file to location')
# extracting download file # extracting download file
cmd = "xz -d " + self.tmpXz cmd = "xz -d " + self.tmp_xz
os.system(cmd) os.system(cmd)
# moving temp file to gtfile location # moving temp file to gtfile location
cmd = 'mv ' + self.tmpDir + 'gitea-' + self.githubVersion + '-' + self.gtSystem + ' ' + self.gtFile cmd = 'mv ' + self.tmp_dir + 'gitea-' + self.github_version \
+ '-' + self.gt_system + ' ' + self.gt_file
os.system(cmd) os.system(cmd)
cmd = 'chmod +x ' + self.gtFile cmd = 'chmod +x ' + self.gt_file
os.system(cmd) os.system(cmd)
def checkAndExtract(self): def check_and_extract(self):
os.chdir(self.tmpDir) """Check file and extract"""
if self.shaCheck(): os.chdir(self.tmp_dir)
self.extractFile() if sha_check():
self.extract_file()
else: else:
logging.error('Download: error: sha256sum failed') logging.error('Download: error: sha256sum failed')
quit() sys.exit()

View File

@@ -0,0 +1,52 @@
'''
Gitea Auto Updater
Copyright 2019, 2020 The Gitea-Auto-Update Authors
All rights reserved.
License: GNU General Public License
'''
import unittest
import gitea_auto_update.lib.version
VERSION = gitea_auto_update.lib.version
class TestVersion(unittest.TestCase):
"""Test the version class"""
def test_simple_version(self):
"""1.9.1 should be newer than 1.9.0"""
self.assertTrue(VERSION.check_version('1.9.1', '1.9.0'))
def test_two_int_version(self):
"""1.10.0 should be newer than 1.9.0"""
self.assertTrue(VERSION.check_version('1.10.0', '1.9.0'))
def test_false_version(self):
"""1.8.0 should be older than 1.9.0"""
self.assertFalse(VERSION.check_version('1.8.0', '1.9.0'))
def test_same_version(self):
"""1.9.7 should be the same as 1.9.7"""
self.assertFalse(VERSION.check_version('1.9.7', '1.9.7'))
def test_int(self):
"""9 should be newer than 8"""
self.assertTrue(VERSION.check_version('9', '8'))
def test_suffix(self):
"""1.9.0+dev-264-g8de76b6e6 should be newer than 1.8.0"""
self.assertTrue(VERSION.check_version('1.9.0+dev-264-g8de76b6e6', '1.8.0'))
def test_parse_file_version(self):
"""It should get the version from a string"""
string = 'Gitea version 1.8.1 built with go1.12.2 : bindata, sqlite, sqlite_unlock_notify'
self.assertEqual(
VERSION.parse_file_version(string),
'1.8.1'
)
if __name__ == '__main__':
unittest.main()

View File

@@ -1,52 +1,60 @@
''' '''
Gitea Auto Updater Gitea Auto Updater
Copyright 2018, 2019 The Gitea-Auto-Update Authors Copyright 2018, 2019, 2020 The Gitea-Auto-Update Authors
All rights reserved. All rights reserved.
License: GNU General Public License License: GNU General Public License
''' '''
from packaging import version
import os import os
import requests
import logging import logging
from packaging import version
import requests
def get_github_version_tag(api_url):
"""Get the version from github"""
version_tag = requests.get(api_url).json()['tag_name']
logging.info('Version: github_version_tag = %s', version_tag)
return version_tag
def parse_file_version(string):
"""Get the version from a file"""
return string.split(" ")[2]
def check_version(new_version, old_version):
"""Function to check if there is a new version"""
return version.parse(new_version) > version.parse(old_version)
class Version: class Version:
"""Class to get and check the gitea version"""
def __init__(self, gtSite, gtFile): def __init__(self, gt_site, gt_file):
self.gtSite = gtSite self.gt_site = gt_site
self.gtFile = gtFile self.gt_file = gt_file
def checkVersion(self, newVersion, oldVersion): def get_version_from_file(self):
# Function to check if there is a new version """Read the version from the gitea file"""
return version.parse(newVersion) > version.parse(oldVersion) version_string = os.popen(self.gt_file + " -v").read()
return parse_file_version(version_string)
def parseFileVersion(self, string): def get_current_version(self):
return string.split(" ")[2] """Function to get the current version"""
def getVersionFromFile(self):
versionString = os.popen(self.gtFile + " -v").read()
return self.parseFileVersion(versionString)
def getCurrentVersion(self):
# Function to get the current version
try: try:
# Try to get the version from the file # Try to get the version from the file
currentVersion = self.getVersionFromFile() current_version = self.get_version_from_file()
except: except IOError:
# Get the version via the web api if the file does fail # Get the version via the web api if the file does fail
try: try:
currentVersion = requests.get(self.gtSite).json()['version'] current_version = requests.get(self.gt_site).json()['version']
if currentVersion.status_code != 200: if current_version.status_code != 200:
raise RuntimeError("Could not download version.") raise RuntimeError("Could not download version.")
except: except RuntimeError:
# To allow installation, return a default version of "0.0.0". # To allow installation, return a default version of "0.0.0".
currentVersion = "0.0.0" current_version = "0.0.0"
finally: finally:
logging.info('Version: current_version = %s', currentVersion) logging.info('Version: current_version = %s', current_version)
return currentVersion return current_version
def getGithubVersionTag(self, apiUrl):
versionTag = requests.get(apiUrl).json()['tag_name']
logging.info('Version: github_version_tag = %s', versionTag)
return versionTag

View File

@@ -1,7 +1,7 @@
''' '''
Gitea Auto Updater Gitea Auto Updater
Copyright 2018, 2019 The Gitea-Auto-Update Authors Copyright 2018, 2019, 2020 The Gitea-Auto-Update Authors
All rights reserved. All rights reserved.
License: GNU General Public License License: GNU General Public License
@@ -15,72 +15,80 @@ import gitea_auto_update.lib.version
import gitea_auto_update.lib.download import gitea_auto_update.lib.download
import gitea_auto_update.lib.build import gitea_auto_update.lib.build
class Update: class Update:
"""
Main class to update gitea
"""
def __init__(self, gtSite, gtFile, sourceDir, apiUrl, buildFromSource, tmpDir, gtSystem): def __init__(self,
self.gtSite = gtSite config):
self.gtFile = gtFile self.config = config
self.sourceDir = sourceDir
self.apiUrl = apiUrl
self.buildFromSource = buildFromSource
self.tmpDir = tmpDir
self.gtSystem = gtSystem
self.initVersionAndBuild() # Get version tag from github and remove first char (v)
self.getVersionAndTag() self.github_version_tag = gitea_auto_update.lib.version.get_github_version_tag(
self.checkAndUpdate() config.get('Gitea', 'apiUrl')
)
# Get version from version tag
self.github_version = self.github_version_tag[1:]
def initVersionAndBuild(self): self.check_and_update()
self.version = gitea_auto_update.lib.version.Version(self.gtSite, self.gtFile)
self.build = gitea_auto_update.lib.build.Build(self.gtFile, self.sourceDir)
def getVersionAndTag(self): def do_update(self):
self.currentVersion = self.version.getCurrentVersion() # Version from gitea site """Execute the update"""
self.githubVersionTag = self.version.getGithubVersionTag(self.apiUrl) # Get version tag from github and remove first char (v)
self.githubVersion = self.githubVersionTag[1:] # Get version from version tag
def doUpdate(self): # Should the new version be build from source?
if self.buildFromSource: # Should the new version be build from source? if self.config.get('Gitea', 'buildFromSource'):
self.build.fromSource(self.githubVersionTag) gitea_auto_update.lib.build.build_from_source(
self.github_version_tag,
self.config.get('Gitea', 'file'),
self.config.get('Gitea', 'sourceDir')
)
else: else:
self.download = gitea_auto_update.lib.download.Download(self.tmpDir, gitea_auto_update.lib.download.Download(
self.githubVersion, self.config.get('Gitea', 'tmpDir'),
self.githubVersionTag, self.github_version_tag,
self.gtSystem, self.config.get('Gitea', 'system'),
self.gtFile) self.config.get('Gitea', 'file')
)
def checkAndUpdate(self): def check_and_update(self):
if self.version.checkVersion(self.githubVersion, self.currentVersion): # Check if there is a new version """Check if a update is possible and do it if it is"""
# Version from gitea site
version = gitea_auto_update.lib.version.Version(
self.config.get('Gitea', 'site'),
self.config.get('Gitea', 'file')
)
current_version = version.get_current_version()
# Check if there is a new version
if gitea_auto_update.lib.version.check_version(self.github_version, current_version):
logging.info('Update: new version available, stopping service') logging.info('Update: new version available, stopping service')
os.system("systemctl stop gitea.service") os.system("systemctl stop gitea.service")
self.doUpdate() self.do_update()
logging.info('Update: starting gitea.service') logging.info('Update: starting gitea.service')
os.system("systemctl start gitea.service") os.system("systemctl start gitea.service")
print("update successfully") print("update successfully")
else: else:
print("current version is uptodate") print("current version is uptodate")
def updater(settings='settings.ini'): def updater(settings='settings.ini'):
"""Get the config and set logging"""
# Config # Config
config = configparser.ConfigParser() config = configparser.ConfigParser()
config.read(settings) config.read(settings)
# Create a log file # Create a log file
logging.basicConfig(filename=config.get('Gitea', 'logFile'), level=logging.DEBUG) logging.basicConfig(filename=config.get('Gitea', 'logFile'), level=logging.DEBUG)
# Start update # Start update
Update(config.get('Gitea', 'site'), Update(config)
config.get('Gitea', 'file'),
config.get('Gitea', 'sourceDir'),
config.get('Gitea', 'apiUrl'),
config.get('Gitea', 'buildFromSource'),
config.get('Gitea', 'tmpDir'),
config.get('Gitea', 'system'))
def main(): def main():
"""Main func"""
if not sys.version_info[0] == 3: if not sys.version_info[0] == 3:
sys.exit("Sorry, Python 2 is not supported. Please update to Python 3.") sys.exit("Sorry, Python 2 is not supported. Please update to Python 3.")
fire.Fire(updater) fire.Fire(updater)
if __name__ == '__main__': if __name__ == '__main__':
main() main()

View File

@@ -1,32 +1,41 @@
'''
Gitea Auto Updater
Copyright 2018, 2019, 2020 The Gitea-Auto-Update Authors
All rights reserved.
License: GNU General Public License
'''
import setuptools import setuptools
with open("README.md", "r") as fh: with open("README.md", "r") as fh:
long_description = fh.read() LONG_DESCRIPTION = fh.read()
setuptools.setup(name='gitea_auto_update', setuptools.setup(
version='2.0.7', name='gitea_auto_update',
description='A script which can update gitea to a new version.', version='2.0.7',
long_description=long_description, description='A script which can update gitea to a new version.',
long_description_content_type="text/markdown", long_description=LONG_DESCRIPTION,
url='https://github.com/CMiksche/gitea-auto-update', long_description_content_type="text/markdown",
author='Christoph Miksche', url='https://github.com/CMiksche/gitea-auto-update',
author_email='christoph@miksche.org', author='Christoph Miksche',
license='GPLv3', author_email='christoph@miksche.org',
classifiers=[ license='GPLv3',
"Programming Language :: Python :: 3", classifiers=[
"License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)", "Programming Language :: Python :: 3",
"Operating System :: Unix", "License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)",
], "Operating System :: Unix",
keywords=['gitea', 'update', 'debian', 'linux'], ],
python_requires='>=3', keywords=['gitea', 'update', 'debian', 'linux'],
install_requires=[ python_requires='>=3',
'requests', install_requires=[
'packaging', 'requests',
'fire', 'packaging',
'configparser' 'fire',
], 'configparser'
packages=setuptools.find_packages(), ],
entry_points={ packages=setuptools.find_packages(),
'console_scripts': ['gitea-auto-update=gitea_auto_update.update:main'], entry_points={
} 'console_scripts': ['gitea-auto-update=gitea_auto_update.update:main'],
) }
)

View File

@@ -1,38 +0,0 @@
'''
Gitea Auto Updater
Copyright 2019 The Gitea-Auto-Update Authors
All rights reserved.
License: GNU General Public License
'''
import gitea_auto_update.lib.version
import unittest
version = gitea_auto_update.lib.version.Version('', '')
class Tests(unittest.TestCase):
def testSimpleVersion(self):
self.assertTrue(version.checkVersion('1.9.1', '1.9.0'))
def testTwoIntVersion(self):
self.assertTrue(version.checkVersion('1.10.0', '1.9.0'))
def testFalseVersion(self):
self.assertFalse(version.checkVersion('1.8.0', '1.9.0'))
def testSameVersion(self):
self.assertFalse(version.checkVersion('1.9.7', '1.9.7'))
def testInt(self):
self.assertTrue(version.checkVersion('9', '8'))
def testSuffix(self):
self.assertTrue(version.checkVersion('1.9.0+dev-264-g8de76b6e6', '1.8.0'))
def testParseFileVersion(self):
self.assertEqual(version.parseFileVersion('Gitea version 1.8.1 built with go1.12.2 : bindata, sqlite, sqlite_unlock_notify'), '1.8.1')
if __name__ == '__main__':
unittest.main()