quanteda / spacyr
1
# copied and modified from tensorflow::install.R, https://github.com/rstudio/tensorflow/blob/master/R/install.R
2

3
#' Install spaCy in conda or virtualenv environment
4
#'
5
#' @description Install spaCy in a self-contained environment, including
6
#'   specified language models.  For macOS and Linux-based systems, this will
7
#'   also install Python itself via a "miniconda" environment, for
8
#'   \code{spacy_install}.  Alternatively, an existing conda installation may be
9
#'   used, by specifying its path.  The default setting of \code{"auto"} will
10
#'   locate and use an existing installation automatically, or download and
11
#'   install one if none exists.  
12
#'   
13
#'   For Windows, automatic installation of miniconda installation is not currently
14
#'   available, so the user will need to \href{https://conda.io/projects/conda/en/latest/user-guide/install/index.html}{miniconda (or Anaconda) manually}.
15
#'
16
#' @section spaCy Version Issues:
17
#' 
18
#'   The version options currently default to the latest spaCy v2 (\code{version
19
#'   = "latest"}). As of 2018-04, however,
20
#'   \href{https://github.com/explosion/spaCy/issues/1508}{some performance
21
#'   issues} affect the speed of the spaCy pipeline for spaCy v2.x relative to
22
#'   v1.x.   This can  enormously affect the performance of
23
#'   \code{spacy_parse()}, especially when a large number of small texts are
24
#'   parsed. For this reason, the \pkg{spacyr} provides an option to
25
#'   automatically install the latest version of spaCy v1.*, using \code{version
26
#'   = "latest_v1"}.
27
#'   
28
#' @param conda character; path to conda executable. Default "auto" which
29
#'   automatically find the path
30
#' @param pip \code{TRUE} to use pip for installing spacy. If \code{FALSE}, conda 
31
#' package manager with conda-forge channel will be used for installing spacy.
32
#' @param lang_models character; language models to be installed. Default
33
#'   \code{en_core_web_sm} (English model). A vector of multiple model names can be used
34
#'   (e.g. \code{c("en_core_web_sm", "de_core_news_sm")}).  A list of available language models and their
35
#'   names is available from the \href{https://spacy.io/usage/models}{spaCy
36
#'   language models} page.
37
#' @param version character; spaCy version to install. Specify \code{"latest"}
38
#'   to install the latest release, or \code{"latest_v1"} to install the latest 
39
#'   release of spaCy v1.*.  See spaCy Version Issues.
40
#'
41
#'   You can also provide a full major.minor.patch specification (e.g. "1.1.0")
42
#' @param python_version character; determine Python version for condaenv
43
#'   installation. 3.5 and 3.6 are available.
44
#' @param python_path character; path to Python in virtualenv installation
45
#' @param envname character; name of the conda-environment to install spaCy. 
46
#'   Default is "spacy_condaenv".
47
#' @param prompt logical; ask whether to proceed during the installation
48
#' @examples 
49
#' \dontrun{
50
#' # install spaCy in a miniconda environment (macOS and Linux)
51
#' spacy_install(lang_models = c("en_core_web_sm", "de_core_news_sm"), prompt = FALSE)
52
#' 
53
#' # install spaCy to an existing conda environment
54
#' spacy_install(conda = "~/anaconda/bin/")
55
#' }
56
#' 
57
#' @export
58
spacy_install <- function(conda = "auto",
59
                          version = "latest",
60
                          lang_models = "en_core_web_sm",
61
                          python_version = "3.6",
62
                          envname = "spacy_condaenv",
63
                          pip = FALSE,
64
                          python_path = NULL,
65
                          prompt = TRUE) {
66
    # verify os
67 2
    if (!is_windows() && !is_osx() && !is_linux()) {
68 0
        stop("This function is available only for Windows, Mac, and Linux")
69
    }
70

71
    # model name check
72 2
    if (any(lang_models %in% c('en', 'de', 'es', 'pt', 'fr', 'it', 'nl', 'el', 'nb', 'lt') == TRUE)) {
73 0
        model <-
74 0
            lang_models[lang_models %in%
75 0
                            c('en', 'de', 'es', 'pt', 'fr', 'it', 'nl', 'el', 'nb', 'lt') == TRUE][1]
76 0
        stop('An abbreviation of the model name, "', model, '", is provided.\n',
77 0
             '  Please use a full model name (e.g. "', model, '_core_', ifelse(model == 'en', 'web', 'news'),'_sm").\n')
78
    }
79

80
    # verify 64-bit
81
    # if (.Machine$sizeof.pointer != 8) {
82
    #     stop("Unable to install TensorFlow on this platform.",
83
    #          "Binary installation is only available for 64-bit platforms.")
84
    # }
85
    #
86

87 2
    if (!(identical(version, "latest") || identical(version, "latest_v1"))) {
88 2
        if (!(grepl("^[1-9]\\.\\d{1,2}\\.\\d{1,2}\\b", version))){
89 2
            stop("spacy version specification error\n",
90 2
                 "Please provide a full major.minor.patch specification",
91 2
                 call. = FALSE)
92
        }
93
    }
94

95
    # resolve and look for conda
96 2
    conda <- tryCatch(reticulate::conda_binary(conda), error = function(e) NULL)
97 2
    have_conda <- !is.null(conda)
98

99
    # mac and linux
100 2
    if (is_unix()) {
101

102
        # check for explicit conda method
103

104
            # validate that we have conda
105 2
            if (!have_conda) {
106 0
                cat("No conda was found in the system. ")
107 0
                ans <- utils::menu(c("No", "Yes"), title = "Do you want spacyr to download miniconda in ~/miniconda?")
108 0
                if (ans == 2) {
109 0
                  install_miniconda()
110 0
                  conda <- tryCatch(reticulate::conda_binary("auto"), error = function(e) NULL)
111 0
                } else stop("Conda environment installation failed (no conda binary found)\n", call. = FALSE)
112
            }
113

114
            # process the installation of spacy
115 2
            process_spacy_installation_conda(conda, version, lang_models,
116 2
                                             python_version, prompt,
117 2
                                             envname = envname, pip = pip)
118

119
    # windows installation
120
    } else {
121

122
        # determine whether we have system python
123 0
        python_versions <- reticulate::py_versions_windows()
124 0
        python_versions <- python_versions[python_versions$type == "PythonCore", ]
125 0
        python_versions <- python_versions[python_versions$version %in% c("3.5", "3.6"), ]
126 0
        python_versions <- python_versions[python_versions$arch == "x64", ]
127 0
        have_system <- nrow(python_versions) > 0
128 0
        if (have_system)
129 0
            python_system_version <- python_versions[1, ]
130

131
        # validate that we have conda
132 0
        if (!have_conda) {
133 0
            stop("Conda installation failed (no conda binary found)\n\n",
134 0
                 "Install Anaconda 3.x for Windows (https://www.anaconda.com/download/#windows)\n",
135 0
                 "before installing spaCy",
136 0
                 call. = FALSE)
137
        }
138

139
        # process the installation of spacy
140 0
        process_spacy_installation_conda(conda, version, lang_models,
141 0
                                         python_version, prompt,
142 0
                                         envname = envname, pip = pip)
143

144
    }
145 2
    message("\nInstallation complete.\n",
146 2
            sprintf("Condaenv: %s; Language model(s): ", envname), lang_models, "\n")
147

148 2
    invisible(NULL)
149
}
150

151
#' @rdname spacy_install
152
#' @description If you wish to install Python ion a "virtualenv", use the
153
#'   \code{spacy_install_virtualenv} function.
154
#' @examples
155
#' \dontrun{
156
#' # install spaCy in a virtualenv environment
157
#' spacy_install_virtualenv(lang_models = c("en_core_web_sm"))
158
#' }
159
#' @export
160
spacy_install_virtualenv <- function(version = "latest",
161
                                     lang_models = "en_core_web_sm",
162
                                     python_version = "3.6",
163
                                     python_path = NULL,
164
                                     prompt = TRUE) {
165
    # verify os
166 0
    if (!is_osx() && !is_linux()) {
167 0
        stop("This function is available only for Mac and Linux", call. = FALSE)
168
    }
169

170 0
    if (!(identical(version, "latest") || identical(version, "latest_v1"))) {
171 0
        if (!(grepl("(\\d+\\.){1,2}(\\d+)?", version))){
172 0
            stop("spaCy version specification error\n",
173 0
                 "Please provide a full major.minor.patch specification",
174 0
                 call. = FALSE)
175
        }
176
    }
177

178
    # mac and linux
179

180
    # check for explicit conda method
181

182
    # find system python binary
183 0
    python <- if (!is.null(python_path)) python_path else python_unix_binary("python")
184 0
    if (is.null(python))
185 0
        stop("Unable to locate Python on this system.", call. = FALSE)
186

187
    # find other required tools
188 0
    pip <- python_unix_binary("pip")
189 0
    have_pip <- !is.null(pip)
190 0
    virtualenv <- python_unix_binary("virtualenv")
191 0
    have_virtualenv <- !is.null(virtualenv)
192

193
    # stop if either pip or virtualenv is not available
194 0
    if (!have_pip || !have_virtualenv) {
195 0
        install_commands <- NULL
196 0
        if (is_osx()) {
197 0
            if (!have_pip)
198 0
                install_commands <- c(install_commands, "$ sudo /usr/bin/easy_install pip")
199 0
            if (!have_virtualenv) {
200 0
                if (is.null(pip))
201 0
                    pip <- "/usr/local/bin/pip"
202 0
                install_commands <- c(install_commands, sprintf("$ sudo %s install --upgrade virtualenv", pip))
203
            }
204 0
            if (!is.null(install_commands))
205 0
                install_commands <- paste(install_commands, collapse = "\n")
206 0
        } else if (is_ubuntu()) {
207 0
            if (!have_pip)
208 0
                install_commands <- c(install_commands, "python-pip")
209 0
            if (!have_virtualenv)
210 0
                install_commands <- c(install_commands, "python-virtualenv")
211 0
            if (!is.null(install_commands)) {
212 0
                install_commands <- paste("$ sudo apt-get install",
213 0
                                          paste(install_commands, collapse = " "))
214
            }
215
        } else {
216 0
            if (!have_pip)
217 0
                install_commands <- c(install_commands, "pip")
218 0
            if (!have_virtualenv)
219 0
                install_commands <- c(install_commands, "virtualenv")
220 0
            if (!is.null(install_commands)) {
221 0
                install_commands <- paste("Please install the following Python packages before proceeding:",
222 0
                                          paste(install_commands, collapse = ", "))
223
            }
224
        }
225 0
        if (!is.null(install_commands)) {
226

227
            # if these are terminal commands then add special preface
228 0
            if (grepl("^\\$ ", install_commands)) {
229 0
                install_commands <- paste0(
230 0
                    "Execute the following at a terminal to install the prerequisites:\n",
231 0
                    install_commands
232
                )
233
            }
234

235 0
            stop("Prerequisites for installing spaCy not available.\n\n",
236 0
                 install_commands, "\n\n", call. = FALSE)
237
        }
238
    }
239 0
    process_spacy_installation_virtualenv(python, virtualenv, version, lang_models, prompt)
240

241 0
    cat("\nInstallation complete.\n\n")
242

243 0
    invisible(NULL)
244
}
245

246
process_spacy_installation_conda <- function(conda, version, lang_models, python_version,
247
                                             prompt = TRUE,
248
                                             envname = "spacy_condaenv",
249
                                             pip = FALSE) {
250

251 2
    conda_envs <- reticulate::conda_list(conda = conda)
252 2
    if (prompt) {
253 0
        ans <- utils::menu(c("No", "Yes"), title = "Proceed?")
254 0
        if (ans == 1) stop("condaenv setup is cancelled by user", call. = FALSE)
255
    }
256 2
    conda_env <- subset(conda_envs, conda_envs$name == envname)
257 2
    if (nrow(conda_env) == 1) {
258 2
        cat("Using existing conda environment ", envname, " for spaCy installation\n.",
259 2
            "\nspaCy and language model(s):",
260 2
            paste(lang_models, collapse = ", "), "will be installed.  ")
261 2
        python <- conda_env$python
262
    }
263
    else {
264 2
        cat("A new conda environment", paste0('"', envname, '"'), "will be created and \nspaCy and language model(s):",
265 2
            paste(lang_models, collapse = ", "), "will be installed.  ")
266 2
        cat("Creating", envname, "conda environment for spaCy installation...\n")
267 2
        python_packages <- ifelse(is.null(python_version), "python=3.6",
268 2
                                  sprintf("python=%s", python_version))
269 2
        python <- reticulate::conda_create(envname, packages = python_packages, conda = conda)
270
    }
271

272
    # Short circuit to install everything with conda when no custom packages
273
    # (typically tf-nightly or a daily build URL) and no gpu-enabled build
274
    # is requested (conda doesn't currently have GPU enabled builds.
275
    #
276
    # This avoids any use of pip, which addresses the following issue:
277
    # https://github.com/rstudio/keras/issues/147
278
    #
279
    # This issue is in turn created by two other issues:
280
    #
281
    # 1) TensorBoard appears to rely on an older version of html5lib which is
282
    #    force installed, and which as a result breaks pip:
283
    #    https://github.com/tensorflow/tensorboard/issues/588
284
    #
285
    # 2) Anaconda 5.0.0 is unable to recover from this because the installation
286
    #    of the old version of html5lib actually propagates to the root
287
    #    environment, which permantely breaks pip for *all* conda environments:
288
    #    https://github.com/conda/conda/issues/6079
289
    #
290
    # Hopefully these two issues will be addressed and we can return to using
291
    # pip in all scenarios (as that is the officially supported version)
292
    #
293
    # if (is_windows() && is.null(packages)) {
294
    #     conda_forge_install(
295
    #         envname,
296
    #         spacy_pkgs(version),
297
    #         conda = conda
298
    #     )
299
    #     return(invisible(NULL))
300
    # }
301
    #
302

303
    # this function generates a forced pip error to get a version spaCy highest within a major version
304
    # e.g. if major_version == 1, it will return 1.10.1
305 2
    pip_get_version_conda <- function(major_version) {
306 0
        condaenv_bin <- function(bin) path.expand(file.path(dirname(conda), bin))
307 0
        cmd <- sprintf("%s%s %s && pip install --upgrade %s %s%s",
308 0
                       ifelse(is_windows(), "", ifelse(is_osx(), "source ", "/bin/bash -c \"source ")),
309 0
                       shQuote(path.expand(condaenv_bin("activate"))),
310 0
                       envname,
311 0
                       "--ignore-installed",
312 0
                       paste(shQuote("spacy==random"), collapse = " "),
313 0
                       ifelse(is_windows(), "", ifelse(is_osx(), "", "\"")))
314 0
        pip_get_version(cmd = cmd, major_version = major_version)
315
    }
316
    # install base spaCy using pip
317 2
    if (version == "latest_v1") {
318 0
        version <- ifelse(pip, pip_get_version_conda(1),
319 0
                          conda_get_version(1, conda, envname))
320 0
        cat("Option \"version = version_v1\" is supplied, spaCy", version, "will be installed\n")
321
    }
322 2
    cat("Installing spaCy...\n")
323 2
    packages <- spacy_pkgs(version)
324 2
    reticulate::conda_install(envname, packages, pip = pip, conda = conda)
325

326 2
    for (model in lang_models) spacy_download_langmodel(model = model, conda = conda,
327 2
                                                        envname = envname)
328

329
}
330

331
process_spacy_installation_virtualenv <- function(python, virtualenv, version, lang_models, prompt = TRUE) {
332

333
    # determine python version to use
334 0
    is_python3 <- python_version(python) >= "3.0"
335 0
    if (!is_python3) {
336 0
        stop("spacyr does not support virtual environment installation for python 2.*", call. = FALSE)
337
    }
338 0
    pip_version <- ifelse(is_python3, "pip3", "pip")
339

340 0
    virtualenv_root <- Sys.getenv("WORKON_HOME", unset = "~/.virtualenvs")
341 0
    virtualenv_path <- file.path(virtualenv_root, "spacy_virtualenv")
342

343 0
    cat(sprintf('A new virtual environment "%s" will be created and, \nspaCy and language model(s), "%s", will be installed.\n ',
344 0
                virtualenv_path,
345 0
                paste(lang_models, collapse = ", ")))
346 0
    if (prompt) {
347 0
        ans <- utils::menu(c("No", "Yes"), title = "Proceed?")
348 0
        if (ans == 1) stop("Virtualenv setup is cancelled by user", call. = FALSE)
349
    }
350

351
    # create virtualenv
352 0
    if (!file.exists(virtualenv_root))
353 0
        dir.create(virtualenv_root, recursive = TRUE)
354

355
    # helper to construct paths to virtualenv binaries
356 0
    virtualenv_bin <- function(bin) path.expand(file.path(virtualenv_path, "bin", bin))
357

358
    # create virtualenv if necessary
359 0
    if (!file.exists(virtualenv_path) || !file.exists(virtualenv_bin("activate"))) {
360 0
        cat("Creating virtualenv for spaCy at ", virtualenv_path, "\n")
361 0
        result <- system2(virtualenv, shQuote(c(
362
            #"--system-site-packages",
363 0
            "--python", python,
364 0
            path.expand(virtualenv_path)))
365
        )
366 0
        if (result != 0L)
367 0
            stop("Error ", result, " occurred creating virtualenv at ", virtualenv_path,
368 0
                 call. = FALSE)
369
    } else {
370 0
        cat("Using existing virtualenv at ", virtualenv_path, "\n")
371
    }
372

373
    # function to call pip within virtual env
374 0
    pip_install <- function(pkgs, message) {
375 0
        cmd <- sprintf("%ssource %s && %s install --ignore-installed --upgrade %s%s",
376 0
                       ifelse(is_osx(), "", "/bin/bash -c \""),
377 0
                       shQuote(path.expand(virtualenv_bin("activate"))),
378 0
                       shQuote(path.expand(virtualenv_bin(pip_version))),
379 0
                       paste(shQuote(pkgs), collapse = " "),
380 0
                       ifelse(is_osx(), "", "\""))
381 0
        cat(message, "...\n")
382 0
        result <- system(cmd)
383 0
        if (result != 0L)
384 0
            stop("Error ", result, " occurred installing spaCy", call. = FALSE)
385
    }
386

387
    # this function generates a forced pip error to get a version spaCy highest within a major version
388
    # e.g. if major_version == 1, it will return 1.10.1
389 0
    pip_get_version_virtualenv <- function(major_version) {
390 0
        cmd <- sprintf("%ssource %s && %s install --ignore-installed --upgrade %s%s",
391 0
                       ifelse(is_osx(), "", "/bin/bash -c \""),
392 0
                       shQuote(path.expand(virtualenv_bin("activate"))),
393 0
                       shQuote(path.expand(virtualenv_bin(pip_version))),
394 0
                       paste(shQuote("spacy==random"), collapse = " "),
395 0
                       ifelse(is_osx(), "", "\""))
396 0
        pip_get_version(cmd, major_version)
397
    }
398

399
    # upgrade pip so it can find spaCy
400 0
    pip_install("pip", "Upgrading pip")
401

402
    # install updated version of the wheel package
403 0
    pip_install("wheel", "Upgrading wheel")
404

405
    # upgrade setuptools so it can use wheels
406 0
    pip_install("setuptools", "Upgrading setuptools")
407

408 0
    if (version == "latest_v1") {
409 0
        version <- pip_get_version_virtualenv(1, major_version = 1)
410 0
        cat("Option \"version = version_v1\" is supplied, spaCy", version, "will be installed\n")
411
    }
412 0
    pkgs <- spacy_pkgs(version)
413 0
    pip_install(pkgs, "Installing spaCy...")
414

415 0
    for (model in lang_models) {
416 0
        spacy_download_langmodel_virtualenv(model = model)
417
    }
418
}
419

420
python_unix_binary <- function(bin) {
421 0
    locations <- file.path(c( "/usr/local/bin", "/usr/bin"), bin)
422 0
    locations <- locations[file.exists(locations)]
423 0
    if (length(locations) > 0)
424 0
        locations[[1]]
425
    else
426 0
        NULL
427
}
428

429
python_version <- function(python) {
430

431
    # check for the version
432 0
    result <- system2(python, "--version", stdout = TRUE, stderr = TRUE)
433

434
    # check for error
435 0
    error_status <- attr(result, "status")
436 0
    if (!is.null(error_status))
437 0
        stop("Error ", error_status, " occurred while checking for python version", call. = FALSE)
438

439
    # parse out the major and minor version numbers
440 0
    matches <- regexec("^[^ ]+\\s+(\\d+)\\.(\\d+).*$", result)
441 0
    matches <- regmatches(result, matches)[[1]]
442 0
    if (length(matches) != 3)
443 0
        stop("Unable to parse Python version '", result[[1]], "'", call. = FALSE)
444

445
    # return as R numeric version
446 0
    numeric_version(paste(matches[[2]], matches[[3]], sep = "."))
447
}
448

449

450
# form list of tf pkgs
451
spacy_pkgs <- function(version, packages = NULL) {
452 2
    if (is.null(packages))
453 2
        packages <- sprintf("spacy%s",
454 2
                            ifelse(version == "latest", "", paste0("=", version)))
455 2
    return(packages)
456
}
457

458
#' Uninstall spaCy conda environment
459
#'
460
#' Removes the conda environment created by spacy_install()
461
#' @param conda path to conda executable, default to "auto" which automatically
462
#'   finds the path
463
#' @param prompt logical; ask whether to proceed during the installation
464
#' @param envname character; name of conda environment to remove
465
#' @export
466
spacy_uninstall <- function(conda = "auto",
467
                            prompt = TRUE,
468
                            envname = "spacy_condaenv") {
469 2
    conda <- tryCatch(reticulate::conda_binary(conda), error = function(e) NULL)
470 2
    have_conda <- !is.null(conda)
471

472 2
    if (!have_conda)
473 0
        stop("Conda installation failed (no conda binary found)\n", call. = FALSE)
474

475 2
    conda_envs <- reticulate::conda_list(conda = conda)
476 2
    conda_env <- subset(conda_envs, conda_envs$name == envname)
477 2
    if (nrow(conda_env) != 1) {
478 0
        stop("conda environment", envname, "is not found", call. = FALSE)
479
    }
480 2
    cat("A conda environment", envname, "will be removed\n")
481 2
    ans <- ifelse(prompt, utils::menu(c("No", "Yes"), title = "Proceed?"), 2)
482 0
    if (ans == 1) stop("condaenv removal is cancelled by user", call. = FALSE)
483 2
    python <- reticulate::conda_remove(envname = envname)
484

485 2
    cat("\nUninstallation complete.\n\n")
486

487 2
    invisible(NULL)
488
}
489

490

491
#' Upgrade spaCy in conda environment
492
#'
493
#' @param conda Path to conda executable. Default "auto" which automatically
494
#'   find the path
495
#' @param pip \code{TRUE} to use pip for installing spacy. If \code{FALSE}, conda 
496
#' package manager with conda-forge channel will be used for installing spacy.
497

498
#' @param lang_models Language models to be upgraded. Default NULL (No upgrade). 
499
#'   A vector of multiple model names can be used (e.g. \code{c("en_core_web_sm", "de_core_web_sm")})
500
#' @param prompt logical; ask whether to proceed during the installation
501
#' @param envname character; name of conda environment to upgrade spaCy
502
#' @param update_conda logical; If \code{true}, the conda binary for the system will be updated to the latest version. 
503
#'  Default \code{FALSE}.
504
#' @export
505
spacy_upgrade  <- function(conda = "auto",
506
                           envname = "spacy_condaenv",
507
                           prompt = TRUE,
508
                           pip = FALSE,
509
                           update_conda = FALSE,
510
                           lang_models = "en_core_web_sm") {
511

512 2
    conda <- reticulate::conda_binary(conda)
513 2
    if (!(envname %in% reticulate::conda_list(conda = conda)$name)) {
514 0
        message("Conda evnronment", envname, "does not exist")
515
    }
516
    
517 2
    if (update_conda == TRUE) {
518 0
        message("Update conda binary")
519 0
        args <- reticulate:::conda_args("update", "root", "conda")
520 0
        result <- system2(conda, shQuote(args))
521 0
        message("Conda is updated\n")
522
    }
523
    
524 2
    message("checking spaCy version")
525 2
    condaenv_bin <- function(bin) path.expand(file.path(dirname(conda), bin))
526 2
    cmd <- sprintf("%s%s %s && pip search spacy%s",
527 2
                   ifelse(is_windows(), "", ifelse(is_osx(), "source ", "/bin/bash -c \"source ")),
528 2
                   shQuote(path.expand(condaenv_bin("activate"))),
529 2
                   envname,
530 2
                   ifelse(is_windows(), "", ifelse(is_osx(), "", "\"")))
531 2
    result <- system(cmd, intern = TRUE, ignore.stderr = TRUE)
532 2
    spacy_index <- grep("^spacy \\(", result)
533 2
    latest_spacy <- sub("spacy \\((.+?)\\).+", "\\1", result[spacy_index])
534 2
    installed_spacy <- sub(".+?(\\d.+\\d).*", "\\1", result[spacy_index + 1])
535 2
    if (!pip) {
536 2
        latest_spacy <- conda_get_version(major_version = NA, conda, envname)
537
    }
538 2
    if (latest_spacy == installed_spacy) {
539 2
        message("Your spaCy version is the latest available.")
540 2
        return(invisible(NULL))
541 2
    } else if (substr(installed_spacy, 0, 2) == "1.") {
542 2
        cat(sprintf("The version spacy installed is %s\n",
543 2
                    installed_spacy))
544 2
        ans <- if (prompt) utils::menu(c("v1.*", "v2.*"), title = sprintf("Do you want to upgrade to v1.* or lastest v2.*?")) else 2
545 2
        if (ans == 2) {
546 2
            cat("spaCy will be upgraded to version", latest_spacy, "\n")
547 2
            process_spacy_installation_conda(conda = conda,
548 2
                                             envname = envname,
549 2
                                             version = latest_spacy,
550 2
                                             lang_models = lang_models,
551 2
                                             python_version = "3.6",
552 2
                                             prompt = FALSE)
553 2
            message("\nSuccessfully upgraded\n",
554 2
                    sprintf("Condaenv: %s; Langage model(s): ", envname), lang_models, "\n",
555 2
                    "For the upgrade to take effect, please restart R session")
556
        } else {
557 0
            if (pip == TRUE) {
558 0
                cmd <- sprintf("%s%s %s && pip install --upgrade %s %s%s",
559 0
                               ifelse(is_windows(), "", ifelse(is_osx(), "source ", "/bin/bash -c \"source ")),
560 0
                               shQuote(path.expand(condaenv_bin("activate"))),
561 0
                               envname,
562 0
                               "--ignore-installed",
563 0
                               paste(shQuote("spacy==random"), collapse = " "),
564 0
                               ifelse(is_windows(), "", ifelse(is_osx(), "", "\"")))
565 0
                latest_spacy_v1 <- pip_get_version(cmd, major_version = 1)
566
            } else {
567 0
                latest_spacy_v1 <- conda_get_version(major_version = 1, conda, envname)
568
            }
569 0
            if (latest_spacy_v1 == installed_spacy){
570 0
                message("your spaCy is the latest v1")
571 0
                return(invisible(NULL))
572
            } else {
573 0
                cat(sprintf("A new version of spaCy v1 (%s) will be installed (installed version: %s)\n",
574 0
                            latest_spacy_v1, installed_spacy))
575 0
                process_spacy_installation_conda(conda = conda,
576 0
                                                 envname = envname,
577 0
                                                 version = "latest_v1",
578 0
                                                 lang_models = lang_models,
579 0
                                                 python_version = "3.6",
580 0
                                                 prompt = FALSE,
581 0
                                                 pip = pip)
582
            }
583
        }
584
    } else {
585 0
        cat(sprintf("A new version of spaCy (%s) was found (installed version: %s)\n",
586 0
                    latest_spacy, installed_spacy))
587 0
        ans <- if (prompt) utils::menu(c("No", "Yes"), title = sprintf("Do you want to upgrade?")) else 2
588 0
        if (ans == 2) {
589 0
            cat('"Yes" was chosen. spaCy will be upgraded.\n\n')
590 0
            if (!is.null(lang_models)) {
591 0
                ans <- ifelse(prompt, utils::menu(c("No", "Yes"),
592 0
                                                  title = sprintf("Do you also want to re-download language model %s?",
593 0
                                                  paste(lang_models, collapse = ", "))), 2)
594 0
                if (ans == 1) lang_models <- NULL
595
            }
596 0
            process_spacy_installation_conda(conda = conda,
597 0
                                             envname = envname,
598 0
                                             version = latest_spacy,
599 0
                                             lang_models = lang_models,
600 0
                                             python_version = "3.6",
601 0
                                             prompt = FALSE,
602 0
                                             pip = pip)
603 0
            message("\nSuccessfully upgraded\n",
604 0
                    sprintf("Condaenv: %s; Langage model(s): ", envname), lang_models, "\n",
605 0
                    "For the upgrade to take effect, please restart R session")
606

607
        } else {
608 0
            message("No upgrade is chosen")
609
        }
610

611
    }
612

613 2
    invisible(NULL)
614
}
615

616
install_miniconda <- function() {
617 0
    if (is_osx()) {
618 0
        message("Downloading installation script")
619 0
        system(paste(
620 0
            "curl https://repo.continuum.io/miniconda/Miniconda3-latest-MacOSX-x86_64.sh -o ~/miniconda.sh;",
621 0
            "echo \"Running installation script\";",
622 0
            "bash ~/miniconda.sh -b -p $HOME/miniconda"))
623 0
        system('echo \'export PATH="$PATH:$HOME/miniconda/bin"\' >> $HOME/.bash_profile; rm ~/miniconda.sh')
624 0
        message("Installation of miniconda complete")
625 0
    } else if (is_linux()) {
626 0
        message("Downloading installation script")
627 0
        system(paste(
628 0
            "wget -nv https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh -O ~/miniconda.sh;",
629 0
            "echo \"Running installation script\";",
630 0
            "bash ~/miniconda.sh -b -p $HOME/miniconda"))
631 0
        system('echo \'export PATH="$PATH:$HOME/miniconda/bin"\' >> $HOME/.bashrc; rm ~/miniconda.sh')
632 0
        message("Installation of miniconda complete")
633
    } else {
634 0
        stop("miniconda installation is available only for Mac or Linux")
635
    }
636
}
637

638
pip_get_version <- function(cmd, major_version) {
639 0
    regex <- "^(\\S+)\\s?(.*)$"
640 0
    cmd1 <- sub(regex, "\\1", cmd)
641 0
    cmd2 <- sub(regex, "\\2", cmd)
642 0
    oldw <- getOption("warn")
643 0
    options(warn = -1)
644 0
    result <- paste(system2(cmd1, cmd2, stdout = TRUE, stderr = TRUE),
645 0
                    collapse = " ")
646 0
    options(warn = oldw)
647 0
    version_check_regex <- sprintf(".+(%s.\\d+\\.\\d+).+", major_version)
648 0
    return(sub(version_check_regex, "\\1", result))
649
}
650

651

652
conda_get_version <- function(major_version = NA, conda, envname) {
653 2
    condaenv_bin <- function(bin) path.expand(file.path(dirname(conda), bin))
654 2
    cmd <- sprintf("%s%s %s && conda search spacy -c conda-forge%s",
655 2
                   ifelse(is_windows(), "", ifelse(is_osx(), "source ", "/bin/bash -c \"source ")),
656 2
                   shQuote(path.expand(condaenv_bin("activate"))),
657 2
                   envname,
658 2
                   ifelse(is_windows(), "", ifelse(is_osx(), "", "\"")))
659 2
    regex <- "^(\\S+)\\s?(.*)$"
660 2
    cmd1 <- sub(regex, "\\1", cmd)
661 2
    cmd2 <- sub(regex, "\\2", cmd)
662 2
    oldw <- getOption("warn")
663 2
    result <- system2(cmd1, cmd2, stdout = TRUE, stderr = TRUE)
664 2
    result <- sub("\\S+\\s+(\\S+)\\s.+", "\\1", result)
665 2
    if (!is.na(major_version)) {
666 0
        result <- grep(paste0("^", major_version, "\\."), result, value = T)
667
    }
668
    #version_check_regex <- sprintf(".+(%s.\\d+\\.\\d+).+", major_version)
669 2
    return(result[length(result)])
670
}
671

Read our documentation on viewing source code .

Loading