From d54d2f099160af525ef533d24ed322b3b2647ec8 Mon Sep 17 00:00:00 2001 From: Rodolphe Breard Date: Mon, 9 Nov 2015 11:28:56 +0100 Subject: [PATCH 01/10] Add a badge with the license. Using such a badge allows the user to quickly identify the license. --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index faff90f..c5c8b1e 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ vim-dnsserial ============= +[![Apache License 2.0](https://img.shields.io/github/license/breard-r/vim-dnsserial.svg "Apache License 2.0")](https://www.apache.org/licenses/LICENSE-2.0.html) + Another DNS-zone serial number updater. From a4c03b38a5010a06a8f64114b56fe3b8b65276da Mon Sep 17 00:00:00 2001 From: Rodolphe Breard Date: Sat, 14 Nov 2015 19:05:12 +0100 Subject: [PATCH 02/10] Add the possibility to turn off the automatic serial update. Some users may want to explicitly update the DNS serial number. Instead of forcing them to update on each write, a new configuration option is used so they can chose turn it off. --- README.md | 6 ++++++ ftplugin/bindzone.vim | 14 ++++++++++---- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index c5c8b1e..a910146 100644 --- a/README.md +++ b/README.md @@ -17,3 +17,9 @@ I know this not the first vim plugin available to update a DNS-zone serial numbe * it lacks functionalities. It chose not to fork the original plugin but to write a new one from scratch mainly for legal purposes, but also because I did not found the code as simple as I expected. + + +Configuration +------------- + +You can turn off the automatic serial update by setting `let g:dnsserial_auto_update = 0` in your vimrc. diff --git a/ftplugin/bindzone.vim b/ftplugin/bindzone.vim index 7881921..8fb7aa6 100644 --- a/ftplugin/bindzone.vim +++ b/ftplugin/bindzone.vim @@ -13,7 +13,13 @@ " limitations under the License. -augroup dnsserial - autocmd! - autocmd BufWritePre DNSSerialUpdate -augroup END +if !exists('g:dnsserial_auto_update') + let g:dnsserial_auto_update = 1 +endif + +if g:dnsserial_auto_update + augroup dnsserial + autocmd! + autocmd BufWritePre DNSSerialUpdate + augroup END +endif From 2f1756485c73b0ab2c99f004da866ab9cb5e5550 Mon Sep 17 00:00:00 2001 From: Rodolphe Breard Date: Sat, 14 Nov 2015 19:12:03 +0100 Subject: [PATCH 03/10] Add a `Usage` section in the README. Users shouldn't have to guess neither that the plugin auto-updates the DNS serial number nor the name of the function to call to manually update it. --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index a910146..37041ba 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,12 @@ I know this not the first vim plugin available to update a DNS-zone serial numbe It chose not to fork the original plugin but to write a new one from scratch mainly for legal purposes, but also because I did not found the code as simple as I expected. +Usage +----- + +By default, each time you save a `bindzone` file, the script will look for the DNS serial number and update it. You can also update it without saving the file by invoking the `:DNSSerialUpdate` function. + + Configuration ------------- From acc6dd81e11cbfd53c564536752cafc151ef87e9 Mon Sep 17 00:00:00 2001 From: Rodolphe Breard Date: Sat, 14 Nov 2015 19:32:44 +0100 Subject: [PATCH 04/10] Add a `Patterns` section to the README. The documentation on how the DNS serial number have to be formated was missing. Even if the pattern is very common, it is important to specify it. --- README.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/README.md b/README.md index 37041ba..980d4c3 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,20 @@ Usage By default, each time you save a `bindzone` file, the script will look for the DNS serial number and update it. You can also update it without saving the file by invoking the `:DNSSerialUpdate` function. +Patterns +-------- + +In order to be detected, the DNS serial number must match the following pattern: + +* `YYYYMMDDXX ; serial` + - `YYYY` is the year (4 digits); + - `MM` is the month (2 digits); + - `DD` is the day (2 digits); + - `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 ------------- From 317389ec3133ba6169cb37ba6f2cca24d3b70520 Mon Sep 17 00:00:00 2001 From: Rodolphe Breard Date: Sun, 15 Nov 2015 00:02:46 +0100 Subject: [PATCH 05/10] 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. --- README.md | 61 +++++++++++++++++++++++++++++++++++-- autoload/dnsserial.vim | 69 ++++++++++++++++++++++++++++++------------ plugin/dnsserial.vim | 24 +++++++++++++++ 3 files changed, 133 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index 980d4c3..c1d8102 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ By default, each time you save a `bindzone` file, the script will look for the D 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` - `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; - 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 ------------- -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} + ] +} +``` diff --git a/autoload/dnsserial.vim b/autoload/dnsserial.vim index c72b448..15cca4c 100644 --- a/autoload/dnsserial.vim +++ b/autoload/dnsserial.vim @@ -12,28 +12,59 @@ " See the License for the specific language governing permissions and " limitations under the License. -function! s:IncrementSerial(old_date, old_nb) - let curr_date = strftime("%Y%m%d") - if a:old_date ==? curr_date - let curr_nb = a:old_nb + 1 - if curr_nb < 10 - let curr_nb = "0".curr_nb + +function! s:HasDateChanged(pattern, old_matchlist) + let i = 0 + for matching in a:pattern.matching + if matching.type ==? 'date' + let old_date = a:old_matchlist[i] + let new_date = strftime(matching.fmt) + if old_date !=? new_date + return 1 + endif endif - else - let curr_nb = "01" + let i += 1 + 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 - 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 function! dnsserial#DNSSerialUpdate() - let pattern = '\(\d\{8}\)\(\d\+\)\s*;\s*\cserial' - if search(pattern) == 0 - echom "No serial found." - return 0 - endif - let old_pattern = matchlist(getline('.'), pattern) - let old_serial = old_pattern[1].old_pattern[2] - let new_serial = s:IncrementSerial(old_pattern[1], old_pattern[2]) - execute "s/".old_serial."/".new_serial."/" - echom "Serial updated to ".new_serial."." + let patterns = g:dnsserial_custom_patterns + g:dnsserial_patterns + for pattern in patterns + if search(pattern.regex) != 0 + let offset = len(pattern.matching) + let old_matchlist = matchlist(getline('.'), pattern.regex)[1:offset] + let old_serial = join(old_matchlist, '') + let new_serial = s:GetNewSerial(pattern, old_matchlist) + execute "s/" . old_serial . "/" . new_serial . "/" + echom "Serial updated to " . new_serial . "." + return 0 + endif + endfor + echom "No serial found." endfunction diff --git a/plugin/dnsserial.vim b/plugin/dnsserial.vim index 0607bde..7de4233 100644 --- a/plugin/dnsserial.vim +++ b/plugin/dnsserial.vim @@ -12,4 +12,28 @@ " See the License for the specific language governing permissions and " 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() From c296d354b222212a3c604dc448f073231a6a799b Mon Sep 17 00:00:00 2001 From: Rodolphe Breard Date: Sun, 15 Nov 2015 00:06:58 +0100 Subject: [PATCH 06/10] Update the code type in the README. The sample custom patterns were defined as `json`, which doesn't renders nicely on GitHub. They are now defined as `js` which is much more readable. --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index c1d8102..d38b010 100644 --- a/README.md +++ b/README.md @@ -79,7 +79,7 @@ This is a list of every components of the serial number. Each component is defin A simple pattern matching a serial defined as an integer and followed by a comment starting by the word `serial` is: -```json +```js { 'regex': '\(\d\+\)\s*;\s*\cserial', 'matching': [ @@ -91,7 +91,7 @@ A simple pattern matching a serial defined as an integer and followed by a comme The same example, but having the serial number starting by the current date (YYYYMMDD) and the integer padded on two digits: -```json +```js { 'regex': '\(\d\{8}\)\(\d\+\)\s*;\s*\cserial', 'matching': [ From a5e7aa3dd5a81517558b66be279ab4753358b5a8 Mon Sep 17 00:00:00 2001 From: Rodolphe Breard Date: Mon, 16 Nov 2015 12:17:30 +0100 Subject: [PATCH 07/10] Add support for timestamp based serial. Some people uses the current timestamp for the DNS serial number. The current implementation detects timestamps between September 9 2001 and March 17 2030. Implementing it has reduced the date based serial detection to a range between 1900 and 2999, however it should not be a problem at all because DNS didn't existed before 1900 and, if it still exists in 3000, there is literally almost 1000 years to fix the problem. --- README.md | 9 ++++++++- plugin/dnsserial.vim | 12 ++++++++++-- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index d38b010..c575e8a 100644 --- a/README.md +++ b/README.md @@ -31,18 +31,25 @@ Patterns In order to be detected, the DNS serial number must match one the following pattern: * `YYYYMMDDXX ; serial` - - `YYYY` is the year (4 digits); + - `YYYY` is the year (4 digits, must start by either `19` or `2`); - `MM` is the month (2 digits); - `DD` is the day (2 digits); - `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. +* `SSSSSSSSSS ; serial` + - `SSSSSSSSSS` is the UNIX tiemstamp (10 digits, must start by `1`); + - the word `serial` is not case-sensitive; + - 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. +According to those patterns, only dates between 1900 and 2999 will be detected; however this should not be a problem at all. Most importantly, only timestamps between September 9 2001 and March 17 2030 will be detected. + Configuration ------------- diff --git a/plugin/dnsserial.vim b/plugin/dnsserial.vim index 7de4233..72ee66a 100644 --- a/plugin/dnsserial.vim +++ b/plugin/dnsserial.vim @@ -20,12 +20,20 @@ endif if !exists('g:dnsserial_patterns') let g:dnsserial_patterns = [ \{ - \'regex': '\(\d\{8}\)\(\d\+\)\s*;\s*\cserial', + \'regex': '\(19\d\{2}\|20\d\{2}\)\([01]\d\)\([0-3]\d\)\(\d\+\)\s*;\s*\cserial', \'matching': [ - \{'type': 'date', 'fmt': '%Y%m%d'}, + \{'type': 'date', 'fmt': '%Y'}, + \{'type': 'date', 'fmt': '%m'}, + \{'type': 'date', 'fmt': '%d'}, \{'type': 'integer', 'padding': 2, 'date_reset': 1} \] \}, + \{ + \'regex': '\(1\d\{9}\)\s*;\s*\cserial', + \'matching': [ + \{'type': 'date', 'fmt': '%s'}, + \] + \}, \{ \'regex': '\(\d\+\)\s*;\s*\cserial', \'matching': [ From a1635a13f71599633fb6e59cc049cde6664b5c0a Mon Sep 17 00:00:00 2001 From: Rodolphe Breard Date: Sun, 6 Dec 2015 21:07:58 +0100 Subject: [PATCH 08/10] Add a vim documentation. The README is not a sufficient enough source of information. It is easier for vim users to access the documentation through vim itself using the standard vim documentation. --- doc/dnsserial.txt | 147 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 147 insertions(+) create mode 100644 doc/dnsserial.txt diff --git a/doc/dnsserial.txt b/doc/dnsserial.txt new file mode 100644 index 0000000..489349c --- /dev/null +++ b/doc/dnsserial.txt @@ -0,0 +1,147 @@ +*dnsserial.txt* another DNS-zone serial number updater + + ____ _ _ ____ _ _ ~ + | _ \| \ | / ___| ___ ___ _ __(_) __ _| |~ + | | | | \| \___ \/ __|/ _ \ '__| |/ _` | |~ + | |_| | |\ |___) \__ \ __/ | | | (_| | |~ + |____/|_| \_|____/|___/\___|_| |_|\__,_|_|~ + + Another DNS-zone serial number updater. + +============================================================================== +CONTENTS *DNSserialContents* + + 1. Introduction ......... |DNSserial| + 2. Usage ................ |DNSserialUsage| + 3. Patterns ............. |DNSserialPatterns| + 4. Configuration ........ |DNSserialConfiguration| + 5. Custom patterns ...... |DNSserialCustomPatterns| + 5.1 regex ........... |DNSserialCustomPatterns-regex| + 5.2 matching ........ |DNSserialCustomPatterns-matching| + 5.3 examples ........ |DNSserialCustomPatterns-examples| + 6. License .............. |DNSserialLicense| + +============================================================================== +Section 1: Introduction *DNSserial* + +I know this not the first vim plugin available to update a DNS-zone serial +number. Here is a few reasons why I chose not to use the canonical one: + + - there is no license and therefore it is not free; + - it is unmaintained; + - it is bugged; + - it lacks functionalities. + +It chose not to fork the original plugin but to write a new one from scratch +mainly for legal purposes, but also because I did not found the code as simple +as I expected. + +============================================================================== +Section 2: Usage *DNSserialUsage* + +By default, each time you save a bindzone file, the script will look for the +DNS serial number and update it. You can also update it without saving the +file by invoking the :DNSSerialUpdate function. + +============================================================================== +Section 3: Patterns *DNSserialPatterns* + +In order to be detected, the DNS serial number must match one the following +pattern: + + - YYYYMMDDXX ; serial + * YYYY is the year (4 digits, must start by either 19 or 2); + * MM is the month (2 digits); + * DD is the day (2 digits); + * 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. + + - SSSSSSSSSS ; serial + * SSSSSSSSSS is the UNIX tiemstamp (10 digits, must start by 1); + * the word serial is not case-sensitive; + * 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. + +According to those patterns, only dates between 1900 and 2999 will be +detected; however this should not be a problem at all. Most importantly, only +timestamps between September 9 2001 and March 17 2030 will be detected. + +============================================================================== +Section 4: Configuration *DNSserialConfiguration* + +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. + +============================================================================== +Section 5: Custom patterns *DNSserialCustomPatterns* + +A pattern is defined by a dictionary with two keys: regex and matching. + +------------------------------------------------------------------------------ +Section 5.1: regex *DNSserialCustomPatterns-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. + +------------------------------------------------------------------------------ +Section 5.1: matching *DNSserialCustomPatterns-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. + +------------------------------------------------------------------------------ +Section 5.1: examples *DNSserialCustomPatterns-examples* + +A simple pattern matching a serial defined as an integer and followed by a +comment starting by the word serial is: + + { + '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: + + { + 'regex': '\(\d\{8}\)\(\d\+\)\s*;\s*\cserial', + 'matching': [ + {'type': 'date', 'fmt': '%Y%m%d'}, + {'type': 'integer', 'padding': 2, 'date_reset': 1} + ] + } + +============================================================================== +Section 6: License *DNSserialLicense* + +DNSserial is Copyright 2015 Rodolphe Breard and is licensed under the Apache +License, Version 2.0. From 7aa04b98934a7e60c0eb47c5f94a6ae111b7fee3 Mon Sep 17 00:00:00 2001 From: Rodolphe Breard Date: Tue, 3 Sep 2019 11:07:13 +0200 Subject: [PATCH 09/10] Add a "Status" section to the README --- README.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/README.md b/README.md index c575e8a..4e8c5a9 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,18 @@ I know this not the first vim plugin available to update a DNS-zone serial numbe It chose not to fork the original plugin but to write a new one from scratch mainly for legal purposes, but also because I did not found the code as simple as I expected. +Status +------ + +This project is passively maintained. If there is no recent commits it is because: + +- I did not encountered a bug and nobody reported any. +- I am happy with the functionalities and nobody asked for new ones. +- It works on both vim and neovim. + +If you need anything, please open an issue. + + Usage ----- From 8e612140171bbb53785f37f38d24ca028f3f521a Mon Sep 17 00:00:00 2001 From: Rodolphe Breard Date: Wed, 4 Sep 2019 17:45:19 +0200 Subject: [PATCH 10/10] Fix a typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4e8c5a9..4eecf68 100644 --- a/README.md +++ b/README.md @@ -51,7 +51,7 @@ In order to be detected, the DNS serial number must match one the following patt - there can be any number of blanks on each sides of the semicolon. * `SSSSSSSSSS ; serial` - - `SSSSSSSSSS` is the UNIX tiemstamp (10 digits, must start by `1`); + - `SSSSSSSSSS` is the UNIX timestamp (10 digits, must start by `1`); - the word `serial` is not case-sensitive; - there can be any number of blanks on each sides of the semicolon.