From b56262010bfca072995fd10833c548186f74f765 Mon Sep 17 00:00:00 2001 From: Dominik Picheta Date: Fri, 21 Jun 2013 21:49:50 +0100 Subject: [PATCH] Implements binary package symlinking to $babelDir/bin. This fixes the issues outlined http://forum.nimrod-code.org/t/163; Windows support is still TODO. --- babel.nim | 43 +++++++++++++++++++++++++++++++------------ packageinfo.nim | 4 ++++ todo.markdown | 3 ++- 3 files changed, 37 insertions(+), 13 deletions(-) diff --git a/babel.nim b/babel.nim index feaac4c..83fc108 100644 --- a/babel.nim +++ b/babel.nim @@ -113,8 +113,8 @@ proc doCmd(cmd: string) = quit("Execution failed with exit code " & $exitCode, QuitFailure) proc copyFilesRec(origDir, currentDir, dest: string, pkgInfo: TPackageInfo) = - ## Used for library-only packages. Copies all the required files, skips - ## files specified in the .babel file. + ## Copies all the required files, skips files specified in the .babel file + ## (TPackageInfo). for kind, file in walkDir(currentDir): if kind == pcDir: var skip = false @@ -122,7 +122,7 @@ proc copyFilesRec(origDir, currentDir, dest: string, pkgInfo: TPackageInfo) = if samePaths(file, origDir / ignoreDir): skip = true break - let thisDir = splitPath(file).tail + let thisDir = splitPath(file).tail assert thisDir != "" if thisDir[0] == '.': skip = true if thisDir == "nimcache": skip = true @@ -142,6 +142,11 @@ proc copyFilesRec(origDir, currentDir, dest: string, pkgInfo: TPackageInfo) = skip = true break + for ignoreExt in pkgInfo.skipExt: + if file.splitFile.ext == ('.' & ignoreExt): + skip = true + break + if not skip: copyFileD(file, changeRoot(origDir, dest, file)) @@ -181,14 +186,19 @@ proc buildFromDir(dir: string, paths: seq[string]) = proc installFromDir(dir: string, latest: bool): string = ## Returns where package has been installed to. If package is a binary, - ## ``""`` is returned. + ## ``""`` is returned. The return value of this function is used by + ## ``processDeps`` to gather a list of paths to pass to the nimrod compiler. var pkgInfo = getPkgInfo(dir) let pkgDestDir = libsDir / (pkgInfo.name & (if latest: "" else: '-' & pkgInfo.version)) if existsDir(pkgDestDir): - if not prompt("Package already exists. Overwrite?"): + if not prompt(pkgInfo.name & " already exists. Overwrite?"): quit(QuitSuccess) removeDir(pkgDestDir) + # Remove any symlinked binaries + for bin in pkgInfo.bin: + # TODO: Check that this binary belongs to the package being installed. + removeFile(binDir / bin) echo("Installing ", pkginfo.name, "-", pkginfo.version) @@ -199,19 +209,28 @@ proc installFromDir(dir: string, latest: bool): string = if pkgInfo.bin.len > 0: buildFromDir(dir, paths) createDir(binDir) + # Copy all binaries and files that are not skipped + var nPkgInfo = pkgInfo + nPkgInfo.skipExt.add("nim") # Implicitly skip .nim files + copyFilesRec(dir, dir, pkgDestDir, nPkgInfo) + # Set file permissions to +x for all binaries built, + # and symlink them on *nix OS' to $babelDir/bin/ for bin in pkgInfo.bin: - copyFileD(dir / bin, binDir / bin) - let currentPerms = getFilePermissions(binDir / bin) - setFilePermissions(binDir / bin, currentPerms + {fpUserExec}) - # Copy the .babel to lib/ - let babelFile = findBabelFile(dir) - copyFileD(babelFile, changeRoot(dir, pkgDestDir, babelFile)) + let currentPerms = getFilePermissions(pkgDestDir / bin) + setFilePermissions(pkgDestDir / bin, currentPerms + {fpUserExec}) + when defined(unix): + doCmd("ln -s \"" & pkgDestDir / bin & "\" " & binDir / bin) + elif defined(windows): + {.error: "TODO WINDOWS".} + else: + {.error: "Sorry, your platform is not supported.".} result = "" else: copyFilesRec(dir, dir, pkgDestDir, pkgInfo) - echo(pkgInfo.name & " installed successfully.") result = pkgDestDir + echo(pkgInfo.name & " installed successfully.") + proc getTagsList(dir: string): seq[string] = let output = execProcess("cd \"" & dir & "\" && git tag") if output.len > 0: diff --git a/packageinfo.nim b/packageinfo.nim index 5131bbc..5b9cc44 100644 --- a/packageinfo.nim +++ b/packageinfo.nim @@ -12,6 +12,7 @@ type license*: string skipDirs*: seq[string] skipFiles*: seq[string] + skipExt*: seq[string] requires*: seq[tuple[name: string, ver: PVersionRange]] bin*: seq[string] @@ -34,6 +35,7 @@ proc initPackageInfo(): TPackageInfo = result.license = "" result.skipDirs = @[] result.skipFiles = @[] + result.skipExt = @[] result.requires = @[] result.bin = @[] @@ -89,6 +91,8 @@ proc readPackageInfo*(path: string): TPackageInfo = result.skipDirs.add(ev.value.split(',')) of "skipfiles": result.skipFiles.add(ev.value.split(',')) + of "skipext": + result.skipExt.add(ev.value.split(',')) of "bin": result.bin = ev.value.split(',') else: diff --git a/todo.markdown b/todo.markdown index 17f7bc1..98c97ae 100644 --- a/todo.markdown +++ b/todo.markdown @@ -8,4 +8,5 @@ * A way to install specific versions of a package. * more package download methods * Allow for proper versions of packages to download. Reuse 'version' field - in packages.json. \ No newline at end of file + in packages.json. +* Install only .nim files when installing library packages? \ No newline at end of file