From c44089b3c1712c536f2071b5040fb8a83e6f361c Mon Sep 17 00:00:00 2001 From: jan Anja Date: Tue, 14 Dec 2021 18:03:27 +0500 Subject: [PATCH] Add --offline option (#967) * Add --offline flag Closes #699 * Add --ofline test in tuninstall.nim * Add --offline test in tnimblerefresh.nim --- src/nimble.nim | 33 +++++++++++++++++++++++---------- src/nimblepkg/download.nim | 3 +++ src/nimblepkg/options.nim | 3 +++ tests/tnimblerefresh.nim | 5 +++++ tests/tuninstall.nim | 7 +++++++ 5 files changed, 41 insertions(+), 10 deletions(-) diff --git a/src/nimble.nim b/src/nimble.nim index 5ac96217..861376c1 100644 --- a/src/nimble.nim +++ b/src/nimble.nim @@ -31,6 +31,9 @@ proc refresh(options: Options) = ## Downloads the package list from the specified URL. ## ## If the download is not successful, an exception is raised. + if options.offline: + raise nimbleError("Cannot refresh package list in offline mode.") + let parameter = if options.action.typ == actionRefresh: options.action.optionalURL @@ -310,7 +313,7 @@ proc installFromDir(dir: string, requestedVer: VersionRange, options: Options, PackageDependenciesInfo = ## Returns where package has been installed to, together with paths ## to the packages this package depends on. - ## + ## ## The return value of this function is used by ## ``processFreeDependencies`` ## To gather a list of paths to pass to the Nim compiler. @@ -507,6 +510,8 @@ proc raiseCannotCloneInExistingDirException(downloadDir: string) = proc downloadDependency(name: string, dep: LockFileDep, options: Options): DownloadInfo = ## Downloads a dependency from the lock file. + if options.offline: + raise nimbleError("Cannot download in offline mode.") if not options.developWithDependencies: let depDirName = getDependencyDir(name, dep, options) @@ -547,14 +552,14 @@ proc downloadDependency(name: string, dep: LockFileDep, options: Options): result = DownloadInfo( name: name, dependency: dep, - url: url, + url: url, version: version, downloadDir: downloadDir, vcsRevision: vcsRevision) proc installDependency(pkgInfo: PackageInfo, downloadInfo: DownloadInfo, options: Options): PackageInfo = - ## Installs an already downloaded dependency of the package `pkgInfo`. + ## Installs an already downloaded dependency of the package `pkgInfo`. let (_, newlyInstalledPkgInfo) = installFromDir( downloadInfo.downloadDir, downloadInfo.version, @@ -569,7 +574,7 @@ proc installDependency(pkgInfo: PackageInfo, downloadInfo: DownloadInfo, for depDepName in downloadInfo.dependency.dependencies: let depDep = pkgInfo.lockedDeps[depDepName] let revDep = (name: depDepName, version: depDep.version, - checksum: depDep.checksums.sha1) + checksum: depDep.checksums.sha1) options.nimbleData.addRevDep(revDep, newlyInstalledPkgInfo) return newlyInstalledPkgInfo @@ -589,9 +594,11 @@ proc processLockedDependencies(pkgInfo: PackageInfo, options: Options): result.incl developModeDeps[name][] elif isInstalled(name, dep, options): result.incl getDependency(name, dep, options) - else: + elif not options.offline: let downloadResult = downloadDependency(name, dep, options) result.incl installDependency(pkgInfo, downloadResult, options) + else: + raise nimbleError("Unsatisfied dependency: " & pkgInfo.basicInfo.name) proc getDownloadInfo*(pv: PkgTuple, options: Options, doPrompt: bool): (DownloadMethod, string, @@ -607,7 +614,7 @@ proc getDownloadInfo*(pv: PkgTuple, options: Options, else: # If package is not found give the user a chance to refresh # package.json - if doPrompt and + if doPrompt and not options.offline and options.prompt(pv.name & " not found in any local packages.json, " & "check internet for updated packages?"): refresh(options) @@ -1466,7 +1473,7 @@ proc validateDevModeDepsWorkingCopiesBeforeLock( vekWorkingCopyNeedsLock, vekWorkingCopyNeedsMerge, } - + # Remove not errors from the errors set. for name, error in common.dup(errors): if error.kind in notAnErrorSet: @@ -1507,7 +1514,7 @@ proc mergeLockedDependencies*(pkgInfo: PackageInfo, newDeps: LockFileDeps, proc displayLockOperationStart(dir: string): bool = ## Displays a proper log message for starting generating or updating the lock ## file of a package in directory `dir`. - + var doesLockFileExist = dir.lockFileExists let msg = if doesLockFileExist: updatingTheLockFileMsg @@ -1527,7 +1534,7 @@ proc displayLockOperationFinish(didLockFileExist: bool) = displaySuccess(msg) proc lock(options: Options) = - ## Generates a lock file for the package in the current directory or updates + ## Generates a lock file for the package in the current directory or updates ## it if it already exists. let currentDir = getCurrentDir() @@ -1564,6 +1571,9 @@ proc syncWorkingCopy(name: string, path: Path, dependentPkg: PackageInfo, ## with name `name` at path `path` with the revision from the lock file of ## `dependentPkg`. + if options.offline: + raise nimbleError("Cannot sync in offline mode.") + displayInfo(&"Syncing working copy of package \"{name}\" at \"{path}\"...") let lockedDeps = dependentPkg.lockedDeps @@ -1594,7 +1604,7 @@ proc syncWorkingCopy(name: string, path: Path, dependentPkg: PackageInfo, path, vcsRevision, btRemoteTracking) allBranches = localBranches + remoteTrackingBranches - var targetBranch = + var targetBranch = if allBranches.len == 0: # Te revision is not found on any branch. "" @@ -1677,6 +1687,9 @@ proc sync(options: Options) = if not pkgInfo.areLockedDepsLoaded: raise nimbleError("Cannot execute `sync` when lock file is missing.") + if options.offline: + raise nimbleError("Cannot execute `sync` in offline mode.") + if not options.action.listOnly: # On `sync` we also want to update Nimble cache with the dependencies' # versions from the lock file. diff --git a/src/nimblepkg/download.nim b/src/nimblepkg/download.nim index 0f93f4f3..a7ca3483 100644 --- a/src/nimblepkg/download.nim +++ b/src/nimblepkg/download.nim @@ -451,6 +451,9 @@ proc downloadPkg*(url: string, verRange: VersionRange, ## If specified this parameter will cause specific VCS revision to be ## checked out. + if options.offline: + raise nimbleError("Cannot download in offline mode.") + let downloadDir = if downloadPath == "": (getNimbleTempDir() / getDownloadDirName(url, verRange, vcsRevision)) diff --git a/src/nimblepkg/options.nim b/src/nimblepkg/options.nim index 675d4f8c..be042165 100644 --- a/src/nimblepkg/options.nim +++ b/src/nimblepkg/options.nim @@ -27,6 +27,7 @@ type pkgInfoCache*: TableRef[string, PackageInfo] showHelp*: bool showVersion*: bool + offline*: bool noColor*: bool disableValidation*: bool continueTestsOnFailure*: bool @@ -196,6 +197,7 @@ Nimble Options: --silent Hide all Nimble and Nim output --verbose Show all non-debug output. --debug Show all output including debug messages. + --offline Don't use network. --noColor Don't colorise output. --noSSLCheck Don't check SSL certificates. @@ -472,6 +474,7 @@ proc parseFlag*(flag, val: string, result: var Options, kind = cmdLongOption) = of "silent": result.verbosity = SilentPriority of "verbose": result.verbosity = LowPriority of "debug": result.verbosity = DebugPriority + of "offline": result.offline = true of "nocolor": result.noColor = true of "disablevalidation": result.disableValidation = true of "nim": result.nim = val diff --git a/tests/tnimblerefresh.nim b/tests/tnimblerefresh.nim index c03ef074..124a7542 100644 --- a/tests/tnimblerefresh.nim +++ b/tests/tnimblerefresh.nim @@ -7,6 +7,11 @@ import unittest, os, strutils import testscommon suite "nimble refresh": + test "cannot refresh in --offline mode": + let (output, exitCode) = execNimble(["--offline", "refresh"]) + check exitCode != QuitSuccess + check output.contains("Cannot refresh package list in offline mode.") + test "can refresh with default urls": let (output, exitCode) = execNimble(["refresh"]) checkpoint(output) diff --git a/tests/tuninstall.nim b/tests/tuninstall.nim index e5c8e619..6879f61e 100644 --- a/tests/tuninstall.nim +++ b/tests/tuninstall.nim @@ -11,6 +11,13 @@ from nimblepkg/common import cd from nimblepkg/version import newVersion suite "uninstall": + test "cannot install packagebin2 in --offline mode": + cleanDir(installDir) + let args = ["--offline", "install", pkgBin2Url] + let (output, exitCode) = execNimbleYes(args) + check exitCode != QuitSuccess + check output.contains("Cannot download in offline mode.") + test "can install packagebin2": cleanDir(installDir) let args = ["install", pkgBin2Url]