datasnakes / renv

Creating virtual environments for R.
MIT License
17 stars 0 forks source link

Model setup_r() method after setup_python() method. #8

Closed grabear closed 6 years ago

grabear commented 6 years ago

The setup_r() method will create R executables in the environment using various strategies. Will be modeled after setup_python(), which is shown below:

def setup_python(self, context):
        """
        Set up a Python executable in the environment.
        :param context: The information for the environment creation request
                        being processed.
        """
        binpath = context.bin_path
        path = context.env_exe
        copier = self.symlink_or_copy
        copier(context.executable, path)
        dirname = context.python_dir
        if os.name != 'nt':
            if not os.path.islink(path):
                os.chmod(path, 0o755)
            for suffix in ('python', 'python3'):
                path = os.path.join(binpath, suffix)
                if not os.path.exists(path):
                    # Issue 18807: make copies if
                    # symlinks are not wanted
                    copier(context.env_exe, path, relative_symlinks_ok=True)
                    if not os.path.islink(path):
                        os.chmod(path, 0o755)
        else:
            subdir = 'DLLs'
            include = self.include_binary
            files = [f for f in os.listdir(dirname) if include(f)]
            for f in files:
                src = os.path.join(dirname, f)
                dst = os.path.join(binpath, f)
                if dst != context.env_exe:  # already done, above
                    copier(src, dst)
            dirname = os.path.join(dirname, subdir)
            if os.path.isdir(dirname):
                files = [f for f in os.listdir(dirname) if include(f)]
                for f in files:
                    src = os.path.join(dirname, f)
                    dst = os.path.join(binpath, f)
                    copier(src, dst)
            # copy init.tcl over
            for root, dirs, files in os.walk(context.python_dir):
                if 'init.tcl' in files:
                    tcldir = os.path.basename(root)
                    tcldir = os.path.join(context.env_dir, 'Lib', tcldir)
                    if not os.path.exists(tcldir):
                        os.makedirs(tcldir)
                    src = os.path.join(root, 'init.tcl')
                    dst = os.path.join(tcldir, 'init.tcl')
                    shutil.copyfile(src, dst)
                    break
grabear commented 6 years ago

The recommended packages need to be downloaded and installed manually via: https://cran.r-project.org/doc/manuals/r-release/R-admin.html#Using-Subversion-and-rsync

If downloading manually from CRAN, do ensure that you have the correct versions of the recommended packages: if the number in the file VERSION is ‘x.y.z’ you need to download the contents of ‘https://CRAN.R-project.org/src/contrib/dir’, where dir is ‘x.y.z/Recommended’ for r-devel or x.y-patched/Recommended for r-patched, respectively, to directory src/library/Recommended in the sources you have unpacked. After downloading manually you need to execute tools/link-recommended from the top level of the sources to make the requisite links in src/library/Recommended. A suitable incantation from the top level of the R sources using wget might be (for the correct value of dir)

wget -r -l1 --no-parent -A*.gz -nd -P src/library/Recommended \ https://CRAN.R-project.org/src/contrib/dir ./tools/link-recommended

The recommended packages for R-3.4.4 can be found here: https://cran.r-project.org/src/contrib/3.4.4/Recommended/

grabear commented 6 years ago

The original plan was to get the recommended packages from the R installation on the system from the command line using Rscript -e "get pkg list" described below:

            Rcmd = f"{context.abs_R_script} " \
                     f"-e \'base::cat(rownames(installed.packages(priority=\"recommended\")))\'"
            recommended_pkgs = subprocess.Popen([Rcmd], stderr=subprocess.PIPE, stdout=subprocess.PIPE,
                                                shell=True, encoding='utf-8')
            error = recommended_pkgs.stderr.readlines()
            out = recommended_pkgs.stdout.readlines()
            recommended_pkgs.wait()
            recommended_pkgs = out[0].decode("utf-8").split(" ")

But after reading the R documentation again, I was finally able to find the tar files that R builds upon installation.

grabear commented 6 years ago

I verified that symbolic links can be made to the base packages, while allowing R to function normally. (Linux vs Windows). I used the Testing a Unix Like Installation section of the R Manual. Currently, only tried tools::testInstalledBasic("both").

Install the recommended packages by default, but offer the ability to system link to them as well.

The packages could also be copied over, but that takes up more space. Admittedly, this should probably be the default for creating a more genuine R virtual environment.

Using the subprocess workflow above, create more config variables called base_packages, and recommended_packages.

grabear commented 6 years ago

The setup_r script was mostly finished here: 3fda77a1828549ab5610f655cd6474c821175821