We cannot take the approach outlined below of detecting which remote repositories are "really" offline, since offline mode is more of a behavior, and this will lead to counter-intuitive results. A different feature may exist unimplemented, which is to detect when the network is down and provide better feedback for that case. However, when offline mode is declared, nothing earmarked as remote should be accessed, regardless of whether it is actually a physically local resource.
NOTE: One side-effect of this design change is that all offline-mode code can be isolated to maven-core, maven-plugin-descriptor, and [possibly] maven-artifact. Usage of maven-wagon will be determined by an offline-aware manager.
For the purposes of determining the areas sensitive to offline status, it is definitely useful to define what the offline state really means.
So, offline mode has several implications, some of which may not be altogether obvious:
The question remaining is: Which level of offline mode will we support? It seems reasonable to assume that users will be able to tell when localhost is not active (in most cases, localhost should be available, even if the rest of the network is not). Therefore, let's concentrate on the state where no network beyond localhost exists, and leave the more extreme state to users to diagnose and correct as necessary.
Offline mode is essential for breaking the requirement that m2 operate in a network-connected environment. It means legitimizing a development environment in which there is no network connection, and providing a robust m2 service offering in such circumstances. Introduction of offline mode allows m2 to anticipate the inevitable network failures that accompany being physically disconnected from the network, and adjust it's behavior accordingly.
It is more than simply understanding that m2 cannot go and check for the latest version of some snapshot artifact. If m2 is offline, SCM operations cannot succeed; no artifact downloads can take place, regardless of whether they are snapshot versions; artifact deployment cannot take place; certain types of tests cannot be setup, since the container used to run them cannot be reached or started.
All of these operations will produce their own unique errors in the absence of a coordinated offline strategy. In addition, efforts to unite these failing behaviors behind a consistent user interface is much, much more difficult if the system can't tell whether it has access to the network required by these operations.
Offline mode really means anticipating a lack of network connectivity, and as a result turning off certain services provided by m2 and providing a coherent way of predicting and reporting when network-related failures will take place. It means warning users that since the network is missing, certain features and operations will be unavailable, rather than simply waiting for those operations to fail, then trying to help users decipher the error messages they get as a result.
The concept of deployment is dependent on the availability of a some remote repository. Just as above, if that repository is not using file:// (which is highly likely to be the case), or the repository is not on a local filesystem, deployment will fail when offline.
This can be a problem if the tests are more than simple unit tests; that is, if they require configuration of a server process, and subsequent testing in-container.
Since we're only going to concern ourselves with states where localhost is still active, we only need to worry about this case when the server container is not installed on localhost. This allows the popular pattern of starting a server container in-JVM, running tests against it, and shutting it down.
Parts of Wagon will continue to function normally. These include:
It is not possible to determine whether a file-based location will be available except on a case-by-case basis (or a root-url by root-url basis). We may want to move the offline sensitivity entirely to Maven-Artifact, below, so we can be smarter about testing filesystem-based repositories, etc.
This is wholly dependent on Maven-Wagon, above.
We could possibly use a flag on a particular Wagon to see whether it supports offline mode, and then test to see if the file-based basedir for an artifact repository works...if it doesn't work, we can mark that repository offline...
OTOH, all offline-mode checks can probably be run from Wagon-based APIs.
In all but trivial examples, SCM operations cannot complete without having access to the versioning server. Therefore, it is assumed that any SCM-related activity will be unavailable when m2 is in offline mode.
We'll examine the different parts of maven-core on a case-by-case basis, below:
When binding goals to the project's configured lifecycle, each mojo descriptor should declare whether it requires online/offline status. This value should be a java.lang.Boolean, so it can implement 3VL (three value logic: yes, no, don't-care). The requiresOnline field in the mojo descriptor has the following semantics:
The majority of mojos will leave the requiresOnline == false, since online/offline status will be irrelevant, provided they have access to their required artifacts and other classpath elements. In the case of required artifacts and other classpath elements, this is assumed by the mojo API to be in a correct state, and will be handled by the Wagon modifications.
Offline status should be indicated in the MavenSettings instance, since it can conceivably be set from either the settings.xml or the command-line.
In the event the '-o' switch is the impetus for setting offline mode, this should result in modification of the active profile in the MavenSettings instance, just as definition of the active profile from the command-line should result in similar modification. This object is not meant to be static within the build process, but rather to be setup as an aggregation of all settings-related information passed into the system.
Find the control point for m2 using maven-wagon. At this point, inject a offline status parameter which is used when retrieving the specific Wagon.
If offline == true:
Retrieve the file or base-url file to be "downloaded".
When binding a mojo to the project's lifecycle instance, check the mojo descriptor's requiredConnectivity field.
In this case, the client is offline, and the mojo does not require online status.
In this case, the client is online, and the mojo either requires online status, or else doesn't care.
NOTE: Do we want to fail when we cannot bind a mojo to the lifecycle because of offline/online status? That would probably indicate that the user was trying to do something they cannot succeed at for now...so we probably should throw an exception in this case.