fabric与alfred的结合使用案例
安装 Pyenv-Python版本管理神器
删除自己手动安装的python
一般我们手动安装就是从python官网下载:
https://www.python.org/downloads/
下载python3.7.0,安装python3.7.
不过对于删除 Python,我们首先要知道其具体都安装了什么,实际上,在安装 Python 时,其自动生成:
- Python.framework目录;例如:/Library/Frameworks/Python.framework
- Python 应用目录;例如:/Applications/Python x.x
- 指向 Python 的连接。
对于 Mac 自带的 Python,其框架目录为:
System/Library/Frameworks/Python.framework
而用户安装的 Python,其(默认)框架目录为:
/Library/Frameworks/Python.framework
接下来,我们就分别(在 Mac 终端进行)删除上面所提到的三部分,删除用户安装的python,系统的python别随便删除了,可能系统某个组件要用到呢。
第 1 步,删除用户安装的框架:
sudo rm -rf /Library/Frameworks/Python.framework/Versions/x.x
第 2步,删除应用目录:
sudo rm -rf "/Applications/Python x.x"
第 3 步,删除指向 Python 的连接:
cd /usr/local/bin/
ls -l /usr/local/bin | grep '../Library/Frameworks/Python.framework/Versions/x.x' | awk '{print $9}' | tr -d @ | xargs rm12
至此,我们已经成功删除 Python 的相关文件,其中x.x
为 Python 的版本号。
安装pyenv
安装pyenv,一个可以任意切换python版本的工具,建议安装之前,按照如上可以把自己安装的python都卸载掉
我用的是mac,安装就简单很多,直接使用Homebrew:
$ brew update
$ brew install pyenv
$ brew install virtualenv (可选装,这个是创建虚拟环境使用的)
$ pyenv --version
pyenv 1.2.7
# checkout pyenv到pyenv安装的路径下
$ git clone https://github.com/pyenv/pyenv.git ~/.pyenv
# 在~/.bash_profile定义PYENV_ROOT 环境变量
·········edit·~/.bash_profile··············
# Define environment variable PYENV_ROOT
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
if command -v pyenv 1>/dev/null 2>&1; then
eval "$(pyenv init -)"
fi
········································
# 使用pyenv commands可以查看所有pyenv命令
$ pyenv commands
--version
activate
commands
completions
deactivate
...
配置pyenv自动补全
$ source $(pyenv root)/pyenv/completions/pyenv.bash
安装python
$ pyenv install -l # 查看可用的python版本
$ pyenv install <version> # 安装版本号为<version>的Python
$ pyenv uninstall <version> #卸载版本号为<version>的Python
查看已安装Python版本
比如我安装了,python2.7,3.7.0,3.5.2
$ pyenv versions
system
2.7
3.5.2
* 3.7.0 (set by /Users/che/.pyenv/version)
Python 版本管理
$ pyenv global <version> # 全局设置python版本为指定版本,设置全局的 Python 版本,通过将版本号写入 ~/.pyenv/version (如果没有会自动创建)文件的方式。
$ pyenv local <version> # 设置当前路径下python版本为指定版本,设置 Python 本地版本,通过将版本号写入当前目录下的 .python-version 文件(会自动创建)的方式。通过这种方式设置的 Python 版本优先级较 global 高。
$ pyenv shell <version> # 设置当前shell窗口使用的python版本为指定版本,设置面向 shell 的 Python 版本,通过设置当前 shell 的 PYENV_VERSION 环境变量的方式。这个版本的优先级比 local 和 global 都要高。–unset 参数可以用于取消当前 shell 设定的版本。
Python版本的优先级
shell > local > global
pyenv会从当前目录开始向上逐级查找.python-version文件,直到根目录为止,若找不到,则使用global版本。
$ pyenv rehash # 创建垫片路径(为所有已安装的可执行文件创建 shims,如:~/.pyenv/versions/*/bin/*,因此,每当你增删了 Python 版本或带有可执行文件的包(如 pip)以后,都应该执行一次本命令)
到目前为止python已经安装完全。也大概了解了pyenv的使用方式。接下来我们就来安装fabric
安装fabric
由于fabric强烈依赖于python,所有我们把python环境弄好,相当于完成了1/4。
把python version切换到2.7
$ pyenv global 2.7
$ pip install fabric==1.14.0
fabric2 慎入,下面是安装fabric2的安装流程,但是新版本fabric玩不起…太危险...里面很多功能和fabric1的区别很大,很多命令都不一样。
把python version切换到3.7.0
$ brew update $ pip install invoke $ pip install paramiko # brew reinstall openssl (如果出现openssl的问题,可以重装试下) $ pip install fabric2 $ fab2 --version Fabric 2.3.1 Paramiko 2.4.1 Invoke 1.1.1 $ python Python 3.7.0 (default, Aug 23 2018, 12:47:24) [Clang 9.1.0 (clang-902.0.39.2)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> from fabric import Connection (官网的第一句都执行出错...) Traceback (most recent call last): File "<stdin>", line 1, in <module> ModuleNotFoundError: No module named 'fabric' >>>
算了(liao)算了(liao),哪位勇士敢于人先,成功了,记得告诉我。
Hello Fabric
在工作目录中创建一下==fabfile.py==模块文件中
然后向其中添加如下代码
def hello():
print("Hello world!")
接着执行
$ fab hello
Hello world!
Done.
以上就是配置文件的全部。它基于 Fabric 实现了一个(极其)简单的构建工具,简单到甚至不用导入任何 Fabric API。
简单的栗子
1.在~/Documents/fabric目录下创建一个testdir目录
2.在~/Documents/fabric目录下创建一个fabfile.py
from fabric.api import local,lcd
def clone():
local("git clone https://github.com/CNiceToUpp/xcode_tool.git")
def commit():
local("echo 'hello fabric' >> test.file") <== the changes
local("git add . && git commit -m 'add test.file'")
def push():
local("git push")
def prepare_deploy():
with lcd("~/Documents/fabric/testdir"):
clone()
with lcd("~/Documents/fabric/testdir/xcode_tool"):
commit()
push()
3.在~/Documents/fabric目录下运行==fab prepare_deploy==
$ fab prepare_deploy
[localhost] local: git clone https://github.com/CNiceToUpp/xcode_tool.git
Cloning into 'xcode_tool'...
remote: Counting objects: 44, done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 44 (delta 0), reused 2 (delta 0), pack-reused 40
Unpacking objects: 100% (44/44), done.
[localhost] local: echo 'hello fabric' >> test.file
[localhost] local: git add . && git commit -m 'add test.file'
[master 42b13af] add test.file
1 file changed, 1 insertion(+)
[localhost] local: git push
Counting objects: 3, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 265 bytes | 265.00 KiB/s, done.
Total 3 (delta 1), reused 0 (delta 0)
remote: Resolving deltas: 100% (1/1), completed with 1 local object.
To https://github.com/CNiceToUpp/xcode_tool.git
01cb01e..42b13af master -> master
Done.
$ tree . -L 2
.
├── fabfile.py
├── fabfile.pyc
└── testdir
└── xcode_tool
Ok,栗子展示成功。
fabric高级功能
上面的栗子已经教会了如何使用基本的fabric功能
具体的高级功能参考这里
fabric高级功能栗子
deploy task完成一个git clone , 修改文件,git add . ,git commit ,git push 等一系列操作,并且deploy task会在'root@serverip1','cnicetoupp@serverip2','cnicetoupp@serverip3','cnicetoupp@serverip4' 中进行。本来是可以进行并行操作的,但是考虑到在不同机器上git pull ,git push ,会导致冲突,所以改成了串行的了。
在运行之前,要先做好对这些机器ssh免密登录。
在本机运行==ssh-keygen -t rsa==命令。接着全部按回车键,即生成密钥。
之后通过==ssh-copy-id -i ~/.ssh/id_rsa.pub remote_ip==把本机的公钥放到远程机器的authorized_keys.
$ ssh-keygen -t rsa
$ ssh-copy-id -i ~/.ssh/id_rsa.pub remote_ip
当然,远程机器必须也要有git环境,并且最好git 也能免密
在远程机器的~/.gitconfig中添加如下,则所有的git repo都在登录一次之后将免密。
[credential]
helper = store
如果只对某一个repo实现免密,可在repodir/.git/config文件中配置如上。
fabric.py
from __future__ import with_statement
# 这个栗子所使用到的工具类
from fabric.api import run,cd,hosts,settings,env,parallel
from fabric.contrib.console import confirm
from fabric.colors import *
def clone():
with settings(warn_only=True):
if run("git clone https://github.com/CNiceToUpp/xcode_tool.git").failed:
print(red("clone failed"))
else:
print(green("clone successfully"))
def commit():
with settings(warn_only=True):
run("echo 'hello fabric' >> test.file")
if run("git add . && git commit -m 'add test.file'").failed:
print(red("commit failed"))
else:
print(green("commit successfully"))
def push():
with settings(warn_only=True):
if run("git push").failed:
print(red("push failed"))
else:
print(green("push successfully"))
@hosts('root@serverip1','cnicetoupp@serverip2','cnicetoupp@serverip3','cnicetoupp@serverip4')
# @parallel ## 并行执行task 不过在这里并不适用,因为在不同的host同时push,会导致在pull的时候出现conficts.
def deploy():
code_dir = '~/Documents/fabric'
with settings(warn_only=True):
if run("test -d %s" % code_dir).failed:
run("mkdir -p %s" % code_dir)
with cd("~/Documents/fabric/"),settings(warn_only=True):
if run("test -d %s" % code_dir).failed:
clone()
with cd("~/Documents/fabric/xcode_tool"):
commit()
push()
alfred + fabric
在这里,还可以使用alfred更快捷的触发命令。在这里创建一个workflow
alfred_workflow输入为:List Filter
listfilter触发fab deploy操作为:Run Script
runscript输出为2个,一个是将输出写入到一个文件中,一个是post Notification
write to Post Notification
postnotificationwrite to file
writetofile操作流程大概是如下:
alfred_fabric输出结果为一mac系统通知和一个输出文件alfred_fabric_output.log。
总结
pyenv和fabric,alfred都是提高工作效率的小工具,利用好的话,能大大简化工作流程。除了pyenv,还有jenv,scalaenv等等语言管理工具。这里只是做了简单的使用介绍,通过扩展可以将其中的原理应用到自己的工作中,把一些重复,无效的工作写进脚本中,通过alfred一键部署。这也是写这篇文章的目的。
参考
https://www.zhihu.com/question/30941329
https://github.com/pyenv/pyenv (pyenv github 1w多星,可显示它的强大)
https://fabric-chs.readthedocs.io/zh_CN/chs/tutorial.html(fabric1.X)