001package org.vishia.guiBzr; 002 003import java.io.BufferedReader; 004import java.io.File; 005import java.io.FileNotFoundException; 006import java.io.FileReader; 007import java.io.IOException; 008import java.text.DateFormat; 009import java.text.SimpleDateFormat; 010import java.util.LinkedList; 011import java.util.List; 012 013import org.vishia.mainCmd.MainCmd_ifc; 014import org.vishia.mainCmd.Report; 015import org.vishia.util.FileSystem; 016 017public class BzrGetStatus 018{ 019 020 /**TODO only private local using here, it should be a part of DataProject. 021 * 022 */ 023 List<File> listBzrDirs = new LinkedList<File>(); 024 025 final MainData mainData; 026 027 final MainCmd_ifc mainCmdifc; 028 029 /**The format of a timestamp in the log output. */ 030 private final DateFormat logDateFormat= new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); 031 032 033 private final List<DataFile> listUnknownFiles = new LinkedList<DataFile>(); 034 035 public BzrGetStatus(MainCmd_ifc mainCmdifc, MainData mainData) 036 { this.mainCmdifc = mainCmdifc; 037 this.mainData = mainData; 038 } 039 040 041 042 /**Searches all locations of source-archives in the current project folder and all sub folders. 043 * A project means a software project with some sources consisting of some Components with its own archives. 044 * @calls {@link #captureStatus(DataCmpn)} for all found software-archives. 045 * @param sProjectPath Path to the project folder. 046 * 047 */ 048 void getBzrLocations(String sProjectPath) 049 { 050 listBzrDirs.clear(); 051 try{ FileSystem.addFileToList(sProjectPath + "/**/.bzr", listBzrDirs); 052 } catch(Exception exc){ } 053 int zCmpn = listBzrDirs.size(); 054 mainData.currPrj.init(zCmpn); 055 //int ixCmpn = 0; 056 for(File fileBzr: listBzrDirs){ 057 File bzrLocation = fileBzr.getParentFile(); 058 int ixCmpn = mainData.currPrj.createComponentsData(bzrLocation); 059 ixCmpn +=1; 060 } 061 } 062 063 064 065 /**Captures the status of a software archive of one component in comparison of its real source files. 066 * <ul> 067 * <li>last revision of files, last revision in archive, number and timestamp 068 * <li>get status 069 * </ul> 070 * It fills the indexed instance of {@link DataCmpn} 071 * @param ixData The index of the component, index in data 072 */ 073 void captureStatus(DataCmpn data) 074 { 075 //DataCmpn data = mainData.currPrj.data[ixData]; 076 data.uBzrError.setLength(0); 077 data.uBzrLastVersion.setLength(0); 078 data.uBzrStatusOutput.setLength(0); 079 mainData.cmdExec.setCurrentDir(data.dirWorkingtree); 080 String sCmdStatus = mainData.cfg.indexCmds.get("status"); 081 String sCmdheadRevision = mainData.cfg.indexCmds.get("headRevision"); 082 mainCmdifc.writeInfo(sCmdStatus); 083 mainData.cmdExec.execute(sCmdStatus, null, data.uBzrStatusOutput, data.uBzrError); 084 mainCmdifc.writeInfo(sCmdheadRevision); 085 mainData.cmdExec.execute(sCmdheadRevision, null, data.uBzrLastVersion, data.uBzrError); 086 mainCmdifc.writeInfo(" done.\n"); 087 getVersionFromLogOutput(data.uBzrLastVersion, data, data.revisionWorkingTreeTop); 088 File fileBzrVersion = new File(data.dirWorkingtree, "_bzrVersion.txt"); 089 if(fileBzrVersion.exists()){ 090 String lastLogfile = FileSystem.readFile(fileBzrVersion); 091 StringBuilder uLog = new StringBuilder(lastLogfile); 092 getVersionFromLogOutput(uLog, data, data.revisionSbox); 093 } 094 } 095 096 097 098 void captureStatusAllArchives(DataCmpn data){ 099 captureStatus(data); 100 // 101 data.uBzrLastVersion.setLength(0); 102 String sCmdheadRevision = mainData.cfg.indexCmds.get("headRevision"); 103 104 mainCmdifc.writeInfoln(sCmdheadRevision + " archive"); 105 mainData.cmdExec.setCurrentDir(data.dirArchive); 106 mainData.cmdExec.execute(sCmdheadRevision, null, data.uBzrLastVersion, data.uBzrError); 107 getVersionFromLogOutput(data.uBzrLastVersion, data, data.revisionArchive); 108 if(data.dirRemoteArchive !=null){ 109 mainCmdifc.writeInfoln(sCmdheadRevision + " remote archive"); 110 mainData.cmdExec.setCurrentDir(data.dirRemoteArchive); 111 mainData.cmdExec.execute(sCmdheadRevision, null, data.uBzrLastVersion, data.uBzrError); 112 getVersionFromLogOutput(data.uBzrLastVersion, data, data.revisionRemoteArchive); 113 } 114 115 } 116 117 118 119 120 /**Reads the status output and fills the {@link #listUnknownFiles}, 121 * {@link DataCmpn#listModifiedFiles}, {@link DataCmpn#listNewFiles}, 122 * {@link DataCmpn#listAddFiles}, {@link DataCmpn#listRemovedFiles}, 123 * 124 */ 125 void initListFiles() 126 { 127 DataCmpn data = mainData.currCmpn; 128 StringBuilder uStatus = data.uBzrStatusOutput; 129 String sLine; 130 listUnknownFiles.clear(); 131 List<DataFile> listFiles = listUnknownFiles; 132 String sType = "?"; 133 int posLine = 0, posLineEnd; 134 int pos; 135 data.listAddFiles = null; 136 data.listModifiedFiles = null; 137 data.listNewFiles = null; 138 data.listRemovedFiles = null; 139 data.listRenamedFiles = null; 140 data.indexFiles.clear(); 141 142 while( (posLineEnd = uStatus.indexOf("\n", posLine))>=0){ 143 sLine = uStatus.substring(posLine, posLineEnd); 144 if( (pos = sLine.indexOf("modified:"))>=0){ 145 listFiles = data.listModifiedFiles = new LinkedList<DataFile>(); 146 sType = "chg"; 147 } else if( (pos = sLine.indexOf("unknown:"))>=0){ 148 listFiles = data.listNewFiles = new LinkedList<DataFile>(); 149 sType = "new"; 150 } else if( (pos = sLine.indexOf("removed:"))>=0){ 151 listFiles = data.listRemovedFiles = new LinkedList<DataFile>(); 152 sType = "del"; 153 } else if( (pos = sLine.indexOf("added:"))>=0){ 154 listFiles = data.listAddFiles = new LinkedList<DataFile>(); 155 sType = "add"; 156 } else if( (pos = sLine.indexOf("renamed:"))>=0){ 157 listFiles = data.listRenamedFiles = new LinkedList<DataFile>(); 158 sType = "mov"; 159 } else { 160 //line with a file path 161 String sFilePath = sLine.trim(); 162 if(sFilePath.endsWith("*")){ 163 sFilePath = sFilePath.substring(0, sFilePath.length()-1).trim(); 164 } 165 int posSep = sFilePath.indexOf("=>"); 166 if( posSep >=0){ 167 sFilePath = sFilePath.substring(posSep+2).trim(); 168 } 169 sFilePath = sFilePath.replace('\\', '/'); 170 File file = new File(mainData.currCmpn.dirWorkingtree, sFilePath); 171 DataFile fileData = new DataFile(file, sFilePath, sType); 172 listFiles.add(fileData); 173 data.indexFiles.put(sFilePath, fileData); 174 } 175 posLine = posLineEnd +1; 176 } 177 178 } 179 180 181 182 void getVersionFromLogOutput(StringBuilder uLog, DataCmpn data, DataCmpn.Revision revision) 183 { 184 185 try{ 186 String sLine; 187 int posLine = 0, posLineEnd; 188 int pos; 189 boolean bRevnrOk = false, bRevDateOk = false; 190 while( (!bRevnrOk || !bRevDateOk) && (posLineEnd = uLog.indexOf("\n", posLine))>=0){ 191 sLine = uLog.substring(posLine, posLineEnd); 192 if( (pos = sLine.indexOf("revno:"))>=0){ 193 //line: revno: <#?revision> 194 String sRevision = sLine.substring(pos + 6).trim(); 195 //int nrRev = Integer.parseInt(sRevision); 196 revision.nr = sRevision; 197 bRevnrOk = true; 198 } else if( (pos = sLine.indexOf("timestamp:"))>=0){ 199 //line: timestamp: <timestamp> 200 String sDate = sLine.substring(pos + 15, pos+34).trim(); 201 long dateVersion = logDateFormat.parse(sDate).getTime(); 202 revision.date = dateVersion; 203 bRevDateOk = true; 204 } 205 posLine = posLineEnd +1; 206 } 207 } catch(Exception exc){ throw new RuntimeException(exc); } 208 } 209}