📜 ⬆️ ⬇️

SVN revision number in 1C 7.7 code

Good day.

I want to share a way of substitution in the code 1C 7.7 revision numbers and other values ​​from the working copy of SVN.
Implement the following is inspired by the article , the author is grateful for the inspiration.

Prehistory
A medium-sized trading network (about 150 stores), a small development team, we write on 1C 7.7, the configurations in the stores are self-written.
SVN server is used Collabnet Subversion , client TurtoiseSVN , compiler / decompiler of metadata 1C gComp . There is a 1Snoy base (we call it "carbon paper") from which we "scatter" updates and processing around the stores. Stores are updated automatically with ConfStarter .
There are several self-written Java parsers for substitution of functions (auto-logging) and formatting the code and a couple of bat's to simplify working with them and with GComp:
The directory where they live is included in the PATH, so all this stuff starts right from the 1C database catalog, which is quite convenient.

Cause
Rarely, but still there were incidents - then the wrong assembly (revision) was thrown, then from the wrong branch, the store was not updated, etc.
It was necessary to implement monitoring of the state of the stores, namely, I wanted to have reliable information about which assembly was installed in which store.
')
Idea
According to a given template, we obtain data on the working copy using TurtoiseSVN, at the output we get another file-template with the structure “Mask For Search” = “Value For Replacement” for the parser program.
The parser iterates over the template file and looks for matches in the code file. The mask for the search is the name of the function. If it is found, the next line after it (which returns the value of the function) is replaced with “Value For Replacement” from the template. After that, the file is transferred further to the compilation. Next, a data file is downloaded from the store and transferred to the office, where the information obtained is processed and consolidated.

Implementation
To obtain data on a working copy, use the " SubWCRev.exe " program from TurtoiseSVN. It takes three parameters:

The shablon.txt file has the aforementioned “Mask For Search” structure = “Value For Replacement” and the following entries:
 ### getSVNRevision= Return "$WCREV$"; getSVNURL= Return "$WCURL$"; getSVNBuildTime= Return "$WCNOW$"; 

At the output we get the same file, but instead of the keywords indicated between the $ signs, the corresponding values ​​are substituted:

Learn more about keyword substitution here.

Parser program was written in AutoIt . I called it Replacer . It takes two parameters:
The first line in the file with the settings should be ### for "protection against a fool" - so as not to confuse the order of the files. That is why this is done in the file shablon.txt
Replacer Contents:
 #include "file.au3" ;$CmdLine[0] -    . if $CmdLine[0] <2 Then MsgBox(0,"error!","Replacer have not all params!") Exit EndIf ;   Global $SettingsFilePath = $CmdLine[1] Global $WorkFilePath = $CmdLine[2] ;     if FileExists ( $SettingsFilePath) = 0 Then MsgBox(0, "Error", "Settings File is not exist!.") exit EndIf ;      if FileExists ( $WorkFilePath ) = 0 Then MsgBox(0, "Error", "Global Module File is not exist!.") exit EndIf ;   Local $Settingsfile = openFile($SettingsfilePath, 0) Local $T = FileRead($SettingsFilePath,3) if $T <> "###" Then MsgBox(0,"Error in the settings file!","Settings file not have in first line a secure code ###") Exit EndIf ;   While 1 ;    Local $line = FileReadLine($Settingsfile) ; ,   If @error = -1 Then ExitLoop ;  Local $SeparatorPos = StringInStr($line, "=") if $SeparatorPos = 0 Then ;   -   ContinueLoop EndIf ;         Local $find = getFindString($line) ;   Local $replace = getReplaceString($line) ;     ___ReplaceStringInFile($WorkFilePath,$find,$replace) WEnd FileClose($Settingsfile) ;  .        exit ;  "file.au3"    ,      . ;  ,   ,      ,       . Func ___ReplaceStringInFile($szFileName, $szSearchString, $szReplaceString, $fCaseness = 0, $fOccurance = 1) Local $iRetVal = 0 Local $nCount, $sEndsWith ; Check if file is readonly .. If StringInStr(FileGetAttrib($szFileName), "R") Then Return SetError(6, 0, -1) ;=============================================================================== ;== Read the file into an array ;=============================================================================== Local $hFile = FileOpen($szFileName, $FO_READ) If $hFile = -1 Then Return SetError(1, 0, -1) Local $s_TotFile = FileRead($hFile, FileGetSize($szFileName)) If StringRight($s_TotFile, 2) = @CRLF Then $sEndsWith = @CRLF ElseIf StringRight($s_TotFile, 1) = @CR Then $sEndsWith = @CR ElseIf StringRight($s_TotFile, 1) = @LF Then $sEndsWith = @LF Else $sEndsWith = "" EndIf Local $aFileLines = StringSplit(StringStripCR($s_TotFile), @LF) FileClose($hFile) ;=============================================================================== ;== Open the output file in write mode ;=============================================================================== Local $iEncoding = FileGetEncoding($szFileName) Local $hWriteHandle = FileOpen($szFileName, $iEncoding + $FO_OVERWRITE) If $hWriteHandle = -1 Then Return SetError(2, 0, -1) ;=============================================================================== ;== Loop through the array and search for $szSearchString ;=============================================================================== local $needReplace = 0 For $nCount = 1 To $aFileLines[0] ;        if $needReplace = 1 Then ;       $aFileLines[$nCount] = $szReplaceString ExitLoop EndIf ;     If StringInStr($aFileLines[$nCount], $szSearchString, $fCaseness) Then ;     ;$aFileLines[$nCount] = StringReplace($aFileLines[$nCount], $szSearchString, $szReplaceString, 1 - $fOccurance, $fCaseness) ;""  needReplace       .     . $needReplace = 1 $iRetVal = $iRetVal + 1 ;====================================================================== ;== If we want just the first string replaced, copy the rest of the lines ;== and stop ;====================================================================== If $fOccurance = 0 Then $iRetVal = 1 ExitLoop EndIf EndIf Next ;=============================================================================== ;== Write the lines back to original file. ;=============================================================================== For $nCount = 1 To $aFileLines[0] - 1 If FileWriteLine($hWriteHandle, $aFileLines[$nCount]) = 0 Then FileClose($hWriteHandle) Return SetError(3, 0, -1) EndIf Next ; Write the last record and ensure it ends with the same as the input file If $aFileLines[$nCount] <> "" Then FileWrite($hWriteHandle, $aFileLines[$nCount] & $sEndsWith) FileClose($hWriteHandle) Return $iRetVal EndFunc ;  Func openFile($FilePath,$mode) Local $file = FileOpen($FilePath, $mode) If $file = -1 Then MsgBox(0, "Error", "Unable to open file." $FilePath) exit Else Return $file EndIf EndFunc ; ,  ,    Func getFindString($inString) Return StringLeft($inString, StringInStr($inString, "=")-1) EndFunc ;  ,    Func getReplaceString($inString) Return StringRight($inString, StringLen($inString)- StringInStr($inString, "=")) EndFunc 

To automate all these actions, I created the bat get " getRevision.bat ", the parameter is the folder where the global module is located (this is BUILD or REPO).
Content getRevision.bat:
 REM         if not exist .\REPO ( echo FAIL: REPO folder isn't exist! pause exit /b 1 ) REM  -. if not exist "%~dp0\shablon.txt" ( echo FAIL: Shablon isn't exist! pause exit /b 2 ) REM  SubWCRev.exe,     "c:\Program Files\TortoiseSVN\bin\SubWCRev.exe" .\REPO "%~dp0\shablon.txt" .\ReplacerSettings.txt -f REM  ,       "%~dp0\Replacer.exe" ".\ReplacerSettings.txt" "%1\.1s" REM     del ".\ReplacerSettings.txt" 

The call to getRevision.bat was added to Build.bat , and since Build.bat pre-copies the sources into a separate BUILD folder and it is also indicated by the parameter for getRevision.bat, the substitution of values ​​is not reflected in the REPO folder with sources, and accordingly the changes do not fall into SVN that is very convenient for me.
At the request of colleagues, a separate bat was created - ompileSVN.bat
As you can tell by the name, it makes a substitution of the values ​​in the original source folder and starts the compilation. Its contents are:
 @echo   SVN   ... @echo off call getrevision.bat .\REPO @echo     REPO  1cv7.compile.md... "%GCOMP_PATH%\gcomp" -c -D .\REPO -F 1cv7.compile.md>.compile.log 
Compile.bat remained unchanged

So that the parser has something to look for, we insert dummy functions into the global module.
 //-------------------------------------------------  getSVNRevision()   0;  //-------------------------------------------------  getSVNURL()   0;  //-------------------------------------------------  getSVNBuildTime()   0;  //------------------------------------------------- 


Result
If you run CompileSVN.bat and see the changes in the commit, you can see the following:
(some data is changed):
 //-------------------------------------------------  getSVNRevision()  Return "5135";  //-------------------------------------------------  getSVNURL()  Return "https://:/svn/trunk";  //-------------------------------------------------  getSVNBuildTime()  Return "2013/01/22 10:35:15";  //------------------------------------------------- 

Also, a procedure was added to the global module for uploading data from the store.
Chapter 6. Unload MD_INFO
  MD_INFO()   = "";  .( () + "1CV7.MD", , , , , , );  ;  = ( "" ); .( "###MD Info" ); .( "SVN_Revision: " + getSVNRevision() ); .( "SVN_URL: " + getSVNURL() ); .( "SVN_BuildTime: " + ( getSVNBuildTime(), "/", "." ) ); .( "MD_UpdateTime: " +  ); .( "### : " ); .( ": " + ( . ) ); .( ": " + ( . ) );  .( _() + "\" + ( "MDInfo", "" ) );  ;  

Such a file is unloaded (some data has been changed):
 ### MD Info SVN_Revision: 5137 SVN_URL: https://:/svn/branches/_ SVN_BuildTime: 2013.01.21 13:45:44 MD_UpdateTime: 2013.01.22 05:02:52 ### : : _ : 24 

The file is recorded in the folder for the exchange, then transferred to the FTP server. From there, our database "carbon paper" will collect these files and the resulting data is recorded in the database.

For the convenience of collective script updating, the inno setup installer was used, it makes no sense to describe it in detail - everything is simple and there is good help.

With small manipulations, the above described can be easily adapted to any other programming language.

Thank you for attention.

Source: https://habr.com/ru/post/166769/


All Articles