--- title: "semver: Basics" author: "John D Harrison" date: "`r Sys.Date()`" output: rmarkdown::html_vignette: toc: true toc_depth: 3 vignette: > %\VignetteIndexEntry{semver: Basics} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- The goal of this vignette is to describe the basic functionality of the `semver` package. ## Introduction The `semver` package provides tools and functions for parsing, rendering and operating on semantic version strings. Semantic versioning is a simple set of rules and requirements that dictate how version numbers are assigned and incremented as outlined at [http://semver.org](http://semver.org). A basic summary of how semantic versioning operates is given a version number MAJOR.MINOR.PATCH, increment the: 1. MAJOR version when you make incompatible API changes, 2. MINOR version when you add functionality in a backwards-compatible manner, and 3. PATCH version when you make backwards-compatible bug fixes. Additional labels for pre-release and build metadata are available as extensions to the MAJOR.MINOR.PATCH format. ## `semver` package The `semver` package provides a wrapper for the C++14 semantic versioning parser written by Marko Živanović. The project is currently hosted on [github](https://github.com/zmarko/semver). The [Rcpp package](https://github.com/RcppCore/Rcpp) was used to provide R bindings. Some changes were made on the C++ side as currently CRAN does not accept packages compiling under C++14 (R version 3.4.0 should allow this in future). ### Parsing/Rendering semantic versions #### parse_version The `parse_version` function parses a character vector containing valid semantic versioning strings returning an "svlist" object. ```{r example1} library(semver) examples <- c("1.0.0", "2.1.3", "1.0.0-alpha", "1.0.0-alpha+1.2", "1.8.2-beta.1.13", "1.8.2-beta.1.10") sem_versions <- parse_version(examples) sem_versions str(sem_versions) ``` #### render_version The `render_version` function acts on an "svptr"/"svlist" object. It returns an R list/(list of lists) giving the major, minor and patch version as an integer and the prerelease and build version as a charcter ```{r example1a} render_version(sem_versions[c(1, 4)]) render_version(sem_versions[[5]]) str(render_version(sem_versions[[5]])) ``` ### Comparing versions The `parse_version` function returns a list of `svptr` objects. These `svptr` objects represent the semantic versions. We can do comparisons like: #### svptr Ops ```{r example2} sem_versions[[1]] <= sem_versions[[5]] sem_versions[[1]] > sem_versions[[5]] # compare example 5, 6 (pre-release ordering matters) sem_versions[[5]] > sem_versions[[6]] # compare example 3, 4 (build order does not matter) sem_versions[[3]] == sem_versions[[4]] ``` #### Summary of svlist objects You can get the min, max and range of the versions ```{r example3} min(sem_versions) max(sem_versions) range(sem_versions) ``` #### Sort, Order and rank an svlist You can sort, order and rank the versions: ```{r example4} sort(sem_versions) order(sem_versions) rank(sem_versions) ``` #### Ops on svlist You can also compare "svlist" objects. If the lengths of the two lists are unequal recycling occurs: ```{r example4a} sem_versions > sem_versions[1] ``` ### Compare to character strings Sometimes it can be useful to compare a parsed vector of semantic versions to a character string: ```{r example5} sem_versions > "1.1.0-beta" sem_versions[sem_versions > "1.1.0-beta"] ``` ## Updating versions If you want to change or ammend the major, minor, patch, prerelease or build fields the semver package provides a number of methods to achieve this. ### set_version The `set_version` method operates on `svptr` and `svlist` classes. It simply changes the indicated field to the value given. Other fields in the version are unaffected. #### svptr For the `svptr` class the `set_version` method takes a character string argument `field` which indicates which field (major, minor etc.) to change. The `value` argument is an integer scalar when field is major, minor or patch and a character string when prerelease or build. ```{r example6} library(semver) examples <- c("1.0.0", "2.1.3", "1.0.0-alpha", "1.0.0-alpha+1.2", "1.8.2-beta.1.13", "1.8.2-beta.1.10") sem_versions <- parse_version(examples) set_version(sem_versions[[1]], "major", 2L) set_version(sem_versions[[1]], "minor", 1L) set_version(sem_versions[[1]], "patch", 1L) set_version(sem_versions[[4]], "prerelease", "beta") set_version(sem_versions[[4]], "build", "bld1a") ``` **Note that changing a field with the set_version method does not change any other field.** ##### Dollar assignment As syntactic sugar for assigning using `set_version` there is a dollar assignment method for svptr classes so the following are equivalent waysto assign fields: ```{r example7} sem_versions[[1]] <- set_version(sem_versions[[1]], "major", 3L) sem_versions[[1]] # Syntactic sugar sem_versions[[1]]$minor <- 2L sem_versions[[1]] ``` #### svlist For `svlist` classes the `set_version` method expects a character vector for the `field` argument. The `value` argument is expected to be a list with integer and character elements assigning to (major, minor, patch)/(prerelease, build) fields respectively. If either the length of the field or values argeument is shorter than the number of elements in the `svlist` then recycling occurs. ```{r example8} examples <- c("1.0.0", "1.8.2-beta.1.10", "2.4.6-8") sem_versions <- parse_version(examples) # recycling on the field argument set_version(sem_versions, "major", list(2L, 4L, 6L)) # recycling on the value argument set_version(sem_versions, c("major", "minor", "patch"), list(7L)) # assigning integer and character values set_version(sem_versions, c("prerelease", "minor", "build"), list("alpha", 3L, "build1.12")) ``` ### reset_version The `reset_version` method operates on `svptr` and `svlist` classes. It changes the indicated field to the value given. Fields with lower precedence are set to default values: ``` MAJOR(0L) > MINOR (0L) > PATCH (0L) > PRERELEASE ("") > BUILD ("") ``` #### svptr The `reset_version` method for `svptr` classes operates similarly to the `set_version` method with fields of lower precedence being set to default values: ```{r example9} examples <- c("1.8.2-beta.1.10+somebuild", "2.4.6-8") sem_versions <- parse_version(examples) reset_version(sem_versions[[1]], "major", 2L) reset_version(sem_versions[[1]], "minor", 3L) reset_version(sem_versions[[1]], "patch", 4L) reset_version(sem_versions[[1]], "prerelease", "gamma") reset_version(sem_versions[[1]], "build", "superbuild") ``` #### svlist The `reset_version` method for `svlist` classes operates similarly to the `set_version` method with fields of lower precedence being set to default values. Again recycling of elements occur if the length of the field/value argument is shorter than the number of elements in the `svlist`: ```{r example10} examples <- c("1.8.2-beta.1.10+somebuild", "2.4.6-8") sem_versions <- parse_version(examples) # recycling on both arguments reset_version(sem_versions, "major", list(3L)) # recycling on field argument reset_version(sem_versions, "minor", list(3L, 4L)) # recycling on value argument reset_version(sem_versions, c("major", "patch"), list(4L)) # assigning integer and character fields reset_version(sem_versions, c("prerelease", "minor"), list("zeta", 7L)) ``` ### increment_version The `increment_version` method operates on `svptr` and `svlist` classes. It increments the given field with the provided value. Fields of lower precedence are set to default value. 1. **Only major, minor and patch field can be incremented** 2. **To decrement a field provide a negative integer as the value argument** #### svptr The `increment_version` method for `svptr` classes increments the chosen field with the given value with fields of lower precedence being set to default values: ```{r example11} examples <- c("1.8.2-beta.1.10+somebuild", "2.4.6-8") sem_versions <- parse_version(examples) # incrementing versions increment_version(sem_versions[[1]], "major", 1L) increment_version(sem_versions[[1]], "minor", 2L) increment_version(sem_versions[[1]], "patch", 3L) # decrementing versions increment_version(sem_versions[[1]], "major", -1L) increment_version(sem_versions[[1]], "minor", -2L) increment_version(sem_versions[[1]], "patch", -2L) ``` #### svlist The `increment_version` method for `svlist` classes takes a character vector as argument `field` and an integer vector as argument `value`. Recycling occurs as for `set_version`/`reset_version` methods: ```{r example12} examples <- c("1.8.2-beta.1.10+somebuild", "2.4.6-8") sem_versions <- parse_version(examples) ## Incrementing # recycling on both arguments increment_version(sem_versions, "major", 3L) # recycling on field argument increment_version(sem_versions, "minor", c(3L, 4L)) # recycling on value argument increment_version(sem_versions, c("major", "patch"), 4L) ## Decrementing # recycling on both arguments increment_version(sem_versions, "major", -1L) # recycling on field argument increment_version(sem_versions, "minor", c(-3L, -4L)) # recycling on value argument increment_version(sem_versions, c("minor"), -4L) ```