优化setup.py
This commit is contained in:
commit
6dc1c8a374
39
.github/workflows/continuous-integration-workflow.yml
vendored
Normal file
39
.github/workflows/continuous-integration-workflow.yml
vendored
Normal file
|
@ -0,0 +1,39 @@
|
|||
# This workflows will upload a Python Package using Twine when a release is created
|
||||
# For more information see: https://help.github.com/en/actions/language-and-framework-guides/using-python-with-github-actions#publishing-to-package-registries
|
||||
|
||||
# action的名称
|
||||
name: Upload Python Package gotwo
|
||||
|
||||
on:
|
||||
# 当master分支有push时,触发action
|
||||
push:
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
name: publish python package to PYPI
|
||||
# 此作业在 Linux 上运行
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
# 此步骤使用 GitHub 的 https://github.com/actions/checkout
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
# 安装依赖
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
python -m pip install wheel twine
|
||||
python -m pip install -r requirements.txt
|
||||
|
||||
# - name: Test Code
|
||||
# run: |
|
||||
# ./test.sh
|
||||
# 构建和发布
|
||||
- name: Build and publish
|
||||
env:
|
||||
TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }}
|
||||
TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
|
||||
run: |
|
||||
python setup.py sdist bdist_wheel
|
||||
twine upload dist/*
|
7
.gitignore
vendored
Normal file
7
.gitignore
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
build/
|
||||
dist/
|
||||
|
||||
pmpt.egg-info/
|
||||
*.tar.gz
|
||||
*.pyc
|
||||
__pycache__/
|
46
pmpt/__init__.py
Normal file
46
pmpt/__init__.py
Normal file
|
@ -0,0 +1,46 @@
|
|||
import click
|
||||
from . import update as updates
|
||||
from . import util
|
||||
from . import install as installs
|
||||
from . import search as searchs
|
||||
@click.group()
|
||||
def cli():
|
||||
util.init() # 初始化
|
||||
|
||||
@cli.command(short_help='Update Package Index')
|
||||
def update():
|
||||
# 调用更新函数
|
||||
updates.getAllIndex()
|
||||
|
||||
@cli.command(short_help='Install Python package')
|
||||
@click.argument('packlist',nargs=-1, required=True)
|
||||
@click.option('--upgrade','-U',is_flag=True,default=False)
|
||||
@click.option('--reads', '-r',is_flag=True,default=False)
|
||||
@click.option('--force-reinstall','-fr',is_flag=True,default=False)
|
||||
@click.option('--ignore-requires-python','-irp',is_flag=True,default=False)
|
||||
@click.option('--yes','-y',is_flag=True,default=False)
|
||||
def install(*args,**kwargs):
|
||||
installs.main(*args,**kwargs)
|
||||
|
||||
@cli.command(name='list',short_help='List all Python packages')
|
||||
def listp():
|
||||
util.runpip('list')
|
||||
|
||||
@cli.command()
|
||||
@click.argument('name')
|
||||
@click.option('--yes','-y',is_flag=True,default=False)
|
||||
def remove(name,yes):
|
||||
args = []
|
||||
if yes:
|
||||
args.append('-y')
|
||||
args.append(name)
|
||||
util.runpip('uninstall',args)
|
||||
|
||||
@cli.command()
|
||||
@click.argument('name')
|
||||
@click.option('--allinfo','-a',is_flag=True,default=False)
|
||||
@click.option('--api-url','-u',default=None)
|
||||
def search(*args, **kwargs):
|
||||
searchs.main(*args,**kwargs)
|
||||
if __name__ == '__main__':
|
||||
cli()
|
2
pmpt/__main__.py
Normal file
2
pmpt/__main__.py
Normal file
|
@ -0,0 +1,2 @@
|
|||
import pmpt
|
||||
pmpt.cli()
|
84
pmpt/install.py
Normal file
84
pmpt/install.py
Normal file
|
@ -0,0 +1,84 @@
|
|||
from . import util
|
||||
|
||||
def search(name):
|
||||
util.loadIndex() #加载索引
|
||||
|
||||
for Index in util.IndexList:
|
||||
dt = Index.packageList.get(name,None)
|
||||
if dt:
|
||||
return Index.IndexURL
|
||||
|
||||
def main(packlist,upgrade,reads,force_reinstall,ignore_requires_python,yes):
|
||||
|
||||
if reads: # 从文件读取列表
|
||||
f = open(packlist[0])
|
||||
packlist = f.read().split('\n')
|
||||
|
||||
packsInfo = {}
|
||||
print('Start installing these packages')
|
||||
print('Start looking for package')
|
||||
|
||||
for rawpack in packlist: # 解析指定了版本的包名
|
||||
if '==' in rawpack:
|
||||
pack = rawpack.split('==')[0]
|
||||
elif '>=' in rawpack:
|
||||
pack = rawpack.split('>=')[0]
|
||||
elif '<=' in rawpack:
|
||||
pack = rawpack.split('<=')[0]
|
||||
elif '<' in rawpack:
|
||||
pack = rawpack.split('<')[0]
|
||||
elif '>' in rawpack:
|
||||
pack = rawpack.split('>')[0]
|
||||
else:
|
||||
pack = rawpack
|
||||
|
||||
|
||||
result = search(pack.lower()) # 转小写并获取源地址
|
||||
packsInfo[pack] = [result,rawpack]
|
||||
|
||||
canInstallPack = []
|
||||
for k,v in packsInfo.items():
|
||||
if not v:
|
||||
print('Unable to find', k)
|
||||
else:
|
||||
print(f'Find {k} from {v[0]}')
|
||||
canInstallPack.append(k)
|
||||
|
||||
print('Will install',', '.join(canInstallPack))
|
||||
|
||||
while True: # 是否允许安装
|
||||
if yes:
|
||||
break
|
||||
|
||||
ye =input('Are you sure you want to install? (y/n)')
|
||||
|
||||
if ye.lower() == 'y':
|
||||
break
|
||||
elif ye.lower() == 'n':
|
||||
print('User Cancels Installation')
|
||||
exit()
|
||||
else:
|
||||
continue
|
||||
|
||||
print('Start calling pip')
|
||||
for pack in canInstallPack:
|
||||
# 构建命令
|
||||
args = [ '-i', packsInfo[pack][0]] # 指定源
|
||||
|
||||
if upgrade: # 升级
|
||||
args.append('-U')
|
||||
if force_reinstall: # 强制重新安装
|
||||
args.append('--force-reinstall')
|
||||
if ignore_requires_python: # 忽略Python版本
|
||||
args.append('--ignore-requires-python')
|
||||
|
||||
args.append(packsInfo[pack][1])
|
||||
ret = util.runpip('install',args) # 运行pip
|
||||
|
||||
if ret.returncode != 0: #是否执行完毕
|
||||
print('Failed to install.')
|
||||
exit()
|
||||
print('Installation completed')
|
||||
|
||||
|
||||
|
36
pmpt/search.py
Normal file
36
pmpt/search.py
Normal file
|
@ -0,0 +1,36 @@
|
|||
import requests
|
||||
from . import util
|
||||
from moyanlib import jsons
|
||||
from .install import search
|
||||
import os
|
||||
def main(name,allinfo,api_url):
|
||||
if not search(name):
|
||||
print('The package does not exist')
|
||||
exit()
|
||||
|
||||
if not api_url:
|
||||
api_url = open(os.path.join(util.dirs.user_config_dir,'api.url')).read()
|
||||
|
||||
req = requests.get(api_url.format(name))
|
||||
if req.status_code == 404:
|
||||
print('The package does not exist')
|
||||
exit()
|
||||
elif req.status_code != 200:
|
||||
print('Server Error!')
|
||||
print('Error Code:',req.status_code)
|
||||
exit()
|
||||
|
||||
|
||||
packageInfo = jsons.loads(req.text)
|
||||
if not allinfo:
|
||||
print('Package Name:',packageInfo['info']['name'])
|
||||
print('Version:',packageInfo['info']['version'])
|
||||
print('Author:',packageInfo['info']['author'])
|
||||
print('Summary:',packageInfo['info']['summary'])
|
||||
print('Keywords:',packageInfo['info']['keywords'])
|
||||
print('License:',packageInfo['info']['license'])
|
||||
print('Dependent Library:',', '.join(packageInfo['info']['requires_dist']))
|
||||
elif allinfo:
|
||||
for k,v in packageInfo['info'].items():
|
||||
print(f'{k}: {v}')
|
||||
|
65
pmpt/update.py
Normal file
65
pmpt/update.py
Normal file
|
@ -0,0 +1,65 @@
|
|||
import requests
|
||||
from moyanlib import jsons
|
||||
from tqdm import tqdm
|
||||
import dill
|
||||
import os
|
||||
import urllib.parse as urlparse
|
||||
from hashlib import sha256
|
||||
from .util import dirs
|
||||
|
||||
def getSourceID(url):
|
||||
'''
|
||||
获取源id
|
||||
'''
|
||||
url = urlparse.urlparse(url)
|
||||
SourceID_Str = url.netloc + url.path # 取主机名和路径
|
||||
sha = sha256()
|
||||
sha.update(SourceID_Str.encode())
|
||||
return sha.hexdigest()[:8] # 取前八位
|
||||
|
||||
class Index:
|
||||
def __init__(self,indexurl):
|
||||
self.packageList = {}
|
||||
self.IndexURL = indexurl
|
||||
self.number = 0
|
||||
|
||||
def addPackage(self, name):
|
||||
self.packageList[name] = 'H'
|
||||
self.number += 1
|
||||
|
||||
def getIndex(url):
|
||||
req = requests.get(url) # 请求HTML
|
||||
HTMLIndex = req.text
|
||||
|
||||
ClassIndex = Index(url)
|
||||
|
||||
print('Start parsing the HTML index for this source.')
|
||||
for line in tqdm(HTMLIndex.split('\n')):
|
||||
# 提取并筛选标签
|
||||
line_list = line.split('>')
|
||||
if len(line_list) > 1 and '<a ' in line:
|
||||
package_name = line_list[1].split('<')[0]
|
||||
|
||||
ClassIndex.addPackage(package_name) # 添加包
|
||||
|
||||
print('This source has a total of', ClassIndex.number,'packages.')
|
||||
print('Start saving the index for this source.')
|
||||
dill.dump(ClassIndex,open(f'{dirs.user_data_dir}/Index/{getSourceID(url)}.pidx','wb'))
|
||||
|
||||
def getAllIndex():
|
||||
'''
|
||||
SourceList = [
|
||||
'https://pypi.tuna.tsinghua.edu.cn/simple',
|
||||
'https://mirrors.bfsu.edu.cn/pypi/web/simple/'
|
||||
]
|
||||
'''
|
||||
SourceList = jsons.load(open(os.path.join(dirs.user_config_dir,'Source.json'))) # 加载源列表
|
||||
if len(SourceList) < 1:
|
||||
print('You have not configured any sources.')
|
||||
exit(1)
|
||||
|
||||
for url in SourceList: # 遍历源列表
|
||||
print('Start downloading index from', url)
|
||||
getIndex(url)
|
||||
print()
|
||||
|
47
pmpt/util.py
Normal file
47
pmpt/util.py
Normal file
|
@ -0,0 +1,47 @@
|
|||
import os
|
||||
from subprocess import Popen,PIPE
|
||||
import sys
|
||||
import pathlib
|
||||
import dill
|
||||
from platformdirs import PlatformDirs
|
||||
|
||||
dirs = PlatformDirs("PMPT", "MoYan")
|
||||
IndexList = []
|
||||
def getVer(baseVar):
|
||||
s = os.popen('git rev-parse HEAD')
|
||||
baseVar = baseVar + '-' + s.read()[:6]
|
||||
return baseVar
|
||||
__version__ = getVer('1.0.0')
|
||||
def init():
|
||||
os.makedirs(dirs.user_data_dir,exist_ok=True)
|
||||
os.makedirs(os.path.join(dirs.user_data_dir,'Index'),exist_ok=True)
|
||||
os.makedirs(dirs.user_config_dir,exist_ok=True)
|
||||
os.makedirs(dirs.user_cache_dir,exist_ok=True)
|
||||
|
||||
def loadIndex():
|
||||
'''
|
||||
加载索引
|
||||
'''
|
||||
if len(IndexList) == 0: # 判断是否为空
|
||||
IndexDir = pathlib.Path(os.path.join(dirs.user_data_dir,'Index'))
|
||||
for i in IndexDir.iterdir(): # 遍历索引文件夹
|
||||
IndexFile = dill.load(open(i,'rb')) # 加载索引
|
||||
IndexList.append(IndexFile)
|
||||
|
||||
if len(IndexList) == 0:
|
||||
raise FileNotFoundError('No index. Run "pmpt update" first to update the index')
|
||||
|
||||
def runpip(command,other=[]) -> Popen:
|
||||
'''
|
||||
运行pip
|
||||
'''
|
||||
baseCommand = [sys.executable,'-m','pip']
|
||||
baseCommand.append(command)
|
||||
|
||||
Command = baseCommand + other
|
||||
|
||||
print(' '.join(Command))
|
||||
|
||||
runClass = Popen(Command)
|
||||
runClass.wait()
|
||||
return runClass
|
6
requirements.txt
Normal file
6
requirements.txt
Normal file
|
@ -0,0 +1,6 @@
|
|||
platformdirs
|
||||
requests
|
||||
moyanlib
|
||||
click
|
||||
dill
|
||||
tqdm
|
45
setup.py
Normal file
45
setup.py
Normal file
|
@ -0,0 +1,45 @@
|
|||
from setuptools import setup, find_packages
|
||||
from setuptools.command.install import install
|
||||
import os
|
||||
from pmpt import util
|
||||
|
||||
class CustomInstallCommand(install):
|
||||
def run(self):
|
||||
install.run(self) # 在安装过程中执行你想要的代码
|
||||
dirs = util.dirs
|
||||
os.makedirs(dirs.user_data_dir,exist_ok=True)
|
||||
os.makedirs(os.path.join(dirs.user_data_dir,'Index'),exist_ok=True)
|
||||
os.makedirs(dirs.user_config_dir,exist_ok=True)
|
||||
os.makedirs(dirs.user_cache_dir,exist_ok=True)
|
||||
open(os.path.join(dirs.user_config_dir,'Source.json'),'w').write('["https://pypi.org/simple/"]')
|
||||
open(os.path.join(dirs.user_config_dir,'api.url'),'w').write('https://pypi.org/pypi/{}/json')
|
||||
|
||||
setup(
|
||||
name='pmpt', # 包的名称
|
||||
version=util.__version__, # 版本号
|
||||
packages=find_packages(), # 包含的包
|
||||
author='MoYan', # 作者
|
||||
author_email='moyan@moyanjdc.top', # 作者邮箱
|
||||
description='a Python Package Advanced Manager', # 包的简要描述
|
||||
long_description='A longer description of your package', # 包的详细描述
|
||||
long_description_content_type='text/markdown', # 描述的内容类型
|
||||
classifiers=[ # 包的分类信息
|
||||
'Development Status :: 3 - Alpha',
|
||||
'Intended Audience :: Developers',
|
||||
'License :: OSI Approved :: MIT License',
|
||||
'Programming Language :: Python :: 3',
|
||||
'Programming Language :: Python :: 3.7',
|
||||
'Programming Language :: Python :: 3.8',
|
||||
'Programming Language :: Python :: 3.9',
|
||||
],
|
||||
setup_requires = ['platformdirs'],
|
||||
install_requires=open('requirements.txt').read().split('\n'),
|
||||
entry_points={
|
||||
'console_scripts': [
|
||||
'pmpt=pmpt:cli',
|
||||
],
|
||||
},
|
||||
cmdclass={
|
||||
'install': CustomInstallCommand,
|
||||
}
|
||||
)
|
Loading…
Reference in New Issue
Block a user