diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -1,18 +1,47 @@
 # jenkinsPlugins2nix
 
 ```
-jenkinsPlugins2nix: PLUGIN_NAME{:PLUGIN_VERSION} [PLUGIN_NAME{:PLUGIN_VERSION} ...]
+Usage: jenkinsPlugins2nix [-r|--dependency-resolution [as-given|latest]]
+                          (-p|--plugin PLUGIN_NAME{:PLUGIN_VERSION})
+  Generate nix expressions for requested Jenkins plugins.
+
+Available options:
+  -r,--dependency-resolution [as-given|latest]
+                           Dependency resolution (default: latest)
+  -p,--plugin PLUGIN_NAME{:PLUGIN_VERSION}
+                           Plugins we should generate nix for. Latest version is
+                           used if not specified.
+  -h,--help                Show this help text
+
 ```
 
 Along with recent nixpkgs, you can then do the following.
 
 ```
-jenkinsPlugins2nix github-api > plugins.nix
+jenkinsPlugins2nix -p github-api > plugins.nix
 
 ```
 
 and in your `configuration.nix`:
 
 ```
-services.jenkins.plugins = pkgs.callPackage plugins.nix {};
+services.jenkins.plugins = import plugins.nix { inherit (pkgs) fetchurl stdenv; };
 ```
+
+## Version specification
+
+Care is taken to preserve versions of plugins explicitly specified by
+the user, even with the `as-given` resolution strategy. For example,
+if plugin `A` has a dependency `B:0.2` in its manifest file and we
+specify:
+
+```
+jenkins2nix -r latest -p A:0.7 -p B:0.1
+```
+
+We will end up with `A:0.7` and `B:0.2`. This also applies when no
+explicit version is provided which is equivalent to asking for the
+latest one.
+
+In case we only ask for `A`, the version of `B` will depend on
+`--resolution-strategy`.
diff --git a/app/Main.hs b/app/Main.hs
--- a/app/Main.hs
+++ b/app/Main.hs
@@ -1,48 +1,68 @@
 {-# LANGUAGE LambdaCase        #-}
 {-# LANGUAGE OverloadedStrings #-}
 -- |
--- Module    : Nix.JenkinsPlugins2Nix.Types
+-- Module    : Main
 -- Copyright : (c) 2017 Mateusz Kowalczyk
 -- License   : BSD3
 --
 -- @jenkinsPlugins2nix@ entry point.
 module Main (main) where
 
-import           Data.Monoid ((<>))
+import qualified Data.Bimap as Bimap
+import           Data.List (intersperse)
+import           Data.Monoid ((<>), mconcat)
 import qualified Data.Text as Text
 import           Nix.JenkinsPlugins2Nix
 import           Nix.JenkinsPlugins2Nix.Types
-import           System.Environment
+import qualified Options.Applicative as Opt
 import           System.Exit
 import           System.IO
 import qualified Text.PrettyPrint.ANSI.Leijen as Pretty
-
-usage :: Handle -> IO ()
-usage h = do
-  pName <- getProgName
-  hPutStrLn h $
-    pName <> ": PLUGIN_NAME{:PLUGIN_VERSION} [PLUGIN_NAME{:PLUGIN_VERSION} ...]"
+import           Text.Printf (printf)
 
 main :: IO ()
 main = do
-  getArgs >>= \case
-    [] -> do
-      usage stderr
+  config <- Opt.execParser opts
+  mkExprsFor config >>= \case
+    Left err -> do
+      hPutStrLn stderr err
       exitFailure
-    [v] | v == "-h" || v == "--help" -> do
-      usage stdout
+    Right p -> do
+      Pretty.putDoc p
       exitSuccess
-    plugins -> do
-      mkExprsFor (map parseRequestedPlugin plugins) >>= \case
-        Left err -> do
-          hPutStrLn stderr err
-          exitFailure
-        Right p -> do
-          Pretty.putDoc p
-          exitSuccess
   where
-    parseRequestedPlugin :: String -> RequestedPlugin
-    parseRequestedPlugin p = case break (== ':') p of
+    opts = Opt.info (parseConfig Opt.<**> Opt.helper)
+           ( Opt.fullDesc
+          <> Opt.progDesc "Generate nix expressions for requested Jenkins plugins." )
+
+
+parseConfig :: Opt.Parser Config
+parseConfig = Config
+  <$> Opt.option resolutionReader
+      ( Opt.long "dependency-resolution"
+     <> Opt.short 'r'
+     <> Opt.help "Dependency resolution"
+     <> Opt.showDefaultWith (resolutions Bimap.!)
+     <> Opt.metavar (printf "[%s]" . mconcat . intersperse "|" $ Bimap.keysR resolutions)
+     <> Opt.value Latest )
+  <*> Opt.some (Opt.option requestedPluginReader
+                ( Opt.metavar "PLUGIN_NAME{:PLUGIN_VERSION}"
+               <> Opt.long "plugin"
+               <> Opt.short 'p'
+               <> Opt.help "Plugins we should generate nix for. Latest version is used if not specified." )
+               )
+  where
+    resolutions :: Bimap.Bimap ResolutionStrategy String
+    resolutions = Bimap.fromList [(AsGiven, "as-given"), (Latest, "latest")]
+
+    resolutionReader :: Opt.ReadM ResolutionStrategy
+    resolutionReader = Opt.eitherReader $ \s -> case Bimap.lookupR s resolutions of
+      Nothing -> Left $ "Invalid dependency resolution, needs to be one of "
+                     <> show (Bimap.keysR resolutions)
+      Just v -> Right v
+
+    requestedPluginReader :: Opt.ReadM RequestedPlugin
+    requestedPluginReader = Opt.maybeReader $ \p -> Just $! case break (== ':') p of
       (n, ':' : ver) -> RequestedPlugin
         { requested_name = Text.pack n
         , requested_version = Just (Text.pack ver)
diff --git a/jenkinsPlugins2nix.cabal b/jenkinsPlugins2nix.cabal
--- a/jenkinsPlugins2nix.cabal
+++ b/jenkinsPlugins2nix.cabal
@@ -1,5 +1,5 @@
 name:                jenkinsPlugins2nix
-version:             0.1.0.0
+version:             0.2.0.0
 synopsis:            Generate nix for Jenkins plugins.
 description:         Generate nix for Jenkins plugins.
 homepage:            https://github.com/Fuuzetsu/jenkinsPlugins2nix#readme
@@ -39,7 +39,9 @@
   ghc-options:         -threaded -rtsopts -with-rtsopts=-N -Wall
   build-depends:       base
                      , ansi-wl-pprint
+                     , bimap
                      , jenkinsPlugins2nix
+                     , optparse-applicative
                      , text
   default-language:    Haskell2010
 
diff --git a/src/Nix/JenkinsPlugins2Nix.hs b/src/Nix/JenkinsPlugins2Nix.hs
--- a/src/Nix/JenkinsPlugins2Nix.hs
+++ b/src/Nix/JenkinsPlugins2Nix.hs
@@ -1,6 +1,6 @@
 {-# LANGUAGE OverloadedStrings #-}
 -- |
--- Module    : Nix.JenkinsPlugins2Nix.Types
+-- Module    : Nix.JenkinsPlugins2Nix
 -- Copyright : (c) 2017 Mateusz Kowalczyk
 -- License   : BSD3
 --
@@ -8,6 +8,7 @@
 module Nix.JenkinsPlugins2Nix where
 
 import qualified Codec.Archive.Zip as Zip
+import           Control.Arrow ((&&&))
 import           Control.Monad (foldM)
 import qualified Control.Monad.Except as MTL
 import qualified Crypto.Hash as Hash
@@ -66,27 +67,48 @@
         }
 
 -- | Download the given plugin as well as recursively download its dependencies.
-downloadPluginsRecursive :: Map Text Plugin -- ^ Already downloaded plugins.
-                         -> RequestedPlugin -- ^ Plugins we're asked to download.
-                         -> MTL.ExceptT String IO (Map Text Plugin)
-downloadPluginsRecursive m p = if Map.member (requested_name p) m
+downloadPluginsRecursive
+  :: ResolutionStrategy -- ^ Decide what version of dependencies to pick.
+  -> Map Text RequestedPlugin -- ^ Plugins user requested.
+  -> Map Text Plugin -- ^ Already downloaded plugins.
+  -> RequestedPlugin -- ^ Plugin we're going to download.
+  -> MTL.ExceptT String IO (Map Text Plugin)
+downloadPluginsRecursive strategy uPs m p = if Map.member (requested_name p) m
   then return m
   else do
-    plugin <- MTL.ExceptT $ downloadPlugin p
-    foldM (\m' p' -> downloadPluginsRecursive m' $
+        -- Adjust the requested plugin based on whether it was
+        -- specifically requested by the user and on resolution
+        -- strategy.
+    let adjustedPlugin = case Map.lookup (requested_name p) uPs of
+          -- This is not a user-requested plugin which means we have
+          -- to decide what version we're going to grab.
+          Nothing -> case strategy of
+            -- We're just going with whatever was in the manifest
+            -- file, i.e. the thing we passed in in the first place.
+            AsGiven -> p
+            -- It's not a user-specified plugin and we want the latest
+            -- version per strategy so download the latest one.
+            Latest -> p { requested_version = Nothing }
+          -- The user has asked for this plugin explicitly so use
+          -- their possibly-versioned request rather than picking
+          -- based on versions listed in manifest dependencies.
+          Just userPlugin -> userPlugin
+    plugin <- MTL.ExceptT $ downloadPlugin adjustedPlugin
+    foldM (\m' p' -> downloadPluginsRecursive strategy uPs m' $
               RequestedPlugin { requested_name = plugin_dependency_name p'
-                              , requested_version = Just $ plugin_dependency_version p'
+                              , requested_version = Just $! plugin_dependency_version p'
                               })
       (Map.insert (requested_name p) plugin m)
       (plugin_dependencies $ manifest plugin)
 
 -- | Pretty-print nix expression for all the given plugins and their
 -- dependencies that the user asked for.
-mkExprsFor :: [RequestedPlugin]
+mkExprsFor :: Config
            -> IO (Either String Pretty.Doc)
-mkExprsFor ps = do
+mkExprsFor (Config { resolution_strategy = st, requested_plugins = ps }) = do
   eplugins <- MTL.runExceptT $ do
-    plugins <- foldM downloadPluginsRecursive Map.empty ps
+    let userPlugins = Map.fromList $ map (requested_name &&& id) ps
+    plugins <- foldM (downloadPluginsRecursive st userPlugins) Map.empty ps
     return $ Map.elems plugins
   return $! case eplugins of
     Left err -> Left err
diff --git a/src/Nix/JenkinsPlugins2Nix/Parser.hs b/src/Nix/JenkinsPlugins2Nix/Parser.hs
--- a/src/Nix/JenkinsPlugins2Nix/Parser.hs
+++ b/src/Nix/JenkinsPlugins2Nix/Parser.hs
@@ -1,7 +1,7 @@
 {-# LANGUAGE LambdaCase        #-}
 {-# LANGUAGE OverloadedStrings #-}
 -- |
--- Module    : Nix.JenkinsPlugins2Nix.Types
+-- Module    : Nix.JenkinsPlugins2Nix.Parser
 -- Copyright : (c) 2017 Mateusz Kowalczyk
 -- License   : BSD3
 --
@@ -43,32 +43,21 @@
       eManifest :: Either String Manifest
       eManifest = do
         manifest_version' <- getKey "Manifest-Version"
-        archiver_version' <- either (\_ -> Right Nothing) (return . Just) $
-          getKey "Archiver-Version"
-        created_by' <- either (\_ -> Right Nothing) (return . Just) $
-          getKey "Created-By"
-        built_by' <- either (\_ -> Right Nothing) (return . Just) $
-          getKey "Built-By"
-        build_jdk' <- either (\_ -> Right Nothing) (return . Just) $
-          getKey "Build-Jdk"
-        extension_name' <- either (\_ -> Right Nothing) (return . Just) $
-          getKey "Extension-Name"
-        specification_title' <- either (\_ -> Right Nothing) (return . Just) $
-          getKey "Specification-Title"
-        implementation_title' <- either (\_ -> Right Nothing) (return . Just) $
-          getKey "Implementation-Title"
-        implementation_version' <- either (\_ -> Right Nothing) (return . Just) $
-          getKey "Implementation-Version"
-        group_id' <- either (\_ -> Right Nothing) (return . Just) $
-          getKey "Group-Id"
+        archiver_version' <- optional $ getKey "Archiver-Version"
+        created_by' <- optional $ getKey "Created-By"
+        built_by' <- optional $ getKey "Built-By"
+        build_jdk' <- optional $ getKey "Build-Jdk"
+        extension_name' <- optional $ getKey "Extension-Name"
+        specification_title' <- optional $ getKey "Specification-Title"
+        implementation_title' <- optional $ getKey "Implementation-Title"
+        implementation_version' <- optional $ getKey "Implementation-Version"
+        group_id' <- optional $ getKey "Group-Id"
         short_name' <- getKey "Short-Name"
         long_name' <- getKey "Long-Name"
         url' <- getKey "Url"
         plugin_version' <- getKey "Plugin-Version"
-        hudson_version' <- either (\_ -> Right Nothing) (return . Just) $
-          getKey "Hudson-Version"
-        jenkins_version' <- either (\_ -> Right Nothing) (return . Just) $
-          getKey "Jenkins-Version"
+        hudson_version' <- optional $ getKey "Hudson-Version"
+        jenkins_version' <- optional $ getKey "Jenkins-Version"
         plugin_dependencies' <- either (\_ -> Right Set.empty) return $
           getKeyParsing "Plugin-Dependencies" parsePluginDependencies
         plugin_developers' <- either (\_ -> Right Set.empty) return $
diff --git a/src/Nix/JenkinsPlugins2Nix/Types.hs b/src/Nix/JenkinsPlugins2Nix/Types.hs
--- a/src/Nix/JenkinsPlugins2Nix/Types.hs
+++ b/src/Nix/JenkinsPlugins2Nix/Types.hs
@@ -6,16 +6,36 @@
 --
 -- Types used through-out jenkinsPlugins2nix
 module Nix.JenkinsPlugins2Nix.Types
-  ( Manifest(..)
+  ( Config(..)
+  , Manifest(..)
   , Plugin(..)
   , PluginDependency(..)
   , PluginResolution(..)
   , RequestedPlugin(..)
+  , ResolutionStrategy(..)
   ) where
 
 import qualified Crypto.Hash as Hash
 import           Data.Set (Set)
 import           Data.Text (Text)
+
+-- | The way in which version of dependencies will be picked.
+data ResolutionStrategy =
+  -- | Pick the version of the dependency that the package tells us
+  -- about in its manifest file. If none, latest version available is
+  -- used.
+  AsGiven
+  -- | Always pick latest version of the dependency we're told about.
+  | Latest
+  deriving (Show, Eq, Ord)
+
+-- | Program configuration
+data Config = Config
+  { -- | Dependency resolution strategy
+    resolution_strategy :: !ResolutionStrategy
+    -- | User-required plugins.
+  , requested_plugins :: ![RequestedPlugin]
+  } deriving (Show, Eq, Ord)
 
 -- | Plugin that user requested on the command line.
 data RequestedPlugin = RequestedPlugin
