maven version
來進行版本管理。主要還是在分散式專案中模組眾多的場景中使用,畢竟各個模組對外的版本需要保持統一。versions-maven-plugin
。 具體用法以後有機會在贅述。batfhmerge.sh
和 batchgrade.sh
就搞定了。SNAPSHOT
版本來保證別人拉取到你最新的功能程式碼,但是有些公司會要求使用非 SNAPSHOT
版本進行管理也就是正式版本,這樣做的好處就是容易找到之前的版本程式碼功能。# 該指令碼主要用來升級發包期間修改各服務版本
FILEPATH=$1
GROUPID=$2
ARTIFACTID=$3
FILENAME=$4
while getopts ":f:g:a:" opt
do
case $opt in
f)
FILENAME=$OPTARG
echo "您輸入的檔案設定:$FILENAME"
;;
g)
GROUPID=$OPTARG
echo "您輸入的groupid設定:$GROUPID"
;;
a)
ARTIFACTID=$OPTARG
echo "您輸入的artifactid設定:$ARTIFACTID"
;;
ff)
FILENAME=$OPTARG
echo "您輸入的帶修改檔案為:$FILENAME"
;;
?)
echo "未知引數"
exit 1;;
esac
done
echo "開始修改版本號"
NEWCONTENT=1.2.5.$(date +%Y%m%d)
LINE=`cat ${FILENAME} | grep -n -A 1 '<groupId>'"${GROUPID}"'<\/groupId>'| grep -n '<artifactId>'"${ARTIFACTID}"'<\/artifactId>' | awk -F "[:-]+" '{print $2}'`
echo 具體行號:$LINE
if [[ -z $LINE ]]
then
echo 未匹配
exit
fi
VERSIONOLDCONTENT=`sed -n ''"$((LINE+1))"'p' ${FILENAME}| grep '[0-9a-zA-Z\.-]+' -Eo | sed -n '2p'`
echo ${VERSIONOLDCONTENT}
#gsed -i ''"$((LINE+1))"'c\'"${NEWCONTENT}"'' pom.xml
sed -i "" ''"$((LINE+1))"'s/'"${VERSIONOLDCONTENT}"'/'"${NEWCONTENT}"'/' ${FILENAME}
groupId
和 artifactId
,最後確定好 version
對應的行號將最新的日期字尾版本進行填充進去。SED
進行操作,那就需要先獲取到以前的舊版本,然後進行替換操作。pom.xml
檔案他是一個 XML 格式的檔案, XML=eXtensible Markup Language 。即是一種可延伸的標示語言。它與 JSON 一樣主要用來儲存和傳輸資料。在之前的Springboot章節中我們也實現瞭如何實現介面傳遞 XML 資料結構。常見的 XML 程式設計介面有 DOM 和 SAX,這兩種介面處理 XML 檔案的方式不同,當然使用場合也不同。
Python 有三種方法解析 XML,SAX,DOM,以及 ElementTree:
### 1.SAX (simple API for XML )
Python 標準庫包含 SAX 解析器,SAX 用事件驅動模型,通過在解析XML的過程中觸發一個個的事件並呼叫使用者定義的回撥函數來處理XML檔案。
### 2.DOM(Document Object Model)
將 XML 資料在記憶體中解析成一個樹,通過對樹的操作來操作XML。
### 3.ElementTree(元素樹)
ElementTree
。ElementTree
在 python3中已經作為標準庫存在了,所以這裡不需要我們額外的安裝。基於事件和基於檔案的APID來解析XML,可以使用XPath表示式搜尋已解析的檔案,具有對檔案的增刪改查的功能,該方式需要注意大xml檔案,因為是一次性載入到記憶體,所以如果是大xml檔案,不推薦使用該模組解析,應該使用sax方式
pom.xml
檔案不會很大的。ElementTree
通過 XPath
進行節點選擇,所以關於xml 節點查詢我們可以參考 xpath 語法即可。<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.github.zxhTom</groupId>
<artifactId>bottom</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>bottom</name>
<url>http://maven.apache.org</url>
<description>最底層的繁瑣封裝</description>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<log4j2.version>2.10.0</log4j2.version>
</properties>
<dependencies>
<!-- 20180927提供了針對stirng bean list 等判斷的操作。不用我們在詳細的判斷了 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.7</version>
</dependency>
<!-- 提供了針對list 等判斷的操作。不用我們在詳細的判斷了 -->
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.2.1</version>
</dependency>
<!-- jsonobeject jar包依賴 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.28</version>
</dependency>
<!-- 紀錄檔記錄 -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>${log4j2.version}</version>
</dependency>
<!-- 通過反射獲取標有註解的類 -->
<dependency>
<groupId>org.reflections</groupId>
<artifactId>reflections</artifactId>
<version>0.9.10</version>
</dependency>
</dependencies>
</project>
pom.xml
摘自於 com.github.zxhTom
的 bottom 專案中。裡面的恰好出現了註釋,方便我們後期測試。import xml.etree.ElementTree as ET
with open('pom.xml', 'tr', encoding='utf-8') as rf:
tree = ET.parse(rf)
print(tree)
ET.parse
即可解析出來 xml 。import xml.etree.ElementTree as ET
with open('pom.xml', 'tr', encoding='utf-8') as rf:
tree = ET.parse(rf)
# 根據tree進行遍歷
for node in tree.iter():
print(node.tag)
import xml.etree.ElementTree as ET
with open('pom.xml', 'tr', encoding='utf-8') as rf:
tree = ET.parse(rf)
# tree遍歷
for node in tree.findall('.//dependency'):
print(node.tag)
pom.xml
中的名稱空間,在跟節點 project 標籤中設定的xmlns
屬性。至於為什麼需要這個呢?每個xml 標籤內容都是自定義的,比如你可以將dependency用來做版本號的作用,只要你自己解析的時候注意就行了。而maven中將dependency作為引入座標的概念,每個人的想法不一,所以引入名稱空間,在指定的名稱空間中標籤的作用是唯一的,這就是 xmlns
存在的意義。import xml.etree.ElementTree as ET
with open('pom.xml', 'tr', encoding='utf-8') as rf:
tree = ET.parse(rf)
# tree遍歷
for node in tree.findall('.//{http://maven.apache.org/POM/4.0.0}dependency'):
print(node.tag)
通過上面的內容我們知道在定位節點時候需要加入名稱空間。
首先我們知道 com.alibaba.fastjson
的版本號是 1.2.28
import xml.etree.ElementTree as ET
with open('pom.xml', 'tr', encoding='utf-8') as rf:
tree = ET.parse(rf)
# tree遍歷
for node in tree.findall('.//{http://maven.apache.org/POM/4.0.0}dependency'):
groupIdNode=node.find('.{http://maven.apache.org/POM/4.0.0}groupId')
artifactNode=node.find('.{http://maven.apache.org/POM/4.0.0}artifactId')
if(artifactNode.text=='fastjson' and groupIdNode.text=='com.alibaba'):
print(node.find('.{http://maven.apache.org/POM/4.0.0}version').text)
python3 upgrade.py
即可列印出 1.2.28
。com.alibaba.fastjson
的版本號升級為1.2.29
吧。import xml.etree.ElementTree as ET
with open('pom.xml', 'tr', encoding='utf-8') as rf:
tree = ET.parse(rf)
# tree遍歷
for node in tree.findall('.//{http://maven.apache.org/POM/4.0.0}dependency'):
groupIdNode=node.find('.{http://maven.apache.org/POM/4.0.0}groupId')
artifactNode=node.find('.{http://maven.apache.org/POM/4.0.0}artifactId')
if(artifactNode.text=='fastjson' and groupIdNode.text=='com.alibaba'):
node.find('.{http://maven.apache.org/POM/4.0.0}version').text='1.2.29'
tree.write('pom.xml')
pom.xml
好像並不是只改了version標籤的內容。
API追蹤
def write(self, file_or_filename,
encoding=None,
xml_declaration=None,
default_namespace=None,
method=None, *,
short_empty_elements=True):
/Lib/xml/etree/ElementTree.py
原始碼就能夠看到在寫會 xml 檔案的時候我們一共有7個引數可選,其中第一個self 沒啥好說的。屬性 | 作用 |
---|---|
file_or_filename | 檔案 |
encoding | 輸出的編碼格式;預設US-ASCII |
xml_declaration | 將XML宣告新增到檔案中: True新增;False不新增;None在非US-ASCII 或 UTF-8 或 Unicode時新增; 預設None |
default_namespace | 預設的名稱空間 |
method | xml、 html 、 text。預設 xml |
short_empty_elements | 空內容的標籤時的處理 |
tree.write('pom.xml',default_namespace='http://maven.apache.org/POM/4.0.0')
UTF-8
的。tree.write('pom.xml',default_namespace='http://maven.apache.org/POM/4.0.0',encoding='UTF-8')
xml_declaration
就是控制是否生成標準申明的。with open('pom.xml', 'tr', encoding='utf-8') as rf:
tree = ET.parse(rf)
TreeBuilder
進行渲染的,其中 CommentHandler 就是 TreeBuilder.comment 進行的。那麼我們繼續檢視下 TreeBuilder 的原始碼來檢視為什麼預設的 parser 沒有保留下注釋。_comment_factory
, 而這個類就是產生 Comment 。 因為insert_comments=False , 所以預設的TreeBuilder對於註釋只會產生一個空的Comment物件,所以我們通過ET.write出來的pom.xml中關於註釋部分就是空白代替,就是因為這個原因。class CommentedTreeBuilder (ET.TreeBuilder):
def comment(self,data):
self.start(ET.Comment,{})
self.data(data)
self.end(ET.Comment)
上述程式碼類似於 Java中繼承了 TreeBuilder 並且重寫了 comment方法。主要的邏輯就是開頭一個註釋標籤屬性為空,結尾是一個註釋標籤結尾,中間的內容是我們註釋的內容,所以綜上就是保留下來註釋。
重寫了類之後我們還需要在ET中指定我們自定義的TreeBuilder 。
parser = ET.XMLParser(target=CommentedTreeBuilder())
tree = ET.parse(xml_path,parser=parser)
# tree遍歷
for node in tree.findall('.//{http://maven.apache.org/POM/4.0.0}dependency'):
print(node.tag)
ns = {'real_mvn': 'http://maven.apache.org/POM/4.0.0',
'vistual': 'http://characters.zxhtom.com'}
# tree遍歷
for node in tree.findall('.//real_mvn:dependency',ns):
print(node.tag)
檔案 | dependency數量 |
---|---|
knife4j-spring-ui-1.9.6.pom | 0 |
spring-context-support-1.0.6.pom | 3 |
spring-core-5.1.7.RELEASE.pom | 10 |
springfox-swagger-common-3.0.0.pom | 11 |