1、前言html
上篇[1]主要介紹了利用csproj文件使用NuGet打包至ProGet的過程,並附上了用於在Jenkins上運行的python腳本。本篇的主要內容分爲如下幾點:node
1. Nuspec與Nupkg的關係python
2. dll文件該如何打包程序員
3. P4python的幾個操做算法
4. 融入jenkinsapi
5. 本週關於與組長的討論以及生活服務器
2、Nuspec與Nupkg的關係dom
上篇咱們說到,nuspec文件是nupkg的清單文件。可是有時候你會發現,明明你的項目裏有依賴項(dependency),可你進行nuget spec操做後,發現清單文件裏並無項目中所包含的依賴項,這是爲何?爲何進行nuget pack操做後纔會有依賴項,nupkg不是由清單文件nuspec才產生的嗎??ui
首先,咱們想一想整個過程。spa
第一步,咱們進入了項目文件所在的路徑,在CMD中執行了nuget spec操做。根據官方文檔[2] ,這時候實際上是你在初始化生成一個清單文件,一些基本的信息都是Token填充的($xxx$這樣的),若是你裝了Nuget package explorer,雙擊nuspec你會發現有左右兩側內容,左側是清單,右側是package content。而package content中的內容倒是你nuspec當前路徑下的全部文件。根據官方文檔,若是你沒提供須要打包的文件,它就會把當前nuspec所在文件夾中的全部內容放在package content中。那爲何以後執行nuget pack又正確的將內容打包了呢?接着往下走。
第二步,將部分標籤的值修改,防止打包失敗,例如<tags><description><releaseNotes>,不是默認就行
第三步,執行nuget pack XXX.csproj操做。這是很是重要的操做,你們都知道csproj文件實際上是個xml格式的文件,它會把整個項目的文件信息都以xml的形式記錄,在執行這個操做的時候,AssemblyInfo.cs與csproj 文件共同提供信息給nuspec文件,使其清單與打包內容正確,這時候項目中的依賴項就會正確的顯示在了包包中。
3、dll如何打包
關於dll 打包,這周感慨良多。一開始組長讓我搞通打包流程,我用的是csproj的打包方式,而後組長要求必須是dll。這下好,出現思想上的矛盾了。。。
組長的想法是這樣的:
個人想法是這樣的:
你們看到差異了吧,一個是在服務器上已經有一個製做好的nuspec文件,而我只須要在jenkins上執行修改版本號和打包上傳便可。另外一個是獲取dll後,在本地生成nuspec文件再打包上傳。看起來好像沒什麼太大區別哦,其實。。。差的挺多的。組長問,"你怎麼知道你打包須要哪些dll?""讓須要打包的人告訴我啊"「那好,我再問你,你爲何把須要打包的文件再以腳本方式寫入nuspec,這是要幹什麼」 「由於它們要打包在nupkg裏啊」 「你不會先編輯好nuspec嘛,這麼多打包的內容用list寫到nuspec裏,在jenkins裏這麼幹合適嗎?」
其實組長是把打包者與上傳者這兩個角色進行了拆分,而我是把二者結合在了一塊兒。假設一個打包者把nuspec文件以及相關的dll放在perforce服務器上,jenkins上的每個人均可以執行打包上傳任務,由於他不須要知道nuspec裏面的內容,只須要更新個版本號就能夠了。相反的,若是在jenkins上操做的並非打包者,那他並不知道須要打進哪些dll,須要添加或刪除哪些依賴項。那他就沒法打包了。
注意:csproj打包方式與dll不一樣,只要獲取csproj文件,就能執行自動化,由於AssemblyInfo.cs以及csproj文件已經能充分提供信息了。
4、P4python的幾個操做
說實話,p4python官方[3]的幾個例子作的有點渣,好歹說一下怎麼checkout吧。。。沒辦法,根據手上現有的資料和網上看看國外的論壇,分享三個比較實用的操做吧。
(1) 把文件checkout到一個新的changelist中(可不是default哦)
#checkout到一個新的changelist中 desc ={"Description":p4description,"Change":"new"} p4.input = desc info = p4.run("change","-i") for s in info: changelistNumber =s.split(" ",2)[1] changelistId = changelistNumber checkoutfiles=sys.argv[11] #checkout的路徑 submittedFiles=[checkoutfiles] #所須要checkout的文件路徑 for submittedFile in submittedFiles: p4.run("edit",["-c"+""+changelistId,submittedFile]) #checkout
(2) revertunchangedfiles
def revertunchangedFile(p4,files): try: for file in files: p4.run("revert",[ "-a",file]) except Exception as ex: return False
(3) revertfiles
def revertFile(p4,files): try: for file in files: p4.run("revert",file) except Exception as ex: return False
5、融入jenkins
(1)以csproj的方式打包,從新整理
1 # coding=gbk 2 import os 3 import sys 4 import re 5 from P4 import P4 6 7 def getdisc(projectpath): #得到項目文件的當前盤 8 disc = projectpath.split(':', 1)[0] 9 disc = disc+":" 10 return disc 11 12 def modifynuspec(projectfilepath,projectname): #修改nuspec文件內容 13 tfile = projectfilepath+"\\"+projectname+".nuspec" 14 f = open(tfile,'r') 15 xmldata = f.read() 16 xmldata = re.sub('\<description>(.*?)\</description>', '<description>'+projectname+'</description>', xmldata) 17 xmldata = re.sub('\<tags>(.*?)\</tags>', '', xmldata) 18 xmldata = re.sub('\<releaseNotes>(.*?)\</releaseNotes>','', xmldata) #刪除裏面不用的字段 19 f.close() 20 f = open(tfile,'w') 21 f.write(xmldata) 22 f.close() 23 24 def autoversion(projectpath): #替換版本 25 assemblyInfoFile = projectpath+"\\Properties\\AssemblyInfo.cs" 26 lines= open(assemblyInfoFile, 'r+', encoding='iso-8859-15').readlines() 27 flen=len(lines)-1 28 for i in range(flen): 29 if lines[i].startswith("[assembly: AssemblyVersion"): 30 versioncode = lines[i].split('"', 2)[1] #得到當前assemblyinfo的 31 break 32 oldVersion = versioncode 33 splitedVersion = oldVersion.split('.') 34 lastSubVersion = int(splitedVersion[3]) 35 lastSubVersion += 1 36 splitedVersion[3] = str(lastSubVersion) 37 newVersion = '.'.join(splitedVersion) #將當前的assemblyVersion+1 38 if not os.path.exists(assemblyInfoFile): 39 return 40 fileContent = open(assemblyInfoFile, 'r+', encoding='iso-8859-15').read() 41 fileContent = fileContent.replace(oldVersion,newVersion) #把版本替換完重寫文件 42 file = open(assemblyInfoFile,'w+', encoding='iso-8859-15') 43 file.write(fileContent) 44 file.flush() 45 file.close() 46 return newVersion 47 48 def revertunchangedFile(p4,files): 49 try: 50 for file in files: 51 p4.run("revert",[ "-a",file]) 52 except Exception as ex: 53 return False 54 55 def revertFile(p4,files): 56 try: 57 for file in files: 58 p4.run("revert",file) 59 except Exception as ex: 60 return False 61 62 def findNugetpack(projectfilepath,searchKeywords): 63 li = os.listdir(projectfilepath) 64 for filename in li: 65 if filename.endswith(".nupkg") and searchKeywords in filename: 66 nupkgpath = projectfilepath+"\\"+ filename 67 return nupkgpath 68 69 if __name__ == '__main__': 70 if len(sys.argv)!=15: 71 sys.exit(-1) 72 73 #鏈接P4並同步文件 74 p4 = P4() 75 p4.port = sys.argv[1] #端口號 76 p4.user =sys.argv[2] #用戶 77 p4.password = sys.argv[3] #密碼 78 p4.client =sys.argv[4] #本地盤 79 p4.connect() 80 #鏈接P4並同步文件 81 82 #打包參數設置 83 NuGetpath =sys.argv[5] #NuGet.exe路徑 84 Projectfilepath =sys.argv[6] #項目路徑 85 Projectname =sys.argv[7] #項目名稱 86 ProGetSourceUrl =sys.argv[8] #上傳的ProGet地址 87 ProGetAdmin =sys.argv[9] #ProGet用戶名 88 ProGetPassword =sys.argv[10] #ProGet密碼 89 #打包參數設置 90 91 p4description = sys.argv[11] #P4checkout時的描述 92 93 #checkout到一個新的changelist中 94 desc ={"Description":p4description,"Change":"new"} 95 p4.input = desc 96 info = p4.run("change","-i") 97 for s in info: 98 changelistNumber =s.split(" ",2)[1] 99 changelistId = changelistNumber 100 101 checkoutfiles=sys.argv[12] #checkout的路徑 102 submittedFiles=[checkoutfiles] #所須要checkout的文件路徑 103 for submittedFile in submittedFiles: 104 p4.run("edit",["-c"+""+changelistId,submittedFile]) 105 #checkout 106 107 # 改變版本 108 Newversion = autoversion(Projectfilepath) 109 # 改變版本 110 111 ProGetAPIKey = sys.argv[13] #API key 112 try: 113 #打包 114 NuGetdisc = getdisc(NuGetpath) 115 ProjectDisc = getdisc(Projectfilepath) 116 Projectnuspec =Projectfilepath+"\\"+Projectname+".nuspec" 117 if not os.path.exists(Projectnuspec): 118 os.system(''+NuGetdisc+'&&cd '+NuGetpath+'&&nuget setApiKey '+ProGetAPIKey+'') 119 os.system(''+ProjectDisc+'&&cd '+Projectfilepath+'&&nuget spec') 120 modifynuspec(Projectfilepath,Projectname) 121 Projectnamecsproj = Projectname+".csproj" 122 os.system(''+ProjectDisc+'&&cd '+Projectfilepath+'&&nuget pack '+Projectnamecsproj+' -Build') 123 124 SearchKeywords=sys.argv[14] #搜索關鍵詞 125 Nupkgpath = findNugetpack(Projectfilepath,SearchKeywords) 126 os.system(''+NuGetdisc+'&&cd '+NuGetpath+'&&nuget push '+Nupkgpath+' '+ProGetAPIKey+' -Source '+ProGetSourceUrl+' -ApiKey '+ProGetAdmin+':'+ProGetPassword+'') 127 #打包 128 129 revertunchangedFile(p4,submittedFiles) 130 p4.run("change",["-d"],changelistId) 131 except Exception as ex: 132 revertFile(p4,submittedFiles) 133 p4.run("change",["-d"],changelistId) 134 p4.disconnect()
(2)以dll的方式打包
1 # coding=gbk 2 import os 3 import sys 4 import re 5 import xml.dom.minidom 6 import win32api 7 8 from P4 import P4 9 10 def getdisc(projectpath): #得到項目文件的當前盤 11 disc = projectpath.split(':', 1)[0] 12 disc = disc+":" 13 return disc 14 15 def Checknode(filepath,nodename): 16 dom = xml.dom.minidom.parse(filepath) 17 root = dom.documentElement 18 for rt in root.childNodes: 19 for rt1 in rt.childNodes: 20 if rt1.nodeName == nodename: 21 for node in rt1.childNodes: 22 return node.nodeValue 23 24 25 def getFileVersion(file_name): 26 info = win32api.GetFileVersionInfo(file_name, os.sep) 27 ms = info['FileVersionMS'] 28 ls = info['FileVersionLS'] 29 version = '%d.%d.%d.%04d' % (win32api.HIWORD(ms), win32api.LOWORD(ms), win32api.HIWORD(ls), win32api.LOWORD(ls)) 30 return version 31 32 def modifynuspec(projectnuspec,dllfilepath): 33 tfile = projectnuspec 34 f = open(tfile,'r') 35 xmldata = f.read() 36 #oldversion = Checknode(tfile,"version") 按照默認版本號加1(預留) 37 #listindex=int(len(oldversion.split("."))-1) 38 #newversion = int(oldversion.split(".")[listindex])+1 39 #newversion = oldversion[:-1]+str(newversion) 40 dllversion = getFileVersion(dllfilepath) #按照dll版本號 41 xmldata = re.sub('\<version>(.*?)\</version>', '<version>'+dllversion+'</version>', xmldata) 42 f.close() 43 f = open(tfile,'w') 44 f.write(xmldata) 45 f.close() 46 47 def findNugetpack(nuspecfilepath,searchKeywords): 48 li = os.listdir(nuspecfilepath) 49 for filename in li: 50 if filename.endswith(".nupkg") and searchKeywords in filename: 51 nupkgpath = nuspecfilepath+"\\"+ filename 52 return nupkgpath 53 54 55 if __name__ == '__main__': 56 if len(sys.argv)!=13: 57 sys.exit(-1) 58 59 60 #鏈接P4並同步文件 61 p4 = P4() 62 p4.port = sys.argv[1] 63 p4.user = sys.argv[2] 64 p4.password = sys.argv[3] 65 p4.client = sys.argv[4] 66 p4.connect() 67 #鏈接P4並同步文件 68 69 #打包參數設置 70 NuGetpath =sys.argv[5] 71 Nuspecfilepath =sys.argv[6] 72 Nuspecfilename = sys.argv[7] 73 ProGetSourceUrl = sys.argv[8] 74 ProGetAdmin =sys.argv[9] 75 ProGetPassword =sys.argv[19] 76 ProGetApiKey=sys.argv[11] 77 #打包參數設置 78 79 #打包 80 NuGetdisc = getdisc(NuGetpath) 81 ProjectDisc = getdisc(Nuspecfilepath) 82 Projectnuspec =Nuspecfilepath+"\\"+Nuspecfilename+".nuspec" 83 Dllfilepath = sys.argv[12] 84 if os.path.exists(Projectnuspec): 85 modifynuspec(Projectnuspec,Dllfilepath) 86 Projectnuspecname = Nuspecfilename+".nuspec" 87 os.system(''+ProjectDisc+'&&cd '+ Nuspecfilepath+'&&nuget pack '+Projectnuspecname+'') 88 Nupkgpath = findNugetpack(Nuspecfilepath,Nuspecfilename) 89 os.system(''+NuGetdisc+'&&cd '+NuGetpath+'&&nuget push '+Nupkgpath+' '+ProGetApiKey+' -Source '+ProGetSourceUrl+' -ApiKey '+ProGetAdmin+':'+ProGetPassword+'') 90 else: 91 sys.exit(-1) 92 p4.disconnect()
6、與組長的溝通以及生活
工做快倆月了。這半個月過得不太順心,在工做與生活中都意識到了本身的不足。就拿打包這事來講吧,組長本想培養我自我探索自我理清思路的能力,可我只是把每一個具體的點搞清楚了,卻沒有從總體流程去思考,好比dll打包過程當中的想法,這是個能力的缺失點。用打刀塔的09的話說「缺乏大菊觀」。剛進公司我在組A,A組的領導讓我實現基本的小模塊功能就行,到了組B,開始搞總體流程的時候就矇蔽了。
在學校,導師教會了我迎難而上,堅韌不拔的科研精神,由於有時候搞科研就是那一套複雜的方程組,你必須用一些方式去解,沒有其餘餘地。在公司,組長教會了我靈活變通的去解決問題,從一個更高的層次去想每一個流程是怎麼樣的,該以一個最有效率的方法去解決問題,而不是製造問題。
組長人特別好,每次都不厭其煩的給我洗腦,我挺愧疚的,好屢次我都在想爲何不能作的更完美些,而後又給本身挖了個大坑,作了許多重複的事情。組長說,「要當一個有思想的程序員,否則就只是搬代碼。不少時候應該想一想,我爲何這麼作,我作這件的事的意義在哪兒。」
生活上,這個月感情崩了,該來的仍是要來,好聚好散,彼此都祝福了對方。
這個月惟一的好消息是,畢業前發的一篇SCI總算要出刊了,看到樣稿很是開心,特別感謝編輯們的辛勤排版。還有一篇關於算法的SCI還在審。。。都快5個月了我也是醉了。
最後,感謝個人組長!!!並祝各位博友能一切順利,人生不如意之事十之八九,仍是要以積極心態去面對,我相信只要肯努力,肯動腦,終究會成功的。有什麼能夠討論的歡迎留言,多多指教~
References:
[1] http://www.cnblogs.com/lovecsharp094/p/5527204.html
[2] https://docs.nuget.org/create/nuspec-reference
[3] https://www.perforce.com/perforce/doc.current/manuals/p4script/03_python.html
做者:airforce094
出處:http://www.cnblogs.com/lovecsharp094/p/5551120.html
轉載請註明原文出處 , 謝謝合做