bcmd 0.5.18__py3-none-any.whl → 0.6.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of bcmd might be problematic. Click here for more details.

bcmd/common/password.py CHANGED
@@ -1,17 +1,18 @@
1
1
  import getpass
2
2
  from typing import Any
3
3
 
4
- from beni import bcache, bcrypto
4
+ from async_lru import alru_cache
5
+ from beni import bcrypto
5
6
 
6
7
 
7
- @bcache.cache
8
+ @alru_cache
8
9
  async def getPypi() -> tuple[str, str]:
9
10
  content = 'QbuF2mV/lqovtF5dskZGD7qHknYbNuF2QseWRtWxLZTPrC/jL1tcxV8JEKaRjLsu46PxJZ7zepJwggnUTIWnEAoV5VtgP2/hbuzxxHha8817kR5c65H9fXm8eOal7DYXsUoGPQMnm59UWNXUKjmIaP4sn9nySFlRYqa8sEZSbYQ4N0NL35Dpj1e3wyQxJ+7h2jwKAz50Hh8G4yAM3/js9+NUe4ymts+UXcwsP3ADIBMkzjnFc0lEYg2d+fw0A74XWCvoZPoGqHZR/THUOVNAYxoGgDzP4SPIk1XsmtpxvfO/DpJd/Cg/0fB3MYagGKI1+m6Bxqhvd1I/lf0YbM5y4E4='
10
11
  data = _getData(content)
11
12
  return data['username'], data['password']
12
13
 
13
14
 
14
- @bcache.cache
15
+ @alru_cache
15
16
  async def getQiniu() -> tuple[str, str]:
16
17
  content = '7xOuA0FPCndTWcWmWLbqklQTqLTAhuEw9CarRTBYhWQ/g8wPxktw6VAiu50TLv49D1L8oCVfGafsowYDZw/prF6NQwCluPcCMy5JfdC9sKauvuZa51Nsf6PTR1UIyU8ZLUSzH+Ec2Ufcz/yAZCrcAtn63zMHNu3tTAVcZNPL597lSHdSRkpmDR8CaoUh/raH/Q=='
17
18
  data = _getData(content)
bcmd/tasks/__init__.py CHANGED
@@ -10,9 +10,7 @@ from . import lib
10
10
  from . import math
11
11
  from . import mirror
12
12
  from . import pdf
13
- from . import project
14
13
  from . import proxy
15
14
  from . import time
16
15
  from . import upgrade
17
- from . import venv
18
16
  from . import wasabi
bcmd/tasks/lib.py CHANGED
@@ -1,48 +1,16 @@
1
1
  import os
2
- import re
3
- from contextlib import contextmanager
4
2
  from pathlib import Path
5
3
  from typing import Final
6
4
 
7
5
  import typer
8
- from beni import bcolor, bfile, bpath, btask
9
- from beni.bfunc import syncCall, textToAry
6
+ from beni import bcolor, bfile, bpath, brun, btask
7
+ from beni.bfunc import syncCall
10
8
 
11
9
  from ..common import password
12
- from .venv import getPackageList
13
10
 
14
11
  app: Final = btask.newSubApp('lib 工具')
15
12
 
16
13
 
17
- @app.command()
18
- @syncCall
19
- async def tidy_dependencies(
20
- workspace_path: Path = typer.Argument(Path.cwd(), help='workspace 路径'),
21
- isWithVersion: bool = typer.Option(False, '--with-version', help='是否带版本号')
22
- ):
23
- '整理 pyproject.toml 里面的 dependencies'
24
- pyprojectTomlFile = workspace_path / 'pyproject.toml'
25
- btask.assertTrue(pyprojectTomlFile.is_file(), 'pyproject.toml 不存在', pyprojectTomlFile)
26
- venvFile = bpath.get(workspace_path, f'.venv')
27
- btask.assertTrue(venvFile.is_file(), '.venv 不存在', venvFile)
28
- basePackages, lockPackages = await getPackageList(venvFile)
29
- libAry = lockPackages if isWithVersion else basePackages
30
- oldContent = await bfile.readText(pyprojectTomlFile)
31
- ignoreLibAry = _getIgnoreLibAry(oldContent)
32
- ignoreLibAry = sorted(list(set(ignoreLibAry) & set(libAry)))
33
- libAry = sorted(list(set(libAry) - set(ignoreLibAry)))
34
- replaceContent = '\n'.join([f" '{x}'," for x in libAry]) + '\n' + '\n'.join([f" # '{x}'," for x in ignoreLibAry])
35
- newContent = re.sub(r'dependencies = \[(.*?)\n\]', f"dependencies = [\n{replaceContent}\n]", oldContent, 0, re.DOTALL)
36
- if oldContent != newContent:
37
- await bfile.writeText(pyprojectTomlFile, newContent)
38
- bcolor.printYellow(pyprojectTomlFile)
39
- bcolor.printMagenta(newContent)
40
- return True
41
- else:
42
- bcolor.printGreen('无需修改依赖')
43
- return False
44
-
45
-
46
14
  @app.command()
47
15
  @syncCall
48
16
  async def update_version(
@@ -78,41 +46,13 @@ async def update_version(
78
46
  @syncCall
79
47
  async def build(
80
48
  path: Path = typer.Argument(Path.cwd(), help='workspace 路径'),
81
- isKeepBuildFiles: bool = typer.Option(False, '--keep-build-files', '-k', help='是否保留构建文件'),
82
49
  ):
83
50
  '发布项目'
84
- u, p = await password.getPypi()
85
- with _useBuildPath(path, isKeepBuildFiles):
86
- scriptPath = (path / './venv/Scripts')
87
- os.system(f'{scriptPath / "python.exe"} -m build')
88
- os.system(f'{scriptPath / "twine.exe"} upload dist/* -u {u} -p {p}')
89
-
90
-
91
- # ------------------------------------------------------------------------------------
92
-
93
-
94
- def _getIgnoreLibAry(content: str) -> list[str]:
95
- '获取pyproject.toml中屏蔽的第三方库'
96
- content = re.findall(r'dependencies = \[(.*?)\n\]', content, re.DOTALL)[0]
97
- ary = textToAry(content)
98
- return sorted([x[1:].replace('"', '').replace("'", '').replace(',', '').strip() for x in filter(lambda x: x.startswith('#'), ary)])
99
-
100
-
101
- @contextmanager
102
- def _useBuildPath(workspacePath: Path, isKeepBuildFiles: bool):
103
- '整理构建目录,先清空不必要的输出目录,结束后再判断是否需要再清空一次'
104
-
105
- def removeUnusedPath():
106
- bpath.remove(workspacePath / 'dist')
107
- paths = bpath.listDir(workspacePath)
108
- for x in paths:
109
- if x.name.endswith('.egg-info'):
110
- bpath.remove(x)
111
-
112
- try:
113
- with bpath.changePath(workspacePath):
114
- removeUnusedPath()
115
- yield
116
- finally:
117
- if not isKeepBuildFiles:
118
- removeUnusedPath()
51
+ user, pwd = await password.getPypi()
52
+ bpath.remove(path / 'dist')
53
+ bpath.remove(
54
+ *list(path.glob('*.egg-info'))
55
+ )
56
+ with bpath.changePath(path):
57
+ await brun.run(f'uv build')
58
+ await brun.run(f'uv publish -u {user} -p {pwd}')
@@ -0,0 +1,24 @@
1
+ Metadata-Version: 2.4
2
+ Name: bcmd
3
+ Version: 0.6.2
4
+ Summary: Commands for Beni
5
+ Author-email: Beni Mang <benimang@126.com>
6
+ Maintainer-email: Beni Mang <benimang@126.com>
7
+ Keywords: benimang,beni,bcmd
8
+ Requires-Python: >=3.10
9
+ Requires-Dist: aioconsole==0.8.1
10
+ Requires-Dist: async-lru==2.0.5
11
+ Requires-Dist: benimang==0.8.0
12
+ Requires-Dist: cryptography==45.0.4
13
+ Requires-Dist: nest-asyncio==1.6.0
14
+ Requires-Dist: pillow==11.2.1
15
+ Requires-Dist: prettytable==3.16.0
16
+ Requires-Dist: psutil==7.0.0
17
+ Requires-Dist: pymupdf==1.26.1
18
+ Requires-Dist: qiniu==7.16.0
19
+ Requires-Dist: typer==0.16.0
20
+ Provides-Extra: full
21
+ Requires-Dist: img2pdf==0.6.1; extra == "full"
22
+ Requires-Dist: pytest==8.4.0; extra == "full"
23
+ Requires-Dist: pytest-asyncio==1.0.0; extra == "full"
24
+ Requires-Dist: pytest-order==1.3.0; extra == "full"
@@ -2,13 +2,13 @@ bcmd/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
2
  bcmd/main.py,sha256=GP_60-6vImXqdMfC5vc4xlscWajx4OYmnlNXASWn19w,147
3
3
  bcmd/common/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
4
  bcmd/common/func.py,sha256=MehbfuWFHTOsihhYxVFj0_U6-hjMTfLh3n-oMrpyyKo,508
5
- bcmd/common/password.py,sha256=25fA1h9ttZuUobnZ_nA0Ouhmk43etBfGeM40dgxJnFY,1347
5
+ bcmd/common/password.py,sha256=2oxHvsCL05lNBpDJ8hbx4LPadDsZQKds4f0rJBYTNHA,1368
6
6
  bcmd/resources/project/.gitignore,sha256=EygWFLwtooQl0GWXSeaLszLT-yQioKM7YMNAidcAHGw,23
7
7
  bcmd/resources/project/main.py,sha256=xdskz_sf05fYA1SRMFCIxDjx8SnegxTbCmHpW86ItLs,11
8
8
  bcmd/resources/project/.vscode/launch.json,sha256=Wpghb9lW9Y1wtrjqlTbyjeejDuU8BQJmBjwsLyPRh1g,478
9
9
  bcmd/resources/project/.vscode/settings.json,sha256=G4rCroWxEHcQfsqIJ6CXRHI6VGr3WYQI3KPPjH_JANs,280
10
10
  bcmd/resources/project/.vscode/tasks.json,sha256=gouhpkrqiPz7v65Jw1Rz-BCYU3sSdmphzXIYCzVnoe0,1783
11
- bcmd/tasks/__init__.py,sha256=lGWAgrSd9A4fsg4ilPjqpAeSox7H4VFnf_BxSyG5h8s,355
11
+ bcmd/tasks/__init__.py,sha256=lcVrTgdEph3tKBwwCPVyEOHp-1A3zdFA_6OWLrOo19M,314
12
12
  bcmd/tasks/bin.py,sha256=B_e-HYOc2Cohk-1PbKHyKn3RhI8TAUfI2EBRoFEHiTM,2961
13
13
  bcmd/tasks/code.py,sha256=IUs_ClZuSsBk2gavlitC8mkRrQQX9rvNDgR8cFxduBA,3992
14
14
  bcmd/tasks/crypto.py,sha256=LKvgsMPLvsi1wlt66TinYiN-oV2IPAfaN9y7hWaVpHs,2951
@@ -16,18 +16,16 @@ bcmd/tasks/debian.py,sha256=B9aMIIct3vNqMJr5hTr1GegXVf20H49C27FMvRRGIzI,3004
16
16
  bcmd/tasks/download.py,sha256=XdZYKi8zQTNYWEgUxeTNDqPgP7IGYJkMmlDDC9u93Vk,2315
17
17
  bcmd/tasks/image.py,sha256=Q8ujT6tq2tt0qS0DIY87PNG2RJ1wSArt2dHVTtCuccA,12161
18
18
  bcmd/tasks/json.py,sha256=WWOyvcZPYaqQgp-Tkm-uIJschNMBKPKtZN3yXz_SC5s,635
19
- bcmd/tasks/lib.py,sha256=lq-PdHxhK-5Akf7k4QaIT8mBB-sCK5or5OqEFTdphIA,4567
19
+ bcmd/tasks/lib.py,sha256=Ofx2rSeqBZtVaRM4ly6ORyAozMgk5b8TTM9cy8vCa_E,1904
20
20
  bcmd/tasks/math.py,sha256=xbl5UdaDMyAjiLodDPleP4Cutrk2S3NOAgurzAgOEAE,2862
21
21
  bcmd/tasks/mirror.py,sha256=nAe8NYftMKzht16MFBj7RqXwvVhR6Jh2uuAyJLh87og,1098
22
22
  bcmd/tasks/pdf.py,sha256=fkHRgxqzrRxdb4_-9pL9wp2roqAHJPS_dVqAGJvRUsM,1504
23
- bcmd/tasks/project.py,sha256=yLYL6WNmq0mlY-hQ-SGKZ6uRjwceJxpgbP-QAo0Wk-Y,1948
24
23
  bcmd/tasks/proxy.py,sha256=xvxN5PClUnc5LQpmq2Wug7_LUVpJboMWLXBvL9lX7EM,1552
25
24
  bcmd/tasks/time.py,sha256=ZiqA1jdgl-TBtFSOxxP51nwv4g9iZItmkFKpf9MKelk,2453
26
25
  bcmd/tasks/upgrade.py,sha256=2Wu_aFn-UcToNPDzjRG78VSChirEiD2KnAf6fJUgYak,535
27
- bcmd/tasks/venv.py,sha256=O7E-6FYoMsB4p1UM9m6_bljI-oBmlKg4AJWtsCln-8k,7661
28
26
  bcmd/tasks/wasabi.py,sha256=xWFAxprSIlBqDDMGaNXZFb-SahnW1d_R9XxSKRYIhnM,3110
29
- bcmd-0.5.18.dist-info/METADATA,sha256=QB_MCVJKL8OM9wBQG1HcgEkFdRL8jgT8r9GOv4wCTPo,500
30
- bcmd-0.5.18.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
31
- bcmd-0.5.18.dist-info/entry_points.txt,sha256=rHJrP6KEQpB-YaQqDFzEL2v88r03rxSfnzAayRvAqHU,39
32
- bcmd-0.5.18.dist-info/top_level.txt,sha256=-KrvhhtBcYsm4XhcjQvEcFbBB3VXeep7d3NIfDTrXKQ,5
33
- bcmd-0.5.18.dist-info/RECORD,,
27
+ bcmd-0.6.2.dist-info/METADATA,sha256=6pMqSMaW_SmvOhC2UXIHaHV5YihW8KyL--9NTzUPNMA,812
28
+ bcmd-0.6.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
29
+ bcmd-0.6.2.dist-info/entry_points.txt,sha256=rHJrP6KEQpB-YaQqDFzEL2v88r03rxSfnzAayRvAqHU,39
30
+ bcmd-0.6.2.dist-info/top_level.txt,sha256=-KrvhhtBcYsm4XhcjQvEcFbBB3VXeep7d3NIfDTrXKQ,5
31
+ bcmd-0.6.2.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (78.1.0)
2
+ Generator: setuptools (80.9.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
bcmd/tasks/project.py DELETED
@@ -1,59 +0,0 @@
1
- from pathlib import Path
2
- from typing import Final
3
-
4
- import typer
5
- from beni import bcolor, binput, bpath, brun, btask
6
- from beni.bfunc import syncCall
7
-
8
- from ..common.func import useResources
9
- from . import venv
10
-
11
- app: Final = btask.newSubApp('项目相关')
12
-
13
-
14
- @app.command()
15
- @syncCall
16
- async def create_py(
17
- path: Path = typer.Option(Path.cwd(), '--path', help='workspace 路径'),
18
- ):
19
- '生成新项目'
20
-
21
- # 检查目标路径是否合法
22
- if path.exists():
23
- if not path.is_dir():
24
- bcolor.printRed('目标路径不是一个目录', path)
25
- return
26
- elif list(bpath.get(path).glob('*')):
27
- bcolor.printRed('目标路径不是空目录', path)
28
- return
29
-
30
- bcolor.printYellow(path)
31
- await binput.confirm('即将在此路径生成新项目,是否继续?')
32
- venv.add(['benimang==now'], path)
33
- with useResources('project') as sourceProjectPath:
34
- bpath.copyOverwrite(sourceProjectPath, path)
35
-
36
-
37
- @app.command()
38
- @syncCall
39
- async def install(
40
- path: Path = typer.Option(Path.cwd(), '--path', help='初始化项目的路径'),
41
- deep: int = typer.Option(3, '--deep', help='探索路径深度(默认:1)'),
42
- ):
43
- '初始化项目(python项目执行beni venv install-lock / nodejs项目执行 pnpm install)'
44
-
45
- async def checkPath(currentPath: Path, currentDeep: int):
46
- for file in bpath.listFile(currentPath):
47
- if file.name == '.venv':
48
- with bpath.changePath(file.parent):
49
- await brun.run('beni venv install-lock', isPrint=True)
50
- return
51
- elif file.name == 'package.json':
52
- with bpath.changePath(file.parent):
53
- await brun.run('pnpm install', isPrint=True)
54
- return
55
- if currentDeep < deep:
56
- for folder in bpath.listPath(currentPath):
57
- await checkPath(folder, currentDeep + 1)
58
-
59
- await checkPath(path, 0)
bcmd/tasks/venv.py DELETED
@@ -1,227 +0,0 @@
1
- import os
2
- import platform
3
- import re
4
- import sys
5
- from pathlib import Path
6
- from typing import Final
7
-
8
- import typer
9
- from beni import bcolor, bexecute, bfile, bhttp, bpath, brun, btask
10
- from beni.bfunc import syncCall
11
- from beni.btype import Null
12
- from prettytable import PrettyTable
13
-
14
- from ..common.func import checkFileOrNotExists, checkPathOrNotExists
15
-
16
- app: Final = btask.newSubApp('venv 相关')
17
-
18
-
19
- @app.command()
20
- @syncCall
21
- async def add(
22
- packages: list[str] = typer.Argument(None),
23
- path: Path = typer.Option(None, '--path', help='指定路径,默认当前目录'),
24
- isOfficial: bool = typer.Option(False, '--official', help='是否使用官方地址安装(https://pypi.org/simple)'),
25
- ):
26
- '添加指定库'
27
- await _venv(
28
- packages,
29
- path=path,
30
- isOfficial=isOfficial,
31
- )
32
-
33
-
34
- @app.command()
35
- @syncCall
36
- async def install_benimang(
37
- path: Path = typer.Option(None, '--path', help='指定路径,默认当前目录'),
38
- ):
39
- '更新 benimang 库,强制使用官方源'
40
- path = path or Path(os.getcwd())
41
- pip = getPipFile(path)
42
- await brun.run(f'{pip} install benimang -U -i https://pypi.org/simple', isPrint=True)
43
- await _venv(
44
- ['benimang==now'],
45
- path=path,
46
- )
47
-
48
-
49
- @app.command()
50
- @syncCall
51
- async def install_base(
52
- path: Path = typer.Option(None, '--path', help='指定路径,默认当前目录'),
53
- isOfficial: bool = typer.Option(False, '--official', help='是否使用官方地址安装(https://pypi.org/simple)'),
54
- isCleanup: bool = typer.Option(False, '--cleanup', help='是否清空venv目录后重新安装'),
55
- ):
56
- '安装基础库'
57
- await _venv(
58
- path=path,
59
- isOfficial=isOfficial,
60
- isUseBase=True,
61
- isCleanup=isCleanup,
62
- )
63
-
64
-
65
- @app.command()
66
- @syncCall
67
- async def install_lock(
68
- path: Path = typer.Option(None, '--path', help='指定路径,默认当前目录'),
69
- isOfficial: bool = typer.Option(False, '--official', help='是否使用官方地址安装(https://pypi.org/simple)'),
70
- isCleanup: bool = typer.Option(False, '--cleanup', help='是否清空venv目录后重新安装'),
71
- ):
72
- '安装指定版本的库'
73
- await _venv(
74
- path=path,
75
- isOfficial=isOfficial,
76
- isUseLock=True,
77
- isCleanup=isCleanup,
78
- )
79
-
80
-
81
- # ------------------------------------------------------------------------------------
82
-
83
- async def _venv(
84
- packages: list[str] = [],
85
- *,
86
- path: Path = Null,
87
- isOfficial: bool = False,
88
- isUseBase: bool = False,
89
- isUseLock: bool = False,
90
- isCleanup: bool = False,
91
- ):
92
- 'python 虚拟环境配置'
93
- btask.assertTrue(not (isUseBase == isUseLock == True), '2个选项只能选择其中一个 --use-base / --use-lock')
94
- path = path or Path(os.getcwd())
95
- venvPath = getVenvPath(path)
96
- checkPathOrNotExists(venvPath)
97
- venvFile = bpath.get(path, '.venv')
98
- checkFileOrNotExists(venvFile)
99
- if isCleanup:
100
- bpath.remove(venvPath)
101
- btask.assertTrue(not venvPath.exists(), f'无法删除 venv 目录 {venvPath}')
102
- packages = packages or []
103
- for i in range(len(packages)):
104
- package = packages[i]
105
- if package.endswith('==now'):
106
- ary = package.split('==')
107
- packages[i] = f'{ary[0]}=={await _getPackageLatestVersion(ary[0])}'
108
- if not venvPath.exists():
109
- await bexecute.run(f'python -m venv {venvPath}')
110
- if not venvFile.exists():
111
- await bfile.writeText(venvFile, '')
112
- basePackages, lockPackages = await getPackageList(venvFile)
113
- if isUseBase:
114
- installPackages = _mergePackageList(basePackages, packages)
115
- elif isUseLock:
116
- installPackages = _mergePackageList(lockPackages, packages)
117
- else:
118
- installPackages = _mergePackageList(lockPackages or basePackages, packages)
119
- installPackages = sorted(list(set(installPackages)))
120
- pip = getPipFile(path)
121
- await _pipInstall(pip, installPackages, isOfficial)
122
- with bpath.useTempFile() as tempFile:
123
- await bexecute.run(f'{pip} freeze > {tempFile}')
124
- basePackages = _mergePackageList(basePackages, packages)
125
- lockPackages = (await bfile.readText(tempFile)).replace('\r\n', '\n').strip().split('\n')
126
- await updatePackageList(venvFile, basePackages, lockPackages)
127
- bcolor.printGreen('OK')
128
-
129
-
130
- async def _pipInstall(pip: Path, installPackages: list[str], disabled_mirror: bool):
131
- python = pip.with_stem('python')
132
- btask.assertTrue(python.is_file(), f'无法找到指定文件 {python}')
133
- btask.assertTrue(pip.is_file(), f'无法找到指定文件 {pip}')
134
- indexUrl = '-i https://pypi.org/simple' if disabled_mirror else ''
135
- with bpath.useTempFile() as file:
136
- await bfile.writeText(file, '\n'.join(installPackages))
137
- table = PrettyTable()
138
- table.add_column(
139
- bcolor.yellow('#'),
140
- [x + 1 for x in range(len(installPackages))],
141
- )
142
- table.add_column(
143
- bcolor.yellow('安装库'),
144
- [x for x in installPackages],
145
- 'l',
146
- )
147
- print(table.get_string())
148
-
149
- btask.assertTrue(
150
- not await bexecute.run(f'{python} -m pip install --upgrade pip {indexUrl}'),
151
- '更新 pip 失败',
152
- )
153
- btask.assertTrue(
154
- not await bexecute.run(f'{pip} install -r {file} {indexUrl}'),
155
- '执行失败',
156
- )
157
-
158
-
159
- async def _getPackageDict(venvFile: Path):
160
- content = await bfile.readText(venvFile)
161
- pattern = r'\[\[ (.*?) \]\]\n(.*?)(?=\n\[\[|\Z)'
162
- matches: list[tuple[str, str]] = re.findall(pattern, content.strip(), re.DOTALL)
163
- return {match[0]: [line.strip() for line in match[1].strip().split('\n') if line.strip()] for match in matches}
164
-
165
-
166
- _baseName: Final[str] = 'venv'
167
-
168
-
169
- def _getLockName():
170
- systemName = platform.system()
171
- return f'{_baseName}-{systemName}'
172
-
173
-
174
- async def getPackageList(venvFile: Path):
175
- result = await _getPackageDict(venvFile)
176
- lockName = _getLockName()
177
- return result.get(_baseName, []), result.get(lockName, [])
178
-
179
-
180
- async def updatePackageList(venvFile: Path, packages: list[str], lockPackages: list[str]):
181
- packageDict = await _getPackageDict(venvFile)
182
- lockName = _getLockName()
183
- packages.sort(key=lambda x: x.lower())
184
- lockPackages.sort(key=lambda x: x.lower())
185
- packageDict[_baseName] = packages
186
- packageDict[lockName] = lockPackages
187
- content = '\n\n\n'.join([f'\n[[ {key} ]]\n{'\n'.join(value)}' for key, value in packageDict.items()]).strip()
188
- await bfile.writeText(venvFile, content)
189
-
190
-
191
- async def _getPackageLatestVersion(package: str):
192
- '获取指定包的最新版本'
193
- data = await bhttp.getJson(
194
- f'https://pypi.org/pypi/{package}/json'
195
- )
196
- return data['info']['version']
197
-
198
-
199
- def _mergePackageList(basePackages: list[str], addPackages: list[str]):
200
- basePackagesDict = {_getPackageName(x): x for x in basePackages}
201
- addPackagesDict = {_getPackageName(x): x for x in addPackages}
202
- packagesDict = basePackagesDict | addPackagesDict
203
- return sorted([x for x in packagesDict.values()])
204
-
205
-
206
- def _getPackageName(package: str):
207
- if '==' in package:
208
- package = package.split('==')[0]
209
- elif '>' in package:
210
- package = package.split('>')[0]
211
- elif '<' in package:
212
- package = package.split('<')[0]
213
- package = package.strip()
214
- if package.startswith('#'):
215
- package = package.replace('#', '', 1).strip()
216
- return package
217
-
218
-
219
- def getVenvPath(path: Path):
220
- return bpath.get(path, 'venv')
221
-
222
-
223
- def getPipFile(path: Path):
224
- if sys.platform.startswith('win'):
225
- return bpath.get(getVenvPath(path), 'Scripts/pip.exe')
226
- else:
227
- return bpath.get(getVenvPath(path), 'bin/pip')
@@ -1,19 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: bcmd
3
- Version: 0.5.18
4
- Summary: Commands for Beni
5
- Author-email: Beni Mang <benimang@126.com>
6
- Maintainer-email: Beni Mang <benimang@126.com>
7
- Keywords: benimang,beni,bcmd
8
- Requires-Python: >=3.10
9
- Requires-Dist: benimang==0.7.14
10
- Requires-Dist: build
11
- Requires-Dist: cryptography
12
- Requires-Dist: pathspec
13
- Requires-Dist: pillow
14
- Requires-Dist: prettytable
15
- Requires-Dist: psutil
16
- Requires-Dist: pymupdf
17
- Requires-Dist: qiniu
18
- Requires-Dist: twine
19
- Requires-Dist: typer