提交 c07a350d 编写于 作者: O openeuler-ci-bot 提交者: Gitee

!71 Bugfix and improve for simple-updat-robot

Merge pull request !71 from LeoFang/master
......@@ -52,8 +52,38 @@ DONE! than you can create a Pull Request.
### Metadata Database
[Database](./upstream-info)
### Introduction of advisors
#### Enviroment Setting
##### 1. necessary packages install
pip3 install python-rpm-spec (ver:0.9)
pip3 install PyYAML (ver:5.3.1)
##### 2. json file config
~/.gitee_personal_token.json
content format: {"user":"user_name","access_token":"token_passwd"}
setting personal access token: https://gitee.com/profile/personal_access_tokens
#### Use Instructions
##### 1. simple-update-root.py
single package auto-upgrade: python3 simple-update-root.py -u pkg pkg_name branch_name
ep: python3 simple-update-root.py -u pkg snappy master
single package manual upgrade: python3 simple-update-root.py pkg_name branch_name [-fc] [-d] [-s] [-n new_version] [-p]
ep: python3 simple-update-root.py snappy openEuler-20.03-LTS -fc -d -s -n 1.8.1
multi-packages in a repo auto-upgrade: python3 simple-update-root.py -u repo repo_name branch_name
ep: python3 simple-update-root.py -u repo src-openeuler master
##### 2. oa_upgradable.py
display all tags of target package: python3 oa_upgradable.py pkg_name
ep: python3 oa_upgradable.py glibc
#### Consultation for advisors:
if any problem, please contact: leo.fangyufa@huawei.com/leofang_94@163.com
## Contribution
1. Fork the repository
......
......@@ -30,12 +30,12 @@ openEuler-Advisor 的目标是为 openEuler 制品仓的日常工作提供自动
4、完善 oa_upgradable.py 支持的上游社区代码管理协议,当前发现还需要增加 fossil 的支持。
## 3、小工具使用说明:
### 3.1、yaml 文件规范
src-openEuler 仓库中的yaml 文件名称与仓库名称应该保持一致,例如glibc 仓库中存放的yaml 文件名称为"glibc.yaml",文件放在仓库根目录下
yaml 文件中需要人工填写的字段有 version_control、src_repo、tag_prefix、separator,其他内容为自动生成的,不需要填写。
#### 3.1.1、yaml字段介绍
......@@ -142,16 +142,47 @@ tag中版本的间隔符,如果 tag是 v1_0_1,然后配置separator 为"_"
如果软件tag分域本来就是".",这个时候设置separator是不影响结果的。
### 3.2、checkabi 功能介绍
### 3.2、Introduction of advisors
#### 3.2.1 Enviroment Setting
##### a. necessary packages install
pip3 install python-rpm-spec (ver:0.9)
pip3 install PyYAML (ver:5.3.1)
##### b. json file config
~/.gitee_personal_token.json
content format: {"user":"user_name","access_token":"token_passwd"}
setting personal access token: https://gitee.com/profile/personal_access_tokens
#### 3.2.2 Use Instructions
##### a. simple-update-root.py
single package auto-upgrade: python3 simple-update-root.py -u pkg pkg_name branch_name
ep: python3 simple-update-root.py -u pkg snappy master
single package manual upgrade: python3 simple-update-root.py pkg_name branch_name [-fc] [-d] [-s] [-n new_version] [-p]
ep: python3 simple-update-root.py snappy openEuler-20.03-LTS -fc -d -s -n 1.8.1
multi-packages in a repo auto-upgrade: python3 simple-update-root.py -u repo repo_name branch_name
ep: python3 simple-update-root.py -u repo src-openeuler master
##### b. oa_upgradable.py
display all tags of target package: python3 oa_upgradable.py pkg_name
ep: python3 oa_upgradable.py glibc
#### 3.2.3 Consultation for advisors:
if any problem, please contact: leo.fangyufa@huawei.com/leofang_94@163.com
### 3.3、checkabi 功能介绍
checkabi 功能依赖libabigail 软件包,使用checkabi 功能前需要安装libabigail ,checkabi 提供了2个功能,下面分别介绍。
#### 3.2.1 比较rpm ABI 差异
#### 3.3.1 比较rpm ABI 差异
命令行:./check_abi.py compare_rpm -r **old.rpm new.rpm** -d **old-debuginfo.rpm new-debuginfo.rpm**
生成的结果存放到 /var/tmp/ 下 文件名为:xx_all_abidiff.out
#### 3.2.2 比较动态库ABI差异
#### 3.3.2 比较动态库ABI差异
命令行:./check_abi.py compare_so -s ./old/usr/lib64/libssl.so.1.1.1 ./new/usr/lib64/libssl.so.1.1.1f
\ No newline at end of file
命令行:./check_abi.py compare_so -s ./old/usr/lib64/libssl.so.1.1.1 ./new/usr/lib64/libssl.so.1.1.1f
......@@ -203,7 +203,6 @@ def __check_subprocess(cmd_list):
resp = subp.stdout.read().decode("utf-8")
if subp.wait() != 0:
eprint("{cmd} > encount errors".format(cmd=" ".join(cmd_list)))
sys.exit(1)
return resp
def __check_svn_helper(repo_url):
......
......@@ -138,6 +138,7 @@ Yours openEuler-Advisor.
resp = self.get_gitee(yamlurl)
except urllib.error.HTTPError:
resp = "Not found"
print("WARNING: {repo}.yaml can't be found in upstream-info.".format(repo=pkg))
if re.match("Not found", resp):
yamlurl = self.yamlfile_url_template.format(branch=br, package=pkg)
try:
......@@ -145,7 +146,7 @@ Yours openEuler-Advisor.
except urllib.error.HTTPError:
resp = "Not found"
if re.match("Not found", resp):
print("Cann't find yaml metadata for {package} from upstream-info.".format(package=pkg))
print("WARNING: {repo}.yaml can't be found in repo on {branch} too".format(repo=pkg, branch=br))
return False
else:
return resp
......
......@@ -2,9 +2,6 @@
libnetwork:
dir: script
file: docker-proxy.spec
authz:
dir: hack
file: authz.spec
lxcfs-tools:
dir: hack
file: lxcfs-tools.spec
......@@ -52,4 +49,4 @@ A-Tune:
file: atune.spec
runc:
dir: .
file: runc-openeuler.spec
\ No newline at end of file
file: runc-openeuler.spec
......@@ -8,3 +8,18 @@ nss:
- '334.20030307'
glibc:
- '9000'
kata-shim:
- '20191207'
kata-runtime:
- '20191207'
kata-proxy:
- '20191207'
kata-agent:
- '20191207'
kexec-tools:
- '200'
sombok:
- '2011'
shadow:
- '1999'
- '2000'
......@@ -44,7 +44,7 @@ def get_ver_tags(gt, repo, cwd_path=None):
try:
repo_yaml = open(os.path.join(cwd_path, repo + ".yaml")).read()
except FileNotFoundError:
print("Cann't find yaml metadata for {pkg} from in {d}.".format(pkg=repo, d=cwd_path))
print("WARNING: {pkg}.yaml can't be found in local path: {path}.".format(pkg=repo, path=cwd_path))
repo_yaml = gt.get_yaml(repo)
else:
repo_yaml = gt.get_yaml(repo)
......@@ -104,7 +104,7 @@ if __name__ == "__main__":
user_gitee = gitee.Gitee()
spec_string = user_gitee.get_spec(args.repo)
if not spec_string:
print("{pkg}.spec can't be found on the master branch".format(pkg=args.repo))
print("WARNING: {pkg}.spec can't be found on master".format(pkg=args.repo))
sys.exit(1)
spec_file = Spec.from_string(spec_string)
......
......@@ -7,8 +7,8 @@ Expected process:
3. Change Source or Source0 if needed
4. Update %changelog
5. try rpmbuild -bb (not yet)
6. fork on gitee
7. git clone, git add, git commit, git push (manually now)
6. fork on gitee and clone to local
7. git add, git commit, git push (manually now)
8. PR on gitee
"""
......@@ -20,6 +20,7 @@ import sys
import subprocess
import os.path
import re
import time
import datetime
import oa_upgradable
......@@ -32,14 +33,14 @@ def download_source_url(spec, o_ver, n_ver):
"""
source = replace_macros(spec.sources[0], spec).replace(o_ver, n_ver)
if re.match(r"%{.*?}", source):
print("Extra macros in URL which failed to be expanded")
print("WARNING: Extra macros in URL which failed to be expanded")
return False
elif source.startswith("http") or source.startswith("ftp"):
fn = os.path.basename(source)
subprocess.call(["curl", "-L", source, "-o", fn])
return fn
else:
print("Not valid URL for Source code")
print("WARNING: Not valid URL for Source code")
return False
......@@ -51,7 +52,7 @@ def download_upstream_url(gt, repo, n_ver):
if not upstream_yaml:
return False
rp_yaml = yaml.loads(upstream_yaml, Loader=yaml.Loader)
rp_yaml = yaml.load(upstream_yaml, Loader=yaml.Loader)
if rp_yaml["version_control"] == "github":
url = "https://github.com/{rp}/archive/{nv}.tar.gz".format(rp=rp_yaml["src_repo"], nv=n_ver)
fn = "{rp}.{nv}.tar.gz".format(rp=repo, nv=n_ver)
......@@ -62,40 +63,43 @@ def download_upstream_url(gt, repo, n_ver):
return False
def update_check(spec, o_ver, n_ver):
def update_ver_check(repo, o_ver, n_ver):
"""
Requirements check for upgraded package
Update version check for upgraded package
"""
if len(spec.patches) >= 1:
print("I'm too naive to handle complicated package.")
print("This package has multiple in-house patches.")
return False
ver_type = version_recommend.VersionType()
if(ver_type.compare(n_ver, o_ver) == 1):
return True
else:
print("Update failed >> [{pkg}: current_ver:{cur_ver}, upgraded_ver:{upd_ver}]".format(
pkg=spec.name, cur_ver=o_ver, upd_ver=n_ver))
print("WARNING: Update failed >> [{pkg}: current_ver:{cur_ver}, upgraded_ver:{upd_ver}]".format(
pkg=repo, cur_ver=o_ver, upd_ver=n_ver))
return False
def fork_clone_repo(gt, repo):
def fork_clone_repo(gt, repo, br):
"""
Fork repo from src-openEuler to private repository, then clone it to local
"""
if not gt.fork_repo(repo):
print("The repo of {pkg} seems to have been forked.".format(pkg=repo))
print("WARNING: The repo of {pkg} seems to have been forked.".format(pkg=repo))
name = gt.token["user"]
subprocess.call(["git", "clone", "git@gitee.com:{user}/{pkg}".format(user=name, pkg=repo)])
os.chdir(repo)
while True:
subprocess.call(["rm", "-rf", "{pkg}".format(pkg=repo)])
subprocess.call(["git", "clone", "git@gitee.com:{user}/{pkg}".format(user=name, pkg=repo)])
os.chdir(repo)
if subprocess.call(["git", "checkout", "{branch}".format(branch=br)]):
time.sleep(1)
else:
os.chdir(os.pardir)
break
def download_src(gt, spec, o_ver, n_ver):
"""
Download source code for upgraded package
"""
os.chdir(replace_macros(spec.name, spec))
source_file = download_source_url(spec, o_ver, n_ver)
if source_file:
print(source_file)
......@@ -106,7 +110,8 @@ def download_src(gt, spec, o_ver, n_ver):
print(source_file)
return True
else:
print("Failed to download the latest source code.")
print("WARNING: Failed to download the latest source code.")
os.chdir(os.pardir)
return False
......@@ -121,13 +126,13 @@ def create_spec(repo, spec_str, o_ver, n_ver, src_fn=None):
in_changelog = False
for l in spec_str.splitlines():
if l.startswith("Release:"):
fn.write("Release:\t0\n")
fn.write(re.sub(r"\d", "1", l) + "\n")
continue
if l.startswith("Source:") or l.startswith("Source0:"):
if src_fn:
fn.write("Source: {src_fn}\n".format(src_fn=src_fn).replace(o_ver, n_ver))
else:
fn.write(l.replace(o_ver, n_ver)+"\n")
fn.write(l.replace(o_ver, n_ver) + "\n")
continue
if not in_changelog:
nl = l.replace(o_ver, n_ver)
......@@ -138,19 +143,20 @@ def create_spec(repo, spec_str, o_ver, n_ver, src_fn=None):
if nl.startswith("%changelog"):
in_changelog = True
d = datetime.date.today()
fn.write(d.strftime("* %a %b %d %Y SimpleUpdate Robot <tc@openeuler.org> - {ver}-0\n").format(ver=n_ver))
fn.write("- Update to version {ver}\n".format(ver=n_ver))
fn.write(d.strftime("* %a %b %d %Y SimpleUpdate Robot <tc@openeuler.org> - {ver}-1\n").format(ver=n_ver))
fn.write("- Upgrade to version {ver}\n".format(ver=n_ver))
fn.write("\n")
fn.close()
os.chdir(os.pardir)
def auto_update_pkg(gt, u_branch, u_pkg):
def auto_update_pkg(gt, u_pkg, u_branch):
"""
Auto upgrade based on given branch for single package
"""
spec_str = gt.get_spec(u_pkg, u_branch)
if not spec_str:
print("{pkg}.spec can't be found on the {br} branch. ".format(
print("WARNING: {pkg}.spec can't be found on the {br} branch.".format(
pkg=u_pkg, br=u_branch))
sys.exit(1)
pkg_spec = Spec.from_string(spec_str)
......@@ -160,42 +166,39 @@ def auto_update_pkg(gt, u_branch, u_pkg):
if pkg_tags is None:
sys.exit(1)
ver_rec = version_recommend.VersionRecommend(pkg_tags, pkg_ver, 0)
rec_up_ver = pkg_ver
if re.search("master", u_branch):
rec_up_ver = ver_rec.latest_version
elif re.search("LTS", u_branch):
rec_up_ver = ver_rec.maintain_version
else:
print("Only support master and LTS version upgrade.")
sys.exit(1)
rec_up_ver = ver_rec.latest_version
fork_clone_repo(gt, u_pkg)
fork_clone_repo(gt, u_pkg, u_branch)
if not update_check(pkg_spec, pkg_ver, rec_up_ver):
if not update_ver_check(u_pkg, pkg_ver, rec_up_ver):
sys.exit(1)
if not download_src(gt, pkg_spec, pkg_ver, rec_up_ver):
sys.exit(1)
create_spec(u_pkg, spec_str, pkg_ver, rec_up_ver)
if len(pkg_spec.patches) >= 1:
print("WARNING: {repo} has multiple patches, please analyse it.".format(repo=u_pkg))
sys.exit(1)
def auto_update_repo(gt, u_branch, u_repo):
def auto_update_repo(gt, u_repo, u_branch):
"""
Auto upgrade based on given branch for packages in given repository
"""
repo_yaml = gt.get_community(u_repo)
if not repo_yaml:
print("{repo}.yaml in community is empty.".format(repo=u_repo))
print("WARNING: {repo}.yaml in community is empty.".format(repo=u_repo))
sys.exit(1)
pkg_info = yaml.load(repo_yaml, Loader=yaml.loader)
pkg_info = yaml.load(repo_yaml, Loader=yaml.Loader)
pkg_list = pkg_info.get("repositories")
for pkg in pkg_list:
pkg_name = pkg.get("name")
print("\n------------------------Updating " + pkg_name + "------------------------")
spec_str = gt.get_spec(pkg_name, u_branch)
if not spec_str:
print("{pkg}.spec can't be found on the {br} branch. ".format(
print("WARNING: {pkg}.spec can't be found on the {br} branch. ".format(
pkg=pkg_name, br=u_branch))
continue
pkg_spec = Spec.from_string(spec_str)
......@@ -205,24 +208,21 @@ def auto_update_repo(gt, u_branch, u_repo):
if pkg_tags is None:
continue
ver_rec = version_recommend.VersionRecommend(pkg_tags, pkg_ver, 0)
rec_up_ver = pkg_ver
if re.search("master", u_branch):
rec_up_ver = ver_rec.latest_version
elif re.search("LTS", u_branch):
rec_up_ver = ver_rec.maintain_version
else:
print("Only support master and LTS version upgrade.")
sys.exit(1)
rec_up_ver = ver_rec.latest_version
fork_clone_repo(gt, pkg_name)
fork_clone_repo(gt, pkg_name, u_branch)
if not update_check(pkg_spec, pkg_ver, rec_up_ver):
if not update_ver_check(pkg_name, pkg_ver, rec_up_ver):
continue
if not download_src(gt, pkg_spec, pkg_ver, rec_up_ver):
continue
create_spec(pkg_name, spec_str, pkg_ver, rec_up_ver)
if len(pkg_spec.patches) >= 1:
print("WARNING: {repo} has multiple patches, please analyse it.".format(repo=pkg_name))
continue
if __name__ == "__main__":
......@@ -242,26 +242,32 @@ if __name__ == "__main__":
user_gitee = gitee.Gitee()
if args.update:
if not args.branch == "master":
print("WARNING: Now only support master version auto-upgrade.")
print("WARNING: You can try manually upgrade with specified version, command as follow:")
print("python3 simple-update-robot.py {pkg} {br} -fc -d -s -n upgrade_ver".format(
pkg=args.repo_pkg, br=args.branch))
sys.exit(1)
if args.update == "repo":
auto_update_repo(user_gitee, args.branch, args.repo_pkg)
auto_update_repo(user_gitee, args.repo_pkg, args.branch)
else:
auto_update_pkg(user_gitee, args.branch, args.repo_pkg)
auto_update_pkg(user_gitee, args.repo_pkg, args.branch)
else:
spec_string = user_gitee.get_spec(args.repo_pkg, args.branch)
if not spec_string:
print("{pkg}.spec can't be found on the {br} branch. ".format(pkg=args.repo_pkg, br=args.branch))
print("WARNING: {pkg}.spec can't be found on the {br} branch. ".format(pkg=args.repo_pkg, br=args.branch))
sys.exit(1)
spec_file = Spec.from_string(spec_string)
cur_version = replace_macros(spec_file.version, spec_file)
if args.fork_then_clone:
fork_clone_repo(user_gitee, args.repo_pkg)
fork_clone_repo(user_gitee, args.repo_pkg, args.branch)
if args.download or args.create_spec:
if not args.new_version:
print("Please specify the upgraded version of the {repo}".format(repo=args.repo_pkg))
sys.exit(1)
elif not update_check(spec_file, cur_version, args.new_version):
elif not update_ver_check(args.repo_pkg, cur_version, args.new_version):
sys.exit(1)
if args.download:
......@@ -270,6 +276,10 @@ if __name__ == "__main__":
if args.create_spec:
create_spec(args.repo_pkg, spec_string, cur_version, args.new_version)
if len(spec_file.patches) >= 1:
print("WARNING: {repo} has multiple patches, please analyse it.".format(repo=args.repo_pkg))
sys.exit(1)
if args.PR:
user_gitee.create_pr(user_gitee.token["user"], args.repo_pkg)
......@@ -1100,7 +1100,7 @@ class VersionRecommend(object):
if m is None: # 版本号应该是数字开头
return False
m = re.search(r'[ab]\d', version)
m = re.search(r'[ab]', version)
if not m is None:
return False
......
此差异已折叠。
version_control: github
src_repo: cyrusimap/cyrus-sasl
tag_prefix: ^v
src_repo: cyrusimap/cyrus-sasl
tag_prefix: "^cyrus-sasl-"
separator: .
version_control: github
src_repo: vathpela/dbxtool-devel
tag_prefix: ^v
src_repo: rhboot/dbxtool
tag_prefix: "^dbxtool-"
separator: .
version_control: github
src_repo: docbook/xslt10-stylesheets
tag_prefix: ^v
tag_prefix: "^release/"
separator: .
version_control: github
src_repo: devicetree-org/devicetree-specification
src_repo: dgibson/dtc
tag_prefix: "^v"
separator: .
---
version_control: git
src_repo: https://pagure.io/fipscheck
tag_prefix: "^fipscheck-"
seperator: "."
version_control: git
src_repo: https://aur.archlinux.org/gamin.git
tag_prefix:
src_repo: https://salsa.debian.org/gnome-team/gamin.git
tag_prefix: "^upstream/"
separator: .
version_control: github
src_repo: ArtifexSoftware/ghostpdl-downloads
tag_prefix: ^v
version_control: git
src_repo: http://git.ghostscript.com/ghostpdl.git
tag_prefix: "^ghostscript-"
separator: .
version_control: git
src_repo: https://git.savannah.gnu.org/git/gnulib.git
tag_repo: ^v
separator: .
tag_prefix: "^v"
seperator: "."
---
version_control: git
src_repo: https://git.savannah.gnu.org/git/gzip.git
tag_prefix: "^v"
seperator: "."
---
version_control: git
src_repo: https://git.code.sf.net/p/linux-ima/ima-evm-utils
tag_prefix: "^v"
seperator: "."
---
version_control: git
src_repo: https://fedorapeople.org/cgit/jolsa/public_git/latrace.git
tag_prefix: "^latrace-"
seperator: "."
version_control: github
src_repo: jftuga/less-Windows
tag_prefix: ^less-v
separator: .
src_repo: gwsw/less
tag_prefix: "^v"
separator: "."
---
version_control: github
src_repo: Distrotech/libIDL
tag_prefix: "^LIBIDL_"
seperator: "_"
version_control: github
src_repo: rpm-software-management/libcomps
tag_prefix: ^v
tag_prefix: "^libcomps-"
separator: .
version_control: github
src_repo: Distrotech/libdaemon
tag_prefix: ^distrotech-libdaemon-
version_control: git
src_repo: https://git.0pointer.net/libdaemon.git
tag_prefix: "^v"
separator: .
---
version_control: github
src_repo: berkeleydb/libdb
tag_prefix: "^v"
seperator: "."
---
version_control: github
src_repo: metalink-dev/libmetalink
tag_prefix: "^release-"
seperator: "."
version_control: github
src_repo: fedora-modularity/libmodulemd
tag_prefix: ^v
tag_prefix: "^libmodulemd-"
separator: .
version_control: github
src_repo: Distrotech/libnetfilter_cthelper
tag_prefix: libnetfilter_cthelper-
separator: .
version_control: git
src_repo: https://git.netfilter.org/libnetfilter_cthelper
tag_prefix: "^libnetfilter_cthelper-"
separator: "."
version_control: github
src_repo: Distrotech/libnetfilter_cttimeout
tag_prefix: libnetfilter_cttimeout-
separator: .
version_control: git
src_repo: https://git.netfilter.org/libnetfilter_cttimeout
tag_prefix: "^libnetfilter_cttimeout-"
separator: "."
version_control: github
src_repo: metalink-dev/libmetalink
tag_prefix: ^release-
separator:
version_control: git
src_repo: http://cygwin.com/git/cygwin-packages/libpaper.git
tag_prefix: "^v"
separator: "."
---
version_control: github
src_repo: gnutls/libtasn1
tag_prefix: "^libtasn1_"
seperator: "_"
version_control: github
src_repo: LMDB/lmdb
tag_prefix: ^v
version_control: git
src_repo: https://git.openldap.org/openldap/openldap.git
tag_prefix: "^LMDB_"
separator: .
---
version_control: git
src_repo: https://arthurdejong.org/git/nss-pam-ldapd
tag_prefix:
seperator: "."
......@@ -3,132 +3,3 @@ version_control: metacpan
src_repo: Storable
tag_prefix: "^v"
separator: "."
last_query:
time_stamp: 2020-04-26 07:41:17.509392700 +00:00
raw_data: |
{
"deprecated" : false,
"metadata" : {
"name" : "Storable",
"author" : [
"Perl 5 Porters"
],
"license" : [
"perl_5"
],
"release_status" : "stable",
"x_serialization_backend" : "JSON::PP version 2.27400_02",
"dynamic_config" : 1,
"resources" : {
"bugtracker" : {
"web" : "http://rt.perl.org/perlbug/"
}
},
"version" : "3.15",
"no_index" : {
"directory" : [
"t",
"inc",
"t",
"xt",
"inc",
"local",
"perl5",
"fatlib",
"example",
"blib",
"examples",
"eg"
]
},
"provides" : {
"Storable" : {
"file" : "__Storable__.pm",
"version" : "3.15"
}
},
"meta-spec" : {
"url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec",
"version" : 2
},
"abstract" : "persistence for Perl data structures",
"prereqs" : {
"configure" : {
"requires" : {
"ExtUtils::MakeMaker" : "0"
}
},
"runtime" : {
"requires" : {
"XSLoader" : "0"
}
},
"build" : {
"requires" : {
"ExtUtils::MakeMaker" : "0"
}
}
},
"generated_by" : "ExtUtils::MakeMaker version 7.24, CPAN::Meta::Converter version 2.150010"
},
"tests" : {
"fail" : 29,
"na" : 0,
"unknown" : 9,
"pass" : 971
},
"authorized" : true,
"provides" : [
"Storable"
],
"stat" : {
"mode" : 33188,
"size" : 200589,
"mtime" : 1556026165
},
"version" : "3.15",
"id" : "fQ3fzxq_Q4EwFEwwhZWcRNYgH0k",
"resources" : {
"bugtracker" : {
"web" : "http://rt.perl.org/perlbug/"
}
},
"main_module" : "Storable",
"checksum_md5" : "7890d8e32c03f9584a1cc65068a7a154",
"changes_file" : "ChangeLog",
"checksum_sha256" : "fc3dad06cb2e6fc86a2f2abc5b5491d9da328ca3e6b6306559c224521db174da",
"version_numified" : 3.15,
"license" : [
"perl_5"
],
"archive" : "Storable-3.15.tar.gz",
"author" : "XSAWYERX",
"abstract" : "persistence for Perl data structures",
"dependency" : [
{
"phase" : "runtime",
"relationship" : "requires",
"version" : "0",
"module" : "XSLoader"
},
{
"phase" : "configure",
"relationship" : "requires",
"version" : "0",
"module" : "ExtUtils::MakeMaker"
},
{
"module" : "ExtUtils::MakeMaker",
"version" : "0",
"relationship" : "requires",
"phase" : "build"
}
],
"first" : false,
"distribution" : "Storable",
"status" : "latest",
"date" : "2019-04-23T13:29:25",
"maturity" : "released",
"download_url" : "https://cpan.metacpan.org/authors/id/X/XS/XSAWYERX/Storable-3.15.tar.gz",
"name" : "Storable-3.15"
}
version_control: github
src_repo: pyparsing/pyparsing
tag_prefix: ^v
tag_prefix: "^pyparsing_"
separator: .
---
version_control: pypi
src_repo: backports
tag_prefix: "^v"
seperator: "."
此差异已折叠。
---
version_control: github
src_repo: readthedocs/commonmark.py
tag_prefix:
seperator: "."
---
version_control: github
src_repo: pycrypto/pycrypto
tag_prefix: "^v"
seperator: "."
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
---
version_control: git
src_repo: https://git.kernel.org/pub/scm/libs/python/python-linux-procfs/python-linux-procfs.git
tag_prefix: "^v"
seperator: "."
---
version_control: github
src_repo: lxml/lxml
tag_prefix: "^lxml-"
seperator: "."
---
version_control: github
src_repo: sqlalchemy/mako
tag_prefix: "^rel_"
seperator: "_"
version_control: github
src_repo: rhinstaller/python-meh
tag_prefix: ^v
version_control: github
src_repo: rhinstaller/python-meh
tag_prefix: "^python-meh-"
separator: .
---
version_control: pypi
src_repo: ordered-set
tag_prefix: "^v"
version_control: github
src_repo: LuminosoInsight/ordered-set
tag_prefix: "^release/"
separator: "."
last_query:
time_stamp: 2020-04-26 03:13:30.051121970 +00:00
raw_data: '{"info":{"author":"","author_email":"","bugtrack_url":null,"classifiers":["Development
Status :: 5 - Production/Stable","Intended Audience :: Developers","License ::
OSI Approved :: MIT License","Programming Language :: Python","Programming Language
:: Python :: 2","Programming Language :: Python :: 2.7","Programming Language
:: Python :: 3","Programming Language :: Python :: 3.4","Programming Language
:: Python :: 3.5","Programming Language :: Python :: 3.6","Programming Language
:: Python :: 3.7","Programming Language :: Python :: Implementation :: CPython","Programming
Language :: Python :: Implementation :: PyPy"],"description":"[![Travis](https://img.shields.io/travis/LuminosoInsight/ordered-set/master.svg?label=Travis%20CI)](https://travis-ci.org/LuminosoInsight/ordered-set)\n[![Codecov](https://codecov.io/github/LuminosoInsight/ordered-set/badge.svg?branch=master&service=github)](https://codecov.io/github/LuminosoInsight/ordered-set?branch=master)\n[![Pypi](https://img.shields.io/pypi/v/ordered-set.svg)](https://pypi.python.org/pypi/ordered-set)\n\nAn
OrderedSet is a mutable data structure that is a hybrid of a list and a set.\nIt
remembers the order of its entries, and every entry has an index number that\ncan
be looked up.\n\n\n## Usage examples\n\nAn OrderedSet is created and used like
a set:\n\n >>> from ordered_set import OrderedSet\n\n >>> letters = OrderedSet(''abracadabra'')\n\n >>>
letters\n OrderedSet([''a'', ''b'', ''r'', ''c'', ''d''])\n\n >>> ''r''
in letters\n True\n\nIt is efficient to find the index of an entry in an OrderedSet,
or find an\nentry by its index. To help with this use case, the `.add()` method
returns\nthe index of the added item, whether it was already in the set or not.\n\n >>>
letters.index(''r'')\n 2\n\n >>> letters[2]\n ''r''\n\n >>> letters.add(''r'')\n 2\n\n >>>
letters.add(''x'')\n 5\n\nOrderedSets implement the union (`|`), intersection
(`&`), and difference (`-`)\noperators like sets do.\n\n >>> letters |= OrderedSet(''shazam'')\n\n >>>
letters\n OrderedSet([''a'', ''b'', ''r'', ''c'', ''d'', ''x'', ''s'', ''h'',
''z'', ''m''])\n\n >>> letters & set(''aeiou'')\n OrderedSet([''a''])\n\n >>>
letters -= ''abcd''\n\n >>> letters\n OrderedSet([''r'', ''x'', ''s'', ''h'',
''z'', ''m''])\n\nThe `__getitem__()` and `index()` methods have been extended
to accept any\niterable except a string, returning a list, to perform NumPy-like
\"fancy\nindexing\".\n\n >>> letters = OrderedSet(''abracadabra'')\n\n >>>
letters[[0, 2, 3]]\n [''a'', ''r'', ''c'']\n\n >>> letters.index([''a'',
''r'', ''c''])\n [0, 2, 3]\n\nOrderedSet implements `__getstate__` and `__setstate__`
so it can be pickled,\nand implements the abstract base classes `collections.MutableSet`
and\n`collections.Sequence`.\n\n\n## Interoperability with NumPy and Pandas\n\nAn
OrderedSet can be used as a bi-directional mapping between a sparse\nvocabulary
and dense index numbers. As of version 3.1, it accepts NumPy arrays\nof index
numbers as well as lists.\n\nThis combination of features makes OrderedSet a simple
implementation of many\nof the things that `pandas.Index` is used for, and many
of its operations are\nfaster than the equivalent pandas operations.\n\nFor further
compatibility with pandas.Index, `get_loc` (the pandas method for\nlooking up
a single index) and `get_indexer` (the pandas method for fancy\nindexing in reverse)
are both aliases for `index` (which handles both cases\nin OrderedSet).\n\n\n##
Type hinting\nTo use type hinting features install `ordered-set-stubs` package
from\n[PyPI](https://pypi.org/project/ordered-set-stubs/):\n\n $ pip install
ordered-set-stubs\n\n\n## Authors\n\nOrderedSet was implemented by Robyn Speer.
Jon Crall contributed changes and\ntests to make it fit the Python set API.\n\n\n##
Comparisons\n\nThe original implementation of OrderedSet was a [recipe posted
to ActiveState\nRecipes][recipe] by Raymond Hettiger, released under the MIT license.\n\n[recipe]:
https://code.activestate.com/recipes/576694-orderedset/\n\nHettiger''s implementation
kept its content in a doubly-linked list referenced by a\ndict. As a result, looking
up an item by its index was an O(N) operation, while\ndeletion was O(1).\n\nThis
version makes different trade-offs for the sake of efficient lookups. Its\ncontent
is a standard Python list instead of a doubly-linked list. This\nprovides O(1)
lookups by index at the expense of O(N) deletion, as well as\nslightly faster
iteration.\n\nIn Python 3.6 and later, the built-in `dict` type is inherently
ordered. If you\nignore the dictionary values, that also gives you a simple ordered
set, with\nfast O(1) insertion, deletion, iteration and membership testing. However,
`dict`\ndoes not provide the list-like random access features of OrderedSet. You\nwould
have to convert it to a list in O(N) to look up the index of an entry or\nlook
up an entry by its index.\n\n\n## Compatibility\n\nOrderedSet is automatically
tested on Python 2.7, 3.4, 3.5, 3.6, and 3.7.\nWe''ve checked more informally
that it works on PyPy and PyPy3.","description_content_type":"text/markdown","docs_url":null,"download_url":"","downloads":{"last_day":-1,"last_month":-1,"last_week":-1},"home_page":"https://github.com/LuminosoInsight/ordered-set","keywords":"","license":"MIT-LICENSE","maintainer":"Robyn
Speer","maintainer_email":"rspeer@luminoso.com","name":"ordered-set","package_url":"https://pypi.org/project/ordered-set/","platform":"any","project_url":"https://pypi.org/project/ordered-set/","project_urls":{"Homepage":"https://github.com/LuminosoInsight/ordered-set"},"release_url":"https://pypi.org/project/ordered-set/3.1.1/","requires_dist":null,"requires_python":">=2.7","summary":"A
MutableSet that remembers its order, so that every entry has an index.","version":"3.1.1","yanked":false},"last_serial":5189421,"releases":{"1.0":[],"1.0.1":[{"comment_text":"","digests":{"md5":"478d253ed92ab13de7bcbdc1b05a09b9","sha256":"e946bbb5a689eb5e6f5f1515964e19e5376fde57747767204eb695d9a38ac3c6"},"downloads":-1,"filename":"ordered-set-1.0.1.tar.gz","has_sig":false,"md5_digest":"478d253ed92ab13de7bcbdc1b05a09b9","packagetype":"sdist","python_version":"source","requires_python":null,"size":2102,"upload_time":"2013-08-06T17:56:20","upload_time_iso_8601":"2013-08-06T17:56:20.709967Z","url":"https://files.pythonhosted.org/packages/84/05/6b87786d97a542d8029a1e1ef47ba9eee97de5b42c41f601b25fecb24648/ordered-set-1.0.1.tar.gz","yanked":false}],"1.1":[{"comment_text":"","digests":{"md5":"1f8d76c4d281a552b79c84be953ffefa","sha256":"ab2afd02ea537f88a9d86a02d95ee3f53de5520880f4039ece7fcef121ad9fe9"},"downloads":-1,"filename":"ordered-set-1.1.tar.gz","has_sig":false,"md5_digest":"1f8d76c4d281a552b79c84be953ffefa","packagetype":"sdist","python_version":"source","requires_python":null,"size":2207,"upload_time":"2013-08-06T19:17:11","upload_time_iso_8601":"2013-08-06T19:17:11.986869Z","url":"https://files.pythonhosted.org/packages/b7/e3/c25675757f47b3e7ace3b88f14685f978356203fe237a3f21649a4a41fa6/ordered-set-1.1.tar.gz","yanked":false}],"1.2":[{"comment_text":"","digests":{"md5":"97316ebb173d84e27da11d2404ae8a67","sha256":"6abbd4b5180cdb0251321e600bd7f37ed289e2bcea817e0205df0477ee98193c"},"downloads":-1,"filename":"ordered-set-1.2.tar.gz","has_sig":false,"md5_digest":"97316ebb173d84e27da11d2404ae8a67","packagetype":"sdist","python_version":"source","requires_python":null,"size":2443,"upload_time":"2014-05-23T18:13:10","upload_time_iso_8601":"2014-05-23T18:13:10.429885Z","url":"https://files.pythonhosted.org/packages/1b/cf/44f194a4b743552aaebb250cfcb8823693f7870303a4177f7eaa4c28e19f/ordered-set-1.2.tar.gz","yanked":false}],"1.3":[{"comment_text":"","digests":{"md5":"b8b8690edc1c04275aa6c2202ea41702","sha256":"57bd11395ed81127a5065c8ea5355389a42f1b2f3a99827b14336e395f3f5524"},"downloads":-1,"filename":"ordered-set-1.3.tar.gz","has_sig":false,"md5_digest":"b8b8690edc1c04275aa6c2202ea41702","packagetype":"sdist","python_version":"source","requires_python":null,"size":2639,"upload_time":"2014-07-21T18:57:35","upload_time_iso_8601":"2014-07-21T18:57:35.075807Z","url":"https://files.pythonhosted.org/packages/3b/07/7df4e081379d79497dcd48e48e56431e8eb129507c822530e4d5d97ed3b4/ordered-set-1.3.tar.gz","yanked":false}],"1.3.1":[{"comment_text":"","digests":{"md5":"6b00a116f22bd83cb8b9962434139427","sha256":"bf3ae1ebf12e6fec255cf8bf7e40e3c78bc0fc3d87dcb5a1d71765d504f7918b"},"downloads":-1,"filename":"ordered-set-1.3.1.tar.gz","has_sig":false,"md5_digest":"6b00a116f22bd83cb8b9962434139427","packagetype":"sdist","python_version":"source","requires_python":null,"size":2906,"upload_time":"2015-04-21T19:20:02","upload_time_iso_8601":"2015-04-21T19:20:02.020643Z","url":"https://files.pythonhosted.org/packages/fd/a0/22aafdc1c89a23a42c2144158b8ad92cee553770808fae72e0618936a6b7/ordered-set-1.3.1.tar.gz","yanked":false}],"1.4.0":[{"comment_text":"","digests":{"md5":"f213135f03017f04900b36acb2787b9d","sha256":"66ebf3b1b634e562958835688ffda86db6d36a2cb3f8e00a26b53f9fa20029d1"},"downloads":-1,"filename":"ordered-set-1.4.0.tar.gz","has_sig":false,"md5_digest":"f213135f03017f04900b36acb2787b9d","packagetype":"sdist","python_version":"source","requires_python":null,"size":3111,"upload_time":"2015-09-28T18:07:25","upload_time_iso_8601":"2015-09-28T18:07:25.469315Z","url":"https://files.pythonhosted.org/packages/55/16/878fa644974e657d53cf85405892788754d87ebe259ddb0e559b86c8657f/ordered-set-1.4.0.tar.gz","yanked":false}],"2.0.0":[{"comment_text":"","digests":{"md5":"aac6e248096099aaef134d1daaa76fce","sha256":"5625139acd8890ffd28570c8ad1401fca9b0b6a5769e275d96aca0b194b9ae5c"},"downloads":-1,"filename":"ordered-set-2.0.0.tar.gz","has_sig":false,"md5_digest":"aac6e248096099aaef134d1daaa76fce","packagetype":"sdist","python_version":"source","requires_python":null,"size":3423,"upload_time":"2016-01-12T20:38:44","upload_time_iso_8601":"2016-01-12T20:38:44.298494Z","url":"https://files.pythonhosted.org/packages/ca/78/44eaacdc2d42c7416f6f66cdb004e374242830658f98ab0271fe1cc6221b/ordered-set-2.0.0.tar.gz","yanked":false}],"2.0.1":[{"comment_text":"","digests":{"md5":"3111c0dd1417b6421eb982e4cd4d0d68","sha256":"55567f094481ba204ffede0117ab563e19af050c7cbf33a9a23292b8cb2b0a0e"},"downloads":-1,"filename":"ordered-set-2.0.1.tar.gz","has_sig":false,"md5_digest":"3111c0dd1417b6421eb982e4cd4d0d68","packagetype":"sdist","python_version":"source","requires_python":null,"size":3407,"upload_time":"2016-03-29T18:01:03","upload_time_iso_8601":"2016-03-29T18:01:03.537632Z","url":"https://files.pythonhosted.org/packages/80/8c/7405f2f1a5b4a95fbc87b1e43df9a630aa30d93c0cfb06a9ea64fd436399/ordered-set-2.0.1.tar.gz","yanked":false}],"2.0.2":[{"comment_text":"","digests":{"md5":"7b8d73dc64fd3c783ecb48e050bfcc0d","sha256":"942cad5d7d5b0760d5cbe93dfb385ac2ed402ca1d48c9f4e102d7d5cce3a90eb"},"downloads":-1,"filename":"ordered-set-2.0.2.tar.gz","has_sig":false,"md5_digest":"7b8d73dc64fd3c783ecb48e050bfcc0d","packagetype":"sdist","python_version":"source","requires_python":null,"size":4881,"upload_time":"2017-04-19T18:21:54","upload_time_iso_8601":"2017-04-19T18:21:54.735431Z","url":"https://files.pythonhosted.org/packages/c3/1c/4ddba479a75369b31655e295463bc37e5f84acb4fa7f34548946ff0160e3/ordered-set-2.0.2.tar.gz","yanked":false}],"3.0.0":[{"comment_text":"","digests":{"md5":"c8f5b99b717618803b914dd9cfe5ef43","sha256":"a34399fe6aa78358aaa00129d67c65b4aa099adfc023731b1d756c85776a89bb"},"downloads":-1,"filename":"ordered-set-3.0.0.tar.gz","has_sig":false,"md5_digest":"c8f5b99b717618803b914dd9cfe5ef43","packagetype":"sdist","python_version":"source","requires_python":">=2.7","size":7237,"upload_time":"2018-06-16T21:03:35","upload_time_iso_8601":"2018-06-16T21:03:35.920467Z","url":"https://files.pythonhosted.org/packages/df/77/db7c91893e3c17587ea15f64e63f660fd27e0abd7811ae809ff2a8e0591a/ordered-set-3.0.0.tar.gz","yanked":false}],"3.0.1":[{"comment_text":"","digests":{"md5":"a8059c7b99cde0f8dda01ddee6b43c2c","sha256":"3d6fd7bffbb15f613a9e8a6281bf97c2d67f7bb8677deca8249df2fbdd9cce7b"},"downloads":-1,"filename":"ordered-set-3.0.1.tar.gz","has_sig":false,"md5_digest":"a8059c7b99cde0f8dda01ddee6b43c2c","packagetype":"sdist","python_version":"source","requires_python":">=2.7","size":9129,"upload_time":"2018-07-10T21:03:59","upload_time_iso_8601":"2018-07-10T21:03:59.936821Z","url":"https://files.pythonhosted.org/packages/15/67/8a98b27f5a8f11273d74201ca3e0e7003a6482423cddfcb6774e5de9050d/ordered-set-3.0.1.tar.gz","yanked":false}],"3.0.2":[{"comment_text":"","digests":{"md5":"b0315b42710a57312d4b875370db2121","sha256":"7d292b866fa44f339ac6e624e3d338accfb415ce0a8431595d51990fbdf61d3b"},"downloads":-1,"filename":"ordered-set-3.0.2.tar.gz","has_sig":false,"md5_digest":"b0315b42710a57312d4b875370db2121","packagetype":"sdist","python_version":"source","requires_python":">=2.7","size":9147,"upload_time":"2018-09-14T21:13:14","upload_time_iso_8601":"2018-09-14T21:13:14.990481Z","url":"https://files.pythonhosted.org/packages/c3/dd/abe09fe9b0022ce5a37489c5c237cf7d50ae2e8807691b03321e7062f816/ordered-set-3.0.2.tar.gz","yanked":false}],"3.1":[{"comment_text":"","digests":{"md5":"5192f5e3771dd290f6d627751ca1c8cb","sha256":"41c7ba85e7619cd4c71e38d4cd434f84de8473b826919eb79274b3a11b940b4d"},"downloads":-1,"filename":"ordered_set-3.1-py2.py3-none-any.whl","has_sig":false,"md5_digest":"5192f5e3771dd290f6d627751ca1c8cb","packagetype":"bdist_wheel","python_version":"py2.py3","requires_python":">=2.7","size":7795,"upload_time":"2018-11-30T21:58:26","upload_time_iso_8601":"2018-11-30T21:58:26.160981Z","url":"https://files.pythonhosted.org/packages/79/16/1f9daee477b04a95146fd0933e3c8af1d47804ae901234ea0228db49fa88/ordered_set-3.1-py2.py3-none-any.whl","yanked":false},{"comment_text":"","digests":{"md5":"acb6be05a5a7c87ab1a16e5320119de7","sha256":"f9b703ea9aa9c1db44412c5ba1c16cf8b7ad7ef37a685e4da2fd3754b40f8f6a"},"downloads":-1,"filename":"ordered-set-3.1.tar.gz","has_sig":false,"md5_digest":"acb6be05a5a7c87ab1a16e5320119de7","packagetype":"sdist","python_version":"source","requires_python":">=2.7","size":10498,"upload_time":"2018-11-30T21:58:27","upload_time_iso_8601":"2018-11-30T21:58:27.755472Z","url":"https://files.pythonhosted.org/packages/74/3c/43038ee35e968c57eb72e88278bb930db84cc75850992bfac3f89ec105bd/ordered-set-3.1.tar.gz","yanked":false}],"3.1.1":[{"comment_text":"","digests":{"md5":"6e12312c8dc4c90fe840e86e8a352644","sha256":"a7bfa858748c73b096e43db14eb23e2bc714a503f990c89fac8fab9b0ee79724"},"downloads":-1,"filename":"ordered-set-3.1.1.tar.gz","has_sig":false,"md5_digest":"6e12312c8dc4c90fe840e86e8a352644","packagetype":"sdist","python_version":"source","requires_python":">=2.7","size":10520,"upload_time":"2019-04-25T19:08:00","upload_time_iso_8601":"2019-04-25T19:08:00.642779Z","url":"https://files.pythonhosted.org/packages/a3/b7/d4d69641cbe707a45c23b190f2d717466ba5accc4c70b5f7a8a450387895/ordered-set-3.1.1.tar.gz","yanked":false}]},"urls":[{"comment_text":"","digests":{"md5":"6e12312c8dc4c90fe840e86e8a352644","sha256":"a7bfa858748c73b096e43db14eb23e2bc714a503f990c89fac8fab9b0ee79724"},"downloads":-1,"filename":"ordered-set-3.1.1.tar.gz","has_sig":false,"md5_digest":"6e12312c8dc4c90fe840e86e8a352644","packagetype":"sdist","python_version":"source","requires_python":">=2.7","size":10520,"upload_time":"2019-04-25T19:08:00","upload_time_iso_8601":"2019-04-25T19:08:00.642779Z","url":"https://files.pythonhosted.org/packages/a3/b7/d4d69641cbe707a45c23b190f2d717466ba5accc4c70b5f7a8a450387895/ordered-set-3.1.1.tar.gz","yanked":false}]}'
此差异已折叠。
此差异已折叠。
此差异已折叠。
version_control: github
src_repo: eliben/pycparser
tag_prefix: ^v
tag_prefix: "^release_v"
separator: .
此差异已折叠。
此差异已折叠。
---
version_control: github
src_repo: readthedocs/recommonmark
tag_prefix:
seperator: "."
version_control: github
src_repo: rhinstaller/python-simpleline
tag_prefix: ^v
tag_prefix: "^simpleline-"
separator: .
此差异已折叠。
version_control: github
src_repo: nphilipp/python-slip
tag_prefix: ^v
tag_prefix: "^python-slip-"
separator: .
---
version_control: git
src_repo: "https://git.savannah.gnu.org/git/screen.git"
tag_prefix: "^v."
seperator: "."
version_control: github
src_repo: fedora-selinux/setroubleshoot
tag_prefix: ^v
version_control: git
src_repo: "https://pagure.io/setroubleshoot.git"
tag_prefix: "^setroubleshoot-plugins-"
separator: .
---
version_control: github
src_repo: xiph/speex
tag_prefix: "^Speex-"
seperator: "."
version_control: github
src_repo: sgallagher/sscg
tag_prefix: ^v
tag_prefix: "^sscg-"
separator: .
---
version_control: github
src_repo: freedesktop/startup-notification
tag_prefix: "^STARTUP_NOTIFICATION_"
seperator: "_"
---
version_control: github
src_repo: tcsh-org/tcsh
tag_prefix: "^TCSH"
seperator: "_"
---
version_control: git
src_repo: http://www.and.org/ustr/ustr.git
tag_prefix: "^v"
seperator: "."
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册