Add the support for multiple formats.
Some people does not use the common YYYYMMDDXX format and/or does not want to use the "; serial" comment right after the serial number. This commit allow multiple formats to be defined, hense more users can use the plugin. A huge consequence of this is that user can also define additional custom formats depending on their needs.
This commit is contained in:
parent
acc6dd81e1
commit
317389ec31
3 changed files with 133 additions and 21 deletions
61
README.md
61
README.md
|
@ -28,7 +28,7 @@ By default, each time you save a `bindzone` file, the script will look for the D
|
||||||
Patterns
|
Patterns
|
||||||
--------
|
--------
|
||||||
|
|
||||||
In order to be detected, the DNS serial number must match the following pattern:
|
In order to be detected, the DNS serial number must match one the following pattern:
|
||||||
|
|
||||||
* `YYYYMMDDXX ; serial`
|
* `YYYYMMDDXX ; serial`
|
||||||
- `YYYY` is the year (4 digits);
|
- `YYYY` is the year (4 digits);
|
||||||
|
@ -38,8 +38,65 @@ In order to be detected, the DNS serial number must match the following pattern:
|
||||||
- the word `serial` is not case-sensitive;
|
- the word `serial` is not case-sensitive;
|
||||||
- there can be any number of blanks on each sides of the semicolon.
|
- there can be any number of blanks on each sides of the semicolon.
|
||||||
|
|
||||||
|
* `XX ; serial`
|
||||||
|
- `XX` is any non-negative number (1 or more digits);
|
||||||
|
- the word `serial` is not case-sensitive;
|
||||||
|
- there can be any number of blanks on each sides of the semicolon.
|
||||||
|
|
||||||
|
|
||||||
Configuration
|
Configuration
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
You can turn off the automatic serial update by setting `let g:dnsserial_auto_update = 0` in your vimrc.
|
You can set several configuration variables in your vimrc:
|
||||||
|
|
||||||
|
* `g:dnsserial_auto_update`: Defines whether or not the serial is updated when the zone file is saved (default is 1, set it to 0 to disable).
|
||||||
|
* `g:dnsserial_custom_patterns`: List of customs patterns that will be added to the default ones. Order matters, the first matching patters will be used. Customs patterns will be tested before the default ones.
|
||||||
|
* `g:dnsserial_patterns`: List of default patterns. It is not advised to change it.
|
||||||
|
|
||||||
|
|
||||||
|
Custom patterns
|
||||||
|
---------------
|
||||||
|
|
||||||
|
A pattern is defined by a dictionary with two keys: `regex` and `matching`.
|
||||||
|
|
||||||
|
**regex**
|
||||||
|
|
||||||
|
Contains the regular expression that will be used to search the document for the serial number. All the components of the serial number must be captured with parenthesis.
|
||||||
|
|
||||||
|
**matching**
|
||||||
|
|
||||||
|
This is a list of every components of the serial number. Each component is defined by a dictionary. The `type` key must be present and contain one of the allowed types. Depending on the type, several additional keys might be defined. Authorized types and their options are:
|
||||||
|
|
||||||
|
* `raw`: Raw string.
|
||||||
|
* `integer`: An integer that will be incremented.
|
||||||
|
- `offset` (int): set the offset by which the integer is incremented. Default is 1.
|
||||||
|
- `padding` (int): Force the integer to be 0-padded on the associated number of digits.
|
||||||
|
- `date_reset` (bool): If set to 1 and a the serial contains a `date`, the integer will be reseted to 0 if the date is updated. Default is 0.
|
||||||
|
* `date`: A formated date that will be updated to the current one.
|
||||||
|
- `fmt` (string, mandatory) : the date format according to the `strftime()` specifications. See `:help strftime` for more details.
|
||||||
|
|
||||||
|
**examples**
|
||||||
|
|
||||||
|
A simple pattern matching a serial defined as an integer and followed by a comment starting by the word `serial` is:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
'regex': '\(\d\+\)\s*;\s*\cserial',
|
||||||
|
'matching': [
|
||||||
|
{'type': 'integer'}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The same example, but having the serial number starting by the current date (YYYYMMDD) and the integer padded on two digits:
|
||||||
|
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
'regex': '\(\d\{8}\)\(\d\+\)\s*;\s*\cserial',
|
||||||
|
'matching': [
|
||||||
|
{'type': 'date', 'fmt': '%Y%m%d'},
|
||||||
|
{'type': 'integer', 'padding': 2, 'date_reset': 1}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
|
@ -12,28 +12,59 @@
|
||||||
" See the License for the specific language governing permissions and
|
" See the License for the specific language governing permissions and
|
||||||
" limitations under the License.
|
" limitations under the License.
|
||||||
|
|
||||||
function! s:IncrementSerial(old_date, old_nb)
|
|
||||||
let curr_date = strftime("%Y%m%d")
|
function! s:HasDateChanged(pattern, old_matchlist)
|
||||||
if a:old_date ==? curr_date
|
let i = 0
|
||||||
let curr_nb = a:old_nb + 1
|
for matching in a:pattern.matching
|
||||||
if curr_nb < 10
|
if matching.type ==? 'date'
|
||||||
let curr_nb = "0".curr_nb
|
let old_date = a:old_matchlist[i]
|
||||||
|
let new_date = strftime(matching.fmt)
|
||||||
|
if old_date !=? new_date
|
||||||
|
return 1
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
else
|
let i += 1
|
||||||
let curr_nb = "01"
|
endfor
|
||||||
|
return 0
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:GetNewValue(matching, old_value, date_changed)
|
||||||
|
if a:matching.type ==? 'date'
|
||||||
|
return strftime(a:matching.fmt)
|
||||||
|
elseif a:matching.type ==? 'integer'
|
||||||
|
let nb = a:old_value + get(a:matching, 'offset', 1)
|
||||||
|
if a:date_changed && get(a:matching, 'date_reset', 0)
|
||||||
|
let nb = 0
|
||||||
|
endif
|
||||||
|
return printf('%0' . get(a:matching, 'padding', 1) . 'd', nb)
|
||||||
endif
|
endif
|
||||||
return curr_date.curr_nb
|
return a:old_value
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:GetNewSerial(pattern, old_matchlist)
|
||||||
|
let date_changed = s:HasDateChanged(a:pattern, a:old_matchlist)
|
||||||
|
let new_serial = []
|
||||||
|
let i = 0
|
||||||
|
for matching in a:pattern.matching
|
||||||
|
let new_value = s:GetNewValue(matching, a:old_matchlist[i], date_changed)
|
||||||
|
call add(new_serial, new_value)
|
||||||
|
let i += 1
|
||||||
|
endfor
|
||||||
|
return join(new_serial, '')
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! dnsserial#DNSSerialUpdate()
|
function! dnsserial#DNSSerialUpdate()
|
||||||
let pattern = '\(\d\{8}\)\(\d\+\)\s*;\s*\cserial'
|
let patterns = g:dnsserial_custom_patterns + g:dnsserial_patterns
|
||||||
if search(pattern) == 0
|
for pattern in patterns
|
||||||
echom "No serial found."
|
if search(pattern.regex) != 0
|
||||||
return 0
|
let offset = len(pattern.matching)
|
||||||
endif
|
let old_matchlist = matchlist(getline('.'), pattern.regex)[1:offset]
|
||||||
let old_pattern = matchlist(getline('.'), pattern)
|
let old_serial = join(old_matchlist, '')
|
||||||
let old_serial = old_pattern[1].old_pattern[2]
|
let new_serial = s:GetNewSerial(pattern, old_matchlist)
|
||||||
let new_serial = s:IncrementSerial(old_pattern[1], old_pattern[2])
|
execute "s/" . old_serial . "/" . new_serial . "/"
|
||||||
execute "s/".old_serial."/".new_serial."/"
|
echom "Serial updated to " . new_serial . "."
|
||||||
echom "Serial updated to ".new_serial."."
|
return 0
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
echom "No serial found."
|
||||||
endfunction
|
endfunction
|
||||||
|
|
|
@ -12,4 +12,28 @@
|
||||||
" See the License for the specific language governing permissions and
|
" See the License for the specific language governing permissions and
|
||||||
" limitations under the License.
|
" limitations under the License.
|
||||||
|
|
||||||
|
|
||||||
|
if !exists('g:dnsserial_custom_patterns')
|
||||||
|
let g:dnsserial_custom_patterns = []
|
||||||
|
endif
|
||||||
|
|
||||||
|
if !exists('g:dnsserial_patterns')
|
||||||
|
let g:dnsserial_patterns = [
|
||||||
|
\{
|
||||||
|
\'regex': '\(\d\{8}\)\(\d\+\)\s*;\s*\cserial',
|
||||||
|
\'matching': [
|
||||||
|
\{'type': 'date', 'fmt': '%Y%m%d'},
|
||||||
|
\{'type': 'integer', 'padding': 2, 'date_reset': 1}
|
||||||
|
\]
|
||||||
|
\},
|
||||||
|
\{
|
||||||
|
\'regex': '\(\d\+\)\s*;\s*\cserial',
|
||||||
|
\'matching': [
|
||||||
|
\{'type': 'integer'}
|
||||||
|
\]
|
||||||
|
\},
|
||||||
|
\]
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
command! DNSSerialUpdate call dnsserial#DNSSerialUpdate()
|
command! DNSSerialUpdate call dnsserial#DNSSerialUpdate()
|
||||||
|
|
Reference in a new issue