Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Richard 祝发兴 - -IT
opencv-python
提交
c148de21
O
opencv-python
项目概览
Richard 祝发兴 - -IT
/
opencv-python
与 Fork 源项目一致
Fork自
OpenCV / opencv-python
通知
1
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
1
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
O
opencv-python
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
1
Issue
1
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
c148de21
编写于
11月 12, 2018
作者:
I
Ivan Pozdeev
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Make library for auto building and caching Homebrew bottles
cache Homebrew
上级
77a3278f
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
447 addition
and
12 deletion
+447
-12
.travis.yml
.travis.yml
+37
-1
config.sh
config.sh
+29
-11
travis_osx_brew_cache.sh
travis_osx_brew_cache.sh
+381
-0
未找到文件。
.travis.yml
浏览文件 @
c148de21
...
...
@@ -25,6 +25,15 @@ dist: trusty
git
:
submodules
:
false
# https://docs.travis-ci.com/user/caching
cache
:
directories
:
# https://stackoverflow.com/questions/39930171/cache-brew-builds-with-travis-ci
-
$HOME/Library/Caches/Homebrew
-
/usr/local/Homebrew/
# used in OSX custom build script dealing with local bottle caching
-
$HOME/local_bottle_metadata
matrix
:
fast_finish
:
true
include
:
...
...
@@ -526,9 +535,36 @@ install: |
script
:
|
# Install and run tests
set -x
install_run $PLAT
install_run $PLAT
&& rc=$? || rc=$?
set +x
#otherwise, Travis logic terminates prematurely
#https://travis-ci.community/t/shell-session-update-command-not-found-in-build-log-causes-build-to-fail-if-trap-err-is-set/817
trap ERR
test "$rc" -eq 0
before_cache
:
|
# Cleanup dirs to be cached
set -x
if [ -n "$IS_OSX" ]; then
# When Taps is cached, this dir causes "Error: file exists" on `brew update`
rm -rf "$(brew --repository)/Library/Taps/homebrew/homebrew-cask/homebrew-cask"
find "$(brew --repository)/Library/Taps" -type d -name .git -exec \
bash -xec '
cd $(dirname '\''{}'\'')
git status
# https://stackoverflow.com/questions/8296710/how-to-ignore-xargs-commands-if-stdin-input-is-empty/19038748#19038748
git ls-files --other -z | xargs -0 -n100 git add
git commit -a -m "Travis auto changes"
[[ -n $(git stash list) ]] && git stash drop' \;
brew_cache_cleanup
fi
set +x
after_success
:
|
# Upload wheels to pypi if requested
if [ -n "$TRAVIS_TAG" ]; then
...
...
config.sh
浏览文件 @
c148de21
...
...
@@ -24,28 +24,46 @@ else
echo
" > Linux environment "
fi
if
[
-n
"
$IS_OSX
"
]
;
then
source
travis_osx_brew_cache.sh
BREW_SLOW_BUILIDING_PACKAGES
=
$(
printf
'%s\n'
\
"x265 20"
\
"cmake 15"
\
"ffmpeg 10"
\
)
#Contrib adds significantly to project's build time
if
[
"
$ENABLE_CONTRIB
"
-eq
1
]
;
then
BREW_TIME_LIMIT
=
$((
BREW_TIME_LIMIT
-
10
*
60
))
fi
fi
function
pre_build
{
echo
"Starting pre-build"
set
-e
set
-e
-o
pipefail
if
[
-n
"
$IS_OSX
"
]
;
then
echo
"Running for OSX"
brew update
--merge
brew_add_local_bottles
brew update
# Don't query analytical info online on `brew info`,
# this takes several seconds and we don't need it
# see https://docs.brew.sh/Manpage , "info formula" section
export
HOMEBREW_NO_GITHUB_API
=
1
echo
'Installing QT4'
brew tap |
grep
-qxF
cartr/qt4
||
brew tap
-v
cartr/qt4
brew tap
--list-pinned
|
grep
-qxF
cartr/qt4
||
brew tap-pin
-v
cartr/qt4
brew list
--versions
qt@4
||
brew
install
-v
qt@4
echo
'-----------------'
echo
'-----------------'
brew_install_and_cache_within_time_limit qt@4
||
{
[
$?
-gt
1
]
&&
return
2
||
return
0
;
}
echo
'Installing FFmpeg'
# brew install does produce output regularly on a regular MacOS,
# but Travis doesn't see it for some reason
brew list
--versions
ffmpeg
||
\
travis_wait brew
install
-v
ffmpeg
--without-x264
--without-xvid
--without-gpl
brew info ffmpeg
echo
'-----------------'
brew_install_and_cache_within_time_limit ffmpeg
||
{
[
$?
-gt
1
]
&&
return
2
||
return
0
;
}
else
echo
"Running for linux"
...
...
travis_osx_brew_cache.sh
0 → 100644
浏览文件 @
c148de21
# Library to cache downloaded and locally-built Homebrew bottles in Travis OSX build.
trap
'{ sleep 1; #if we terminale too abruptly, Travis will lose some log output
exit 2; #The trap isn''t called in the parent function, so can''t use `return` here.
#`exit` will terminate the entire build but it seems we have no choice.
}'
ERR
set
-E
#Should be in Travis' cache
BREW_LOCAL_BOTTLE_METADATA
=
"
$HOME
/local_bottle_metadata"
# Starting reference point for elapsed build time; seconds since the epoch.
#TRAVIS_TIMER_START_TIME is set at the start of a log fold, in nanoseconds since the epoch
BREW_TIME_START
=
$((
$TRAVIS_TIMER_START_TIME
/
10
**
9
))
# If after a package is built, elapsed time is more than this many seconds, fail the build but save Travis cache
# The cutoff moment should leave enough time till Travis' job time limit to process the main project.
BREW_TIME_LIMIT
=
$((
30
*
60
))
# If a slow-building package is about to be built and the projected build end moment is beyond this many seconds,
# skip that build, fail the Travis job and save Travis cache.
# This cutoff should leave enough time for before_cache and cache save.
BREW_TIME_HARD_LIMIT
=
$((
40
*
60
))
#Public functions
function
brew_install_and_cache_within_time_limit
{
# Install the package and its dependencies one by one;
# use bottle if available, build and cache bottle if not.
# Terminate and exit with status 1 if this takes too long.
# Exit with status 2 on any other error.
local
PACKAGE
;
PACKAGE
=
"
${
1
:?
}
"
local
TIME_LIMIT
;
TIME_LIMIT
=
${
2
:-
$BREW_TIME_LIMIT
}
local
TIME_HARD_LIMIT
;
TIME_HARD_LIMIT
=
${
3
:-
$BREW_TIME_HARD_LIMIT
}
local
TIME_START
;
TIME_START
=
${
4
:-
$BREW_TIME_START
}
local
BUILD_FROM_SOURCE INCLUDE_BUILD
_brew_is_bottle_available
"
$PACKAGE
"
||
BUILD_FROM_SOURCE
=
1
[
-n
"
$BUILD_FROM_SOURCE
"
]
&&
INCLUDE_BUILD
=
"--include-build"
||
true
# Whitespace is illegal in package names so converting all whitespace into single spaces due to no quotes is okay.
DEPS
=
`
brew deps
"
$PACKAGE
"
$INCLUDE_BUILD
`
for
dep
in
$DEPS
;
do
#TIME_LIMIT only has to be met if we'll be actually building the main project this iteration, i.e. after the "root" module installation
#While we don't know that yet, we can make better use of Travis-given time with a laxer limit
#We still can't overrun TIME_HARD_LIMIT as that would't leave time to save the cache
brew_install_and_cache_within_time_limit
"
$dep
"
$((
(
TIME_LIMIT+TIME_HARD_LIMIT
)/
2
))
"
$TIME_HARD_LIMIT
"
"
$TIME_START
"
||
return
$?
done
_brew_check_slow_building_ahead
"
$PACKAGE
"
"
$TIME_START
"
"
$TIME_HARD_LIMIT
"
||
return
$?
_brew_install_and_cache
"
$PACKAGE
"
"
$(
[[
-z
"
$INCLUDE_BUILD
"
]]
&&
echo
1
||
echo
0
)
"
_brew_check_elapsed_build_time
"
$TIME_START
"
"
$TIME_LIMIT
"
||
return
$?
}
function
brew_add_local_bottles
{
# Should be called after `brew update` at startup.
# Adds metadata for cached locally-built bottles to local formulas
# so that `brew` commands can find them.
# If the package was updated, removes the corresponding files
# and the bottle's entry in the formula, if any.
# Bottle entry in formula:
# bottle do
# <...>
# sha256 "<sha256>" => :<os_codename>
# <...>
# end
echo
"Cached bottles:"
ls
"
$(
brew
--cache
)
/downloads"
||
true
#may not exist initially since it's "$(brew --cache)" that is in Travis cache
echo
"Saved .json's and links:"
ls
"
$BREW_LOCAL_BOTTLE_METADATA
"
for
JSON
in
"
$BREW_LOCAL_BOTTLE_METADATA
"
/
*
.json
;
do
[
-e
"
$JSON
"
]
||
break
# OSX 10.11 bash has no nullglob
local
PACKAGE JSON_VERSION JSON_REBUILD OS_CODENAME BOTTLE_HASH
_brew_parse_bottle_json
"
$JSON
"
PACKAGE JSON_VERSION JSON_REBUILD OS_CODENAME BOTTLE_HASH
echo
"Adding local bottle:
$PACKAGE
${
JSON_VERSION
}
_
${
JSON_REBUILD
}
"
local
FORMULA_VERSION FORMULA_REBUILD FORMULA_BOTTLE_HASH
_brew_parse_package_info
"
$PACKAGE
"
"
$OS_CODENAME
"
FORMULA_VERSION FORMULA_REBUILD FORMULA_BOTTLE_HASH
local
FORMULA_HAS_BOTTLE
;
[
-n
"
$FORMULA_BOTTLE_HASH
"
]
&&
FORMULA_HAS_BOTTLE
=
1
||
true
local
BOTTLE_LINK BOTTLE
;
BOTTLE_LINK
=
"
${
JSON
}
.bottle.lnk"
;
local
BOTTLE_EXISTS BOTTLE_MISMATCH VERSION_MISMATCH
# Check that the bottle file exists and is still appropriate for the formula
if
[[
"
$FORMULA_VERSION
"
!=
"
$JSON_VERSION
"
||
"
$JSON_REBUILD
"
!=
"
$FORMULA_REBUILD
"
]]
;
then
VERSION_MISMATCH
=
1
;
echo
"The cached bottle is obsolete: formula
${
FORMULA_VERSION
}
_
${
FORMULA_REBUILD
}
"
fi
if
[
-f
"
$BOTTLE_LINK
"
]
;
then
BOTTLE
=
$(
cat
"
$BOTTLE_LINK
"
)
;
BOTTLE
=
$(
cd
"
$(
dirname
"
$BOTTLE
"
)
"
;
pwd
)
/
$(
basename
"
$BOTTLE
"
)
if
[
-e
"
$BOTTLE
"
]
;
then
BOTTLE_EXISTS
=
1
;
# The hash in `brew --cache $PACKAGE` entry is generated from download URL,
# which itself is generated from base URL and version
# (see Homebrew/Library/Homebrew/download_strategy.rb:cached_location).
# So if version changes, hashes will always mismatch anyway
# and we don't need a separate message about this.
# XXX: OSX doesn't have `realpath` so can't compare the entire paths
if
[
-n
"
$FORMULA_HAS_BOTTLE
"
-a
-z
"
$VERSION_MISMATCH
"
-a
\
"
$(
basename
"
$(
brew
--cache
"
$PACKAGE
"
)
"
)
"
!=
"
$(
basename
"
$BOTTLE
"
)
"
]
;
then
BOTTLE_MISMATCH
=
1
;
echo
"Cached bottle file doesn't correspond to formula's cache entry!"
\
"This can happen if download URL has changed."
>
&2
fi
else
echo
"Cached bottle file is missing!"
>
&2
fi
else
echo
"Link file is missing or of invalid type!"
>
&2
fi
# Delete cached bottle and all metadata if invalid
if
[[
-z
"
$BOTTLE_EXISTS
"
||
-n
"
$VERSION_MISMATCH
"
||
-n
"
$BOTTLE_MISMATCH
"
]]
;
then
echo
"Deleting the cached bottle and all metadata"
if
[
"
$FORMULA_BOTTLE_HASH
"
==
"
$BOTTLE_HASH
"
]
;
then
echo
"A bottle block for the cached bottle was merged into the updated formula. Removing..."
local
FORMULA
;
FORMULA
=
$(
brew formula
"
$PACKAGE
"
)
perl
-wpe
'BEGIN { our $IN_BLOCK=0; }
if ( ($IN_BLOCK==0) && /^\s*bottle\s+do\s*$/ ) { $IN_BLOCK=1; next; }
if ( ($IN_BLOCK==1) && /^\s*end\s*$/ ) { $IN_BLOCK=-1; next; }
if ( ($IN_BLOCK==1) && /^\s*sha256\s+"(\w+)"\s+=>\s+:\w+\s*$/ )
{ if ( $1 eq "'
"
$BOTTLE_HASH
"
'" ) {$_="";}; next; }
'
<
"
$FORMULA
"
>
"
${
FORMULA
}
.new"
# Depending on diff version, 1 may mean differences found
# https://stackoverflow.com/questions/6971284/what-are-the-error-exit-values-for-diff
diff
-u
"
$FORMULA
"
"
${
FORMULA
}
.new"
||
test
$?
-le
1
(
cd
$(
dirname
"
$FORMULA
"
)
FORMULA
=
$(
basename
"
$FORMULA
"
)
mv
-v
"
${
FORMULA
}
.new"
"
$FORMULA
"
git commit
-m
"Removed obsolete local bottle
${
JSON_VERSION
}
_
${
JSON_REBUILD
}
:
${
OS_CODENAME
}
"
"
$FORMULA
"
)
fi
if
[
-n
"
$BOTTLE
"
]
;
then
rm
"
$BOTTLE
"
;
fi
rm
-f
"
$BOTTLE_LINK
"
rm
"
$JSON
"
#(Re)add metadata to the formula otherwise
else
if
[
"
$FORMULA_BOTTLE_HASH
"
==
"
$BOTTLE_HASH
"
]
;
then
echo
"The cached bottle is already present in the formula"
else
brew bottle
--merge
--write
"
$JSON
"
fi
fi
done
}
function
brew_cache_cleanup
{
#Cleanup caching directories
# Is supposed to be called in before_cache
#Lefovers from some failure probably
rm
-f
"
$BREW_LOCAL_BOTTLE_METADATA
"
/
*
.tar.gz
#`brew cleanup` may delete locally-built bottles that weren't needed this time
# so we're saving and restoring them
local
BOTTLE_LINK BOTTLE
for
BOTTLE_LINK
in
"
$BREW_LOCAL_BOTTLE_METADATA
"
/
*
.lnk
;
do
BOTTLE
=
$(
cat
"
$BOTTLE_LINK
"
)
ln
"
$BOTTLE
"
"
$BREW_LOCAL_BOTTLE_METADATA
/"
done
brew cleanup
local
BOTTLE_BASENAME
for
BOTTLE_LINK
in
"
$BREW_LOCAL_BOTTLE_METADATA
"
/
*
.lnk
;
do
BOTTLE
=
$(
cat
"
$BOTTLE_LINK
"
)
BOTTLE_BASENAME
=
$(
basename
"
$BOTTLE
"
)
if
test
!
-e
"
$BOTTLE
"
;
then
echo
"Restoring:
$BOTTLE_BASENAME
"
mv
"
$BREW_LOCAL_BOTTLE_METADATA
/
$BOTTLE_BASENAME
"
"
$BOTTLE
"
else
rm
"
$BREW_LOCAL_BOTTLE_METADATA
/
$BOTTLE_BASENAME
"
fi
done
}
function
brew_go_bootstrap_mode
{
# Can be overridden
# Terminate the build but ensure saving the cache
echo
"Going into cache bootstrap mode"
#Can't just `exit` because that would terminate the build without saving the cache
#Have to replace further actions with no-ops
eval
'
function '
"
$cmd
"
' { return 0; }
function repair_wheelhouse { return 0; }
function install_run {
echo -e "\nBuilding dependencies took too long. Restart the build in Travis UI to continue from cache.\n"
# Travis runs user scripts via `eval` i.e. in the same shell process.
# So have to unset errexit in order to get to cache save stage
set +e; return 1
}'
}
#Internal functions
function
_brew_parse_bottle_json
{
# Parse JSON info about a package
# from `brew info --json=v1` input or a JSON file on stdin
# and save it into bash global variables specified in arguments
local
JSON
;
JSON
=
"
${
1
:?
}
"
;
shift
local
JSON_DATA
;
JSON_DATA
=
$(
python2.7
-c
'if True:
import sys,json; j=json.load(open(sys.argv[1],"rb")); [name]=j.keys(); [pdata]=j.values()
print name
print pdata["formula"]["pkg_version"]
print pdata["bottle"]["rebuild"]
[(tag_name, tag_dict)]=pdata["bottle"]["tags"].items()
print tag_name
print tag_dict["sha256"]
'
"
$JSON
"
)
unset
JSON
{
local
i v
;
for
i
in
{
1..5
}
;
do
read
-r
v
eval
"
${
1
:?
}
=
\"
$v
\"
"
shift
done
}
<<<
"
$JSON_DATA
"
}
function
_brew_parse_package_info
{
# Get and parse `brew info --json` about a package
# and save it into bash variables specified in arguments
local
PACKAGE
;
PACKAGE
=
"
${
1
:?
}
"
;
shift
local
OS_CODENAME
;
OS_CODENAME
=
"
${
1
:?
}
"
;
shift
local
JSON_DATA
;
JSON_DATA
=
$(
python2.7
-c
'if True:
import sys, json, subprocess; j=json.loads(subprocess.check_output(("brew","info","--json=v1",sys.argv[1])))
data=j[0]
print data["versions"]["stable"]
bottle_data=data["bottle"]["stable"]
print bottle_data["rebuild"]
print bottle_data["files"].get(sys.argv[2],{"sha256":""})["sha256"]
'
\
"
$PACKAGE
"
"
$OS_CODENAME
"
)
unset
PACKAGE OS_CODENAME
{
local
i v
;
for
i
in
{
1..3
}
;
do
read
-r
v
eval
"
${
1
:?
}
=
\"
$v
\"
"
shift
done
}
<<<
"
$JSON_DATA
"
}
function
_brew_is_bottle_available
{
local
PACKAGE
;
PACKAGE
=
"
${
1
:?
}
"
local
INFO
=
"
$(
brew info
"
$PACKAGE
"
|
head
-n
1
)
"
if
grep
-qwF
'(bottled)'
<<<
"
$INFO
"
;
then
echo
"Bottle available:
$INFO
"
return
0
else
echo
"Bottle not available:
$INFO
"
return
1
fi
}
function
_brew_install_and_cache
{
# Install bottle or make and cache bottle.
# assumes that deps were already installed.
local
PACKAGE
;
PACKAGE
=
"
${
1
:?
}
"
local
USE_BOTTLE
;
USE_BOTTLE
=
"
${
2
:?
}
"
local
VERB
if
brew list
--versions
"
$PACKAGE
"
;
then
if
!
(
brew outdated |
grep
-qx
"
$PACKAGE
"
)
;
then
echo
"Already the latest version:
$PACKAGE
"
return
0
fi
VERB
=
upgrade
else
VERB
=
install
fi
if
[[
"
$USE_BOTTLE
"
-gt
0
]]
;
then
echo
"Installing bottle for:
$PACKAGE
"
brew
$VERB
"
$PACKAGE
"
else
echo
"Building bottle for:
$PACKAGE
"
brew
$VERB
--build-bottle
"
$PACKAGE
"
exec
3>&1
local
OUT
=
$(
brew bottle
--json
"
$PACKAGE
"
|
tee
/dev/fd/3
)
exec
3>&-
ls
"
$PACKAGE
"
*
# doesn't seem to be a documented way to get file names
local
BOTTLE
;
BOTTLE
=
$(
grep
-Ee
'^./'
<<<
"
$OUT
"
)
#proper procedure as per https://discourse.brew.sh/t/how-are-bottle-and-postinstall-related-is-it-safe-to-run-bottle-after-postinstall/3410/4
brew uninstall
"
$PACKAGE
"
brew
install
"
$BOTTLE
"
local
JSON
;
JSON
=
$(
sed
-E
's/bottle(.[[:digit:]]+)?\.tar\.gz$/bottle.json/'
<<<
"
$BOTTLE
"
)
#`brew bottle --merge` doesn't return nonzero on nonexisting json file
test
-f
"
$JSON
"
-a
-f
"
$BOTTLE
"
brew bottle
--merge
--write
"
$JSON
"
local
CACHED_BOTTLE
;
CACHED_BOTTLE
=
"
$(
brew
--cache
"
$PACKAGE
"
)
"
mv
"
$BOTTLE
"
"
$CACHED_BOTTLE
"
;
local
CACHED_JSON
;
CACHED_JSON
=
"
${
BREW_LOCAL_BOTTLE_METADATA
}
/
$(
basename
"
$JSON
"
)
"
mv
"
$JSON
"
"
$CACHED_JSON
"
#Symlinks aren't cached by Travis. Will just save paths in files then.
local
BOTTLE_LINK
;
BOTTLE_LINK
=
"
${
CACHED_JSON
}
.bottle.lnk"
echo
"
$CACHED_BOTTLE
"
>
"
$BOTTLE_LINK
"
fi
}
function
_brew_check_elapsed_build_time
{
# If time limit has been reached,
# arrange for further build to be skipped and return 1
local
TIME_START
;
TIME_START
=
"
${
1
:?
}
"
local
TIME_LIMIT
;
TIME_LIMIT
=
"
${
2
:?
}
"
local
ELAPSED_TIME
;
ELAPSED_TIME
=
$((
$(
date
+%s
)
-
$TIME_START
))
echo
"Elapsed time: "
$((
$ELAPSED_TIME
/
60
))
"m (
${
ELAPSED_TIME
}
s)"
if
[[
"
$ELAPSED_TIME
"
-gt
$TIME_LIMIT
]]
;
then
brew_go_bootstrap_mode
return
1
fi
return
0
}
function
_brew_check_slow_building_ahead
{
#If the package's projected build completion is higher than hard limit,
# skip it and arrange for further build to be skipped and return 1
local
PACKAGE
=
"
${
1
:?
}
"
local
TIME_START
=
"
${
2
:?
}
"
local
TIME_HARD_LIMIT
=
"
${
3
:?
}
"
PROJECTED_BUILD_TIME
=
$(
echo
"
$BREW_SLOW_BUILIDING_PACKAGES
"
|
awk
'$1=="'
"
$PACKAGE
"
'"{print $2}'
)
[
-z
"
$PROJECTED_BUILD_TIME
"
]
&&
return
0
||
true
local
PROJECTED_BUILD_END_ELAPSED_TIME
PROJECTED_BUILD_END_ELAPSED_TIME
=
$((
$(
date
+%s
)
-
TIME_START
+
PROJECTED_BUILD_TIME
*
60
))
if
[[
"
$PROJECTED_BUILD_END_ELAPSED_TIME
"
-ge
"
$TIME_HARD_LIMIT
"
]]
;
then
echo
-e
"
\n
Projected build end elapsed time for
$PACKAGE
:
$((
PROJECTED_BUILD_END_ELAPSED_TIME/60
))
m (
$PROJECTED_BUILD_END_ELAPSED_TIMEs
)"
brew_go_bootstrap_mode
return
1
fi
return
0
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录