diff --git a/src/nimblepkg/checksums.nim b/src/nimblepkg/checksums.nim index 39d7534a..5a434529 100644 --- a/src/nimblepkg/checksums.nim +++ b/src/nimblepkg/checksums.nim @@ -25,22 +25,36 @@ proc updateSha1Checksum(checksum: var Sha1State, fileName, filePath: string) = # directory from which no files are being installed. return checksum.update(fileName) - var file: File - try: - file = filePath.open(fmRead) - except IOError: - ## If the file cannot be open for reading do not count its content in the - ## checksum. - displayWarning(&"The file \"{filePath}\" cannot be open for reading.\n" & - "Skipping it in the calculation of the checksum.") - return - defer: close(file) - const bufferSize = 8192 - var buffer = newString(bufferSize) - while true: - var bytesRead = readChars(file, buffer) - if bytesRead == 0: break - checksum.update(buffer.toOpenArray(0, bytesRead - 1)) + if symlinkExists(filePath): + # Check whether a file is a symbolic link and if so update the checksum with + # the path to the file that the link points to. + var linkPath: string + try: + linkPath = expandSymlink(filePath) + except OSError: + displayWarning(&"Cannot expand symbolic link \"{filePath}\".\n" & + "Skipping it in the calculation of the checksum.") + return + checksum.update(linkPath) + else: + # Otherwise this is an ordinary file and we are adding its content to the + # checksum. + var file: File + try: + file = filePath.open(fmRead) + except IOError: + ## If the file cannot be open for reading do not count its content in the + ## checksum. + displayWarning(&"The file \"{filePath}\" cannot be open for reading.\n" & + "Skipping it in the calculation of the checksum.") + return + defer: close(file) + const bufferSize = 8192 + var buffer = newString(bufferSize) + while true: + var bytesRead = readChars(file, buffer) + if bytesRead == 0: break + checksum.update(buffer.toOpenArray(0, bytesRead - 1)) proc calculateDirSha1Checksum*(dir: string): Sha1Hash = ## Recursively calculates the sha1 checksum of the contents of the directory diff --git a/src/nimblepkg/download.nim b/src/nimblepkg/download.nim index c550186c..ae64918c 100644 --- a/src/nimblepkg/download.nim +++ b/src/nimblepkg/download.nim @@ -309,6 +309,25 @@ proc doDownloadTarball(url, downloadDir, version: string, queryRevision: bool): raise nimbleError(tryDoCmdExErrorMessage(cmd, output, exitCode)) display("Completed", "unpacking " & filePath) + when defined(windows): + # On Windows symbolic link files are not being extracted properly by the + # `tar` command. They are extracted as empty files, but when cloning the + # repository with Git they are extracted as ordinary files with the link + # path in them. For that reason here we parse the tar file content to + # extract the symbolic links and add their paths manually to the content of + # their files. + let listCmd = &"{getTarExePath()} -ztvf {filePath} --force-local" + let (cmdOutput, cmdExitCode) = doCmdEx(listCmd) + if cmdExitCode != QuitSuccess: + raise nimbleError(tryDoCmdExErrorMessage(listCmd, cmdOutput, cmdExitCode)) + for line in cmdOutput.splitLines(): + if line.contains(" -> "): + let parts = line.split + let linkPath = parts[^1] + let linkNameParts = parts[^3].split('/') + let linkName = linkNameParts[1 .. ^1].foldl(a / b) + writeFile(downloadDir / linkName, linkPath) + filePath.removeFile return if queryRevision: getRevision(url, version) else: notSetSha1Hash diff --git a/src/nimblepkg/vcstools.nim b/src/nimblepkg/vcstools.nim index 177ed32a..104bfd29 100644 --- a/src/nimblepkg/vcstools.nim +++ b/src/nimblepkg/vcstools.nim @@ -203,7 +203,12 @@ proc getVcsRevision*(dir: Path): Sha1Hash = proc getPackageFileListWithoutVcs(dir: Path): seq[string] = ## Recursively walks the directory `dir` and returns a list of files in it and ## its subdirectories. - for file in walkDirRec($dir, relative = true): + for file in walkDirRec($dir, yieldFilter = {pcFile, pcLinkToFile}, + relative = true): + when defined(windows): + # On windows relative paths to files which are included in the calculation + # of the package checksum must be the same as on POSIX systems. + let file = file.replace('\\', '/') result.add file proc getPackageFileList*(dir: Path): seq[string] = @@ -1060,7 +1065,6 @@ username = John Doe check not isValidSha1Hash($getVcsRevision(testNoVcsDir)) test "getPackageFileList": - check getPackageFileList(testNoVcsDir) == - @[testFile, testSubDirFile.normalizedPath] + check getPackageFileList(testNoVcsDir) == @[testFile, testSubDirFile] tearDownSuite(testNoVcsDir)