Implemented a whitelist mode.
This commit is contained in:
parent
9f60514c40
commit
19b5d3072f
5 changed files with 104 additions and 40 deletions
116
babel.nim
116
babel.nim
|
|
@ -107,6 +107,10 @@ proc copyFileD(fro, to: string) =
|
||||||
echo(fro, " -> ", to)
|
echo(fro, " -> ", to)
|
||||||
copyFile(fro, to)
|
copyFile(fro, to)
|
||||||
|
|
||||||
|
proc copyDirD(fro, to: string) =
|
||||||
|
echo(fro, " -> ", to)
|
||||||
|
copyDir(fro, to)
|
||||||
|
|
||||||
proc doCmd(cmd: string) =
|
proc doCmd(cmd: string) =
|
||||||
let exitCode = execCmd(cmd)
|
let exitCode = execCmd(cmd)
|
||||||
if exitCode != QuitSuccess:
|
if exitCode != QuitSuccess:
|
||||||
|
|
@ -122,42 +126,81 @@ template cd(dir: string, body: stmt) =
|
||||||
body
|
body
|
||||||
setCurrentDir(lastDir)
|
setCurrentDir(lastDir)
|
||||||
|
|
||||||
|
proc checkInstallFile(pkgInfo: TPackageInfo,
|
||||||
|
origDir, file: string): bool =
|
||||||
|
## Checks whether ``file`` should be installed.
|
||||||
|
## ``True`` means file should be skipped.
|
||||||
|
|
||||||
|
for ignoreFile in pkgInfo.skipFiles:
|
||||||
|
if ignoreFile.endswith("babel"):
|
||||||
|
raise newException(EBabel, ignoreFile & " must be installed.")
|
||||||
|
if samePaths(file, origDir / ignoreFile):
|
||||||
|
result = true
|
||||||
|
break
|
||||||
|
|
||||||
|
for ignoreExt in pkgInfo.skipExt:
|
||||||
|
if file.splitFile.ext == ('.' & ignoreExt):
|
||||||
|
result = true
|
||||||
|
break
|
||||||
|
|
||||||
|
if file.splitFile().name[0] == '.': result = true
|
||||||
|
|
||||||
|
proc checkInstallDir(pkgInfo: TPackageInfo,
|
||||||
|
origDir, dir: string): bool =
|
||||||
|
## Determines whether ``dir`` should be installed.
|
||||||
|
## ``True`` means dir should be skipped.
|
||||||
|
for ignoreDir in pkgInfo.skipDirs:
|
||||||
|
if samePaths(dir, origDir / ignoreDir):
|
||||||
|
result = true
|
||||||
|
break
|
||||||
|
|
||||||
|
let thisDir = splitPath(dir).tail
|
||||||
|
assert thisDir != ""
|
||||||
|
if thisDir[0] == '.': result = true
|
||||||
|
if thisDir == "nimcache": result = true
|
||||||
|
|
||||||
|
proc copyWithExt(origDir, currentDir, dest: string, pkgInfo: TPackageInfo) =
|
||||||
|
for kind, path in walkDir(currentDir):
|
||||||
|
if kind == pcDir:
|
||||||
|
copyWithExt(origDir, path, dest, pkgInfo)
|
||||||
|
else:
|
||||||
|
for iExt in pkgInfo.installExt:
|
||||||
|
if path.splitFile.ext == ('.' & iExt):
|
||||||
|
createDir(changeRoot(origDir, dest, path).splitFile.dir)
|
||||||
|
copyFileD(path, changeRoot(origDir, dest, path))
|
||||||
|
|
||||||
proc copyFilesRec(origDir, currentDir, dest: string, pkgInfo: TPackageInfo) =
|
proc copyFilesRec(origDir, currentDir, dest: string, pkgInfo: TPackageInfo) =
|
||||||
## 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).
|
## (TPackageInfo).
|
||||||
for kind, file in walkDir(currentDir):
|
let whitelistMode =
|
||||||
if kind == pcDir:
|
pkgInfo.installDirs.len != 0 or
|
||||||
var skip = false
|
pkgInfo.installFiles.len != 0 or
|
||||||
for ignoreDir in pkgInfo.skipDirs:
|
pkgInfo.installExt.len != 0
|
||||||
if samePaths(file, origDir / ignoreDir):
|
if whitelistMode:
|
||||||
skip = true
|
for file in pkgInfo.installFiles:
|
||||||
break
|
createDir(dest / file.splitFile.dir)
|
||||||
let thisDir = splitPath(file).tail
|
copyFileD(origDir / file, dest / file)
|
||||||
assert thisDir != ""
|
|
||||||
if thisDir[0] == '.': skip = true
|
for dir in pkgInfo.installDirs:
|
||||||
if thisDir == "nimcache": skip = true
|
# TODO: Allow skipping files inside dirs?
|
||||||
|
copyDirD(origDir / dir, dest / dir)
|
||||||
if skip: continue
|
|
||||||
# Create the dir.
|
copyWithExt(origDir, currentDir, dest, pkgInfo)
|
||||||
createDir(changeRoot(origDir, dest, file))
|
else:
|
||||||
|
for kind, file in walkDir(currentDir):
|
||||||
copyFilesRec(origDir, file, dest, pkgInfo)
|
if kind == pcDir:
|
||||||
else:
|
let skip = pkgInfo.checkInstallDir(origDir, file)
|
||||||
var skip = false
|
|
||||||
if file.splitFile().name[0] == '.': skip = true
|
if skip: continue
|
||||||
for ignoreFile in pkgInfo.skipFiles:
|
# Create the dir.
|
||||||
if ignoreFile.endswith("babel"):
|
createDir(changeRoot(origDir, dest, file))
|
||||||
raise newException(EBabel, ignoreFile & " must be installed.")
|
|
||||||
if samePaths(file, origDir / ignoreFile):
|
copyFilesRec(origDir, file, dest, pkgInfo)
|
||||||
skip = true
|
else:
|
||||||
break
|
let skip = pkgInfo.checkInstallFile(origDir, file)
|
||||||
|
|
||||||
for ignoreExt in pkgInfo.skipExt:
|
if skip: continue
|
||||||
if file.splitFile.ext == ('.' & ignoreExt):
|
|
||||||
skip = true
|
|
||||||
break
|
|
||||||
|
|
||||||
if not skip:
|
|
||||||
copyFileD(file, changeRoot(origDir, dest, file))
|
copyFileD(file, changeRoot(origDir, dest, file))
|
||||||
|
|
||||||
proc install(packages: seq[String], verRange: PVersionRange): string {.discardable.}
|
proc install(packages: seq[String], verRange: PVersionRange): string {.discardable.}
|
||||||
|
|
@ -220,12 +263,13 @@ proc installFromDir(dir: string, latest: bool): string =
|
||||||
buildFromDir(dir, paths)
|
buildFromDir(dir, paths)
|
||||||
createDir(binDir)
|
createDir(binDir)
|
||||||
# Copy all binaries and files that are not skipped
|
# Copy all binaries and files that are not skipped
|
||||||
var nPkgInfo = pkgInfo
|
copyFilesRec(dir, dir, pkgDestDir, pkgInfo)
|
||||||
nPkgInfo.skipExt.add("nim") # Implicitly skip .nim files
|
|
||||||
copyFilesRec(dir, dir, pkgDestDir, nPkgInfo)
|
|
||||||
# Set file permissions to +x for all binaries built,
|
# Set file permissions to +x for all binaries built,
|
||||||
# and symlink them on *nix OS' to $babelDir/bin/
|
# and symlink them on *nix OS' to $babelDir/bin/
|
||||||
for bin in pkgInfo.bin:
|
for bin in pkgInfo.bin:
|
||||||
|
if not existsFile(pkgDestDir / bin):
|
||||||
|
copyFileD(dir / bin, pkgDestDir / bin)
|
||||||
|
|
||||||
let currentPerms = getFilePermissions(pkgDestDir / bin)
|
let currentPerms = getFilePermissions(pkgDestDir / bin)
|
||||||
setFilePermissions(pkgDestDir / bin, currentPerms + {fpUserExec})
|
setFilePermissions(pkgDestDir / bin, currentPerms + {fpUserExec})
|
||||||
when defined(unix):
|
when defined(unix):
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
Copyright (c) 2012, Dominik Picheta
|
Copyright (c) 2013, Dominik Picheta
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,9 @@ type
|
||||||
skipDirs*: seq[string]
|
skipDirs*: seq[string]
|
||||||
skipFiles*: seq[string]
|
skipFiles*: seq[string]
|
||||||
skipExt*: seq[string]
|
skipExt*: seq[string]
|
||||||
|
installDirs*: seq[string]
|
||||||
|
installFiles*: seq[string]
|
||||||
|
installExt*: seq[string]
|
||||||
requires*: seq[tuple[name: string, ver: PVersionRange]]
|
requires*: seq[tuple[name: string, ver: PVersionRange]]
|
||||||
bin*: seq[string]
|
bin*: seq[string]
|
||||||
|
|
||||||
|
|
@ -36,6 +39,9 @@ proc initPackageInfo(): TPackageInfo =
|
||||||
result.skipDirs = @[]
|
result.skipDirs = @[]
|
||||||
result.skipFiles = @[]
|
result.skipFiles = @[]
|
||||||
result.skipExt = @[]
|
result.skipExt = @[]
|
||||||
|
result.installDirs = @[]
|
||||||
|
result.installFiles = @[]
|
||||||
|
result.installExt = @[]
|
||||||
result.requires = @[]
|
result.requires = @[]
|
||||||
result.bin = @[]
|
result.bin = @[]
|
||||||
|
|
||||||
|
|
@ -93,6 +99,12 @@ proc readPackageInfo*(path: string): TPackageInfo =
|
||||||
result.skipFiles.add(ev.value.split(','))
|
result.skipFiles.add(ev.value.split(','))
|
||||||
of "skipext":
|
of "skipext":
|
||||||
result.skipExt.add(ev.value.split(','))
|
result.skipExt.add(ev.value.split(','))
|
||||||
|
of "installdirs":
|
||||||
|
result.installDirs.add(ev.value.split(','))
|
||||||
|
of "installfiles":
|
||||||
|
result.installFiles.add(ev.value.split(','))
|
||||||
|
of "installext":
|
||||||
|
result.installExt.add(ev.value.split(','))
|
||||||
of "bin":
|
of "bin":
|
||||||
for i in ev.value.split(','):
|
for i in ev.value.split(','):
|
||||||
result.bin.add(i.addFileExt(ExeExt))
|
result.bin.add(i.addFileExt(ExeExt))
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,10 @@ structure may be enforced in the future.
|
||||||
|
|
||||||
All files and folders in the directory of where the .babel file resides will be
|
All files and folders in the directory of where the .babel file resides will be
|
||||||
copied as-is, you can however skip some directories or files by setting
|
copied as-is, you can however skip some directories or files by setting
|
||||||
the 'SkipDirs' or 'SkipFiles' options in your .babel file.
|
the ``SkipDirs``, ``SkipFiles`` or ``SkipExt`` options in your .babel file.
|
||||||
|
Directories and files can also be specified on a *whitelist* basis, if you
|
||||||
|
specify either of ``InstallDirs``, ``InstallFiles`` or ``InstallExt`` then
|
||||||
|
babel will **only** install the files specified.
|
||||||
|
|
||||||
#### Example library .babel file
|
#### Example library .babel file
|
||||||
|
|
||||||
|
|
@ -90,6 +93,8 @@ file, copy it into ``$babelDir/pkgs/pkgname-ver/`` and subsequently create a
|
||||||
symlink to the binary in ``$babelDir/bin/``. On Windows a stub .bat file is
|
symlink to the binary in ``$babelDir/bin/``. On Windows a stub .bat file is
|
||||||
created instead.
|
created instead.
|
||||||
|
|
||||||
|
Other files will be copied in the same way as they are for library packages.
|
||||||
|
|
||||||
Dependencies are automatically installed before building.
|
Dependencies are automatically installed before building.
|
||||||
|
|
||||||
## Dependencies
|
## Dependencies
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,11 @@ proc getNimrodVersion*: TVersion =
|
||||||
|
|
||||||
proc samePaths*(p1, p2: string): bool =
|
proc samePaths*(p1, p2: string): bool =
|
||||||
## Normalizes path (by adding a trailing slash) and compares.
|
## Normalizes path (by adding a trailing slash) and compares.
|
||||||
let cp1 = if not p1.endsWith("/"): p1 & "/" else: p1
|
var cp1 = if not p1.endsWith("/"): p1 & "/" else: p1
|
||||||
let cp2 = if not p2.endsWith("/"): p2 & "/" else: p2
|
var cp2 = if not p2.endsWith("/"): p2 & "/" else: p2
|
||||||
|
cp1 = cp1.replace('/', DirSep).replace('\\', DirSep)
|
||||||
|
cp2 = cp2.replace('/', DirSep).replace('\\', DirSep)
|
||||||
|
|
||||||
return cmpPaths(cp1, cp2) == 0
|
return cmpPaths(cp1, cp2) == 0
|
||||||
|
|
||||||
proc changeRoot*(origRoot, newRoot, path: string): string =
|
proc changeRoot*(origRoot, newRoot, path: string): string =
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue