Repository: conan-io/conan
Pull request #2778 (2018-04-19 07:57:26)

moving graph files




Patch:
diff --git a/conans/client/command.py b/conans/client/command.py
index a8dabf78c..19513161d 100644
--- a/conans/client/command.py
+++ b/conans/client/command.py
@@ -18,11 +18,11 @@ from conans.util.files import exception_message_safe
 
 class Extender(argparse.Action):
     """Allows to use the same flag several times in a command and creates a list with the values.
-       For example:
-           conan install MyPackage/1.2@user/channel -o qt:value -o mode:2 -s cucumber:true
-           It creates:
-           options = ['qt:value', 'mode:2']
-           settings = ['cucumber:true']
+    For example:
+        conan install MyPackage/1.2@user/channel -o qt:value -o mode:2 -s cucumber:true
+      It creates:
+          options = ['qt:value', 'mode:2']
+          settings = ['cucumber:true']
     """
     def __call__(self, parser, namespace, values, option_strings=None):  # @UnusedVariable
         # Need None here incase `argparse.SUPPRESS` was supplied for `dest`
@@ -46,23 +46,34 @@ class Extender(argparse.Action):
 
 class OnceArgument(argparse.Action):
     """Allows to declare a parameter that can have only one value, by default argparse takes the
-    latest declared and it's very confusing"""
+    latest declared and it's very confusing.
+    """
     def __call__(self, parser, namespace, values, option_string=None):
         if getattr(namespace, self.dest) is not None and self.default is None:
             msg = '{o} can only be specified once'.format(o=option_string)
             raise argparse.ArgumentError(None, msg)
         setattr(namespace, self.dest, values)
 
-
-_PATH_HELP = ("path to a folder containing a recipe (conanfile.py) "
-              "or to a recipe file, e.g., conan package folder/conanfile.py")
+_BUILD_FOLDER_HELP = ("Directory for the build process. Defaulted to the current directory. A "
+                      "relative path to current directory can also be specified")
+_INSTALL_FOLDER_HELP = ("Directory containing the conaninfo.txt and conanbuildinfo.txt files "
+                        "(from previous 'conan install'). Defaulted to --build-folder")
+_KEEP_SOURCE_HELP = ("Do not remove the source folder in local cache. Use this for testing purposes"
+                     " only")
+_PATTERN_OR_REFERENCE_HELP = ("Pattern or package recipe reference, e.g., 'boost/*', "
+                              "'MyPackage/1.2@user/channel'")
+_PATH_HELP = ("Path to a folder containing a conanfile.py or to a recipe file "
+              "e.g., my_folder/conanfile.py")
+_QUERY_HELP = ("Packages query: 'os=Windows AND (arch=x86 OR compiler=gcc)'. The "
+               "'pattern_or_reference' parameter has to be a reference: MyPackage/1.2@user/channel")
+_SOURCE_FOLDER_HELP = ("Directory containing the sources. Defaulted to the conanfile's directory. A"
+                       " relative path to current directory can also be specified")
 
 
 class Command(object):
-    """ A single command of the conan application, with all the first level commands.
-    Manages the parsing of parameters and delegates functionality in
-    collaborators.
-    It can also show help of the tool
+    """A single command of the conan application, with all the first level commands. Manages the
+    parsing of parameters and delegates functionality in collaborators. It can also show help of the
+    tool.
     """
     def __init__(self, conan_api, client_cache, user_io, outputer):
         assert isinstance(conan_api, Conan)
@@ -88,8 +99,8 @@ class Command(object):
             raise ConanException("Unknown command '%s'" % args.command)
 
     def new(self, *args):
-        """Creates a new package recipe template with a 'conanfile.py'.
-        And optionally, 'test_package' package testing files.
+        """Creates a new package recipe template with a 'conanfile.py' and optionally,
+        'test_package' testing files.
         """
         parser = argparse.ArgumentParser(description=self.new.__doc__, prog="conan new")
         parser.add_argument("name", help='Package name, e.g.: "Poco/1.7.3" or complete reference'
@@ -148,24 +159,20 @@ class Command(object):
                         gitlab_clang_versions=args.ci_gitlab_clang)
 
     def test(self, *args):
-        """ Test a package, consuming it with a conanfile recipe with a test() method.
-        This command installs the conanfile dependencies (including the tested
-        package), calls a "conan build" to build test apps, and finally executes
-        the test() method.
-        The testing recipe is not a package, does not require name/version,
-        neither define package() or package_info() methods.
-        The package to be tested must exist in the local cache or any configured remote.
-        To create and test a binary package use the 'conan create' command.
+        """Test a package consuming it from a conanfile.py with a test() method. This command
+        installs the conanfile dependencies (including the tested package), calls a 'conan build' to
+        build test apps and finally executes the test() method. The testing recipe does not require
+        name or version, neither definition of package() or package_info() methods. The package to
+        be tested must exist in the local cache or in any configured remote.
         """
         parser = argparse.ArgumentParser(description=self.test.__doc__, prog="conan test")
-        parser.add_argument("-tbf", "--test-build-folder", action=OnceArgument,
-                            help="Optional. Working directory of the build process.")
-        parser.add_argument("path", help='path to the "testing" folder containing a recipe '
-                            '(conanfile.py) with a test() method or to a recipe file, '
+        parser.add_argument("path", help='Path to the "testing" folder containing a conanfile.py or'
+                            ' to a recipe file with test() method'
                             'e.g. conan test_package/conanfile.py pkg/version@user/channel')
         parser.add_argument("reference",
-                            help='a full package reference pkg/version@user/channel, of the '
-                            'package to be tested')
+                            help='pkg/version@user/channel of the package to be tested')
+        parser.add_argument("-tbf", "--test-build-folder", action=OnceArgument,
+                            help="Working directory of the build process.")
 
         _add_common_install_arguments(parser, build_help=_help_build_policies)
         args = parser.parse_args(*args)
@@ -174,34 +181,31 @@ class Command(object):
                                 build_modes=args.build, test_build_folder=args.test_build_folder)
 
     def create(self, *args):
-        """ Builds a binary package for recipe (conanfile.py) located in current dir.
-        Uses the specified configuration in a profile or in -s settings, -o options etc.
-        If a 'test_package' folder (the name can be configured with -tf) is found, the command will
-        run the consumer project to ensure that the package has been created correctly. Check the
-        'conan test' command to know more about the 'test_folder' project.
+        """Builds a binary package for a recipe (conanfile.py). Uses the specified configuration in
+        a profile or in -s settings, -o options etc. If a 'test_package' folder (the name can be
+        configured with -tf) is found, the command will run the consumer project to ensure that the
+        package has been created correctly. Check 'conan test' command to know more about
+        'test_folder' project.
         """
-        parser = argparse.ArgumentParser(description=self.create.__doc__,
-                                         prog="conan create")
+        parser = argparse.ArgumentParser(description=self.create.__doc__, prog="conan create")
         parser.add_argument("path", help=_PATH_HELP)
-        parser.add_argument("reference", help='user/channel, or a full package reference'
-                                              ' (Pkg/version@user/channel), if name and version '
-                                              ' are not declared in the recipe (conanfile.py)')
-        parser.add_argument("-ne", "--not-export", default=False, action='store_true',
-                            help='Do not export the conanfile')
-        parser.add_argument("-tf", "--test-folder", action=OnceArgument,
-                            help='alternative test folder name, by default is "test_package". '
-                                 '"None" if test stage needs to be disabled')
-        parser.add_argument("-tbf", "--test-build-folder", action=OnceArgument,
-                            help='Optional. Working directory for the build of the test project.')
+        parser.add_argument("reference",
+                            help='user/channel or pkg/version@user/channel (if name and version not'
+                                 ' declared in conanfile.py) where the pacakage will be created')
+        parser.add_argument("-j", "--json", default=None, action=OnceArgument,
+                            help='json file path where the install information will be written to')
         parser.add_argument('-k', '-ks', '--keep-source', default=False, action='store_true',
-                            help='Optional. Do not remove the source folder in local cache. '
-                                 'Use for testing purposes only')
+                            help=_KEEP_SOURCE_HELP)
         parser.add_argument('-kb', '--keep-build', default=False, action='store_true',
-                            help='Optional. Do not remove the build folder in local cache. '
-                                 'Use for testing purposes only')
-        parser.add_argument("-j", "--json", default=None, action=OnceArgument,
-                            help='Path to a json file where the install information '
-                                 'will be written')
+                            help='Do not remove the build folder in local cache. Use this for '
+                                 'testing purposes only')
+        parser.add_argument("-ne", "--not-export", default=False, action='store_true',
+                            help='Do not export the conanfile.py')
+        parser.add_argument("-tbf", "--test-build-folder", action=OnceArgument,
+                            help='Working directory for the build of the test project.')
+        parser.add_argument("-tf", "--test-folder", action=OnceArgument,
+                            help='Alternative test folder name. By default it is "test_package". '
+                                 'Use "None" to skip the test stage')
 
         _add_manifests_arguments(parser)
         _add_common_install_arguments(parser, build_help=_help_build_policies)
@@ -229,17 +233,17 @@ class Command(object):
                 self._outputer.json_install(self._conan.recorder.get_install_info(), args.json, cwd)
 
     def download(self, *args):
-        """Downloads recipe and binaries to the local cache, without using settings.
-         It works specifying the recipe reference and package ID to be installed.
-         Not transitive, requirements of the specified reference will be retrieved.
-         Useful together with 'conan copy' to automate the promotion of
-         packages to a different user/channel. If only a reference is specified, it will download
-         all packages in the specified remote.
-         If no remote is specified will search sequentially in the available configured remotes."""
+        """Downloads recipe and binaries to the local cache, without using settings. It works
+        specifying the recipe reference and package ID to be installed. Not transitive, requirements
+        of the specified reference will NOT be retrieved. Useful together with 'conan copy' to
+        automate the promotion of packages to a different user/channel. Only if a reference
+        is specified, it will download all packages from the specified remote. Otherwise, it will
+        search sequentially in the configured remotes.
+        """
 
         parser = argparse.ArgumentParser(description=self.download.__doc__, prog="conan download")
         parser.add_argument("reference",
-                            help='package recipe reference e.g., MyPackage/1.2@user/channel')
+                            help='pkg/version@user/channel')
         parser.add_argument("-p", "--package", nargs=1, action=Extender,
                             help='Force install specified package ID (ignore settings/options)')
         parser.add_argument("-r", "--remote", help='look in the specified remote server',
@@ -253,35 +257,32 @@ class Command(object):
                                     remote=args.remote, recipe=args.recipe)
 
     def install(self, *args):
-        """Installs the requirements specified in a conanfile (.py or .txt).
-           If any requirement is not found in the local cache it will retrieve the recipe from a
-           remote, looking for it sequentially in the available configured remotes.
-           When the recipes have been downloaded it will try to download a binary package matching
-           the specified settings, only from the remote from which the recipe was retrieved.
-           If no binary package is found you can build the package from sources using the '--build'
-           option.
-           When the package is installed, Conan will write the files for the specified generators.
-           It can also be used to install a concrete recipe/package specifying a reference in the
-           "path" parameter.
-
+        """Installs the requirements specified in a recipe (conanfile.py or conanfile.txt). It can
+        also be used to install a concrete package specifying a reference. If any requirement is not
+        found in the local cache, it will retrieve the recipe from a remote, looking for it
+        sequentially in the configured remotes. When the recipes have been downloaded it will try to
+        download a binary package matching the specified settings, only from the remote from which
+        the recipe was retrieved. If no binary package is found, it can be build from sources using
+        the '--build' option. When the package is installed, Conan will write the files for the
+        specified generators.
         """
         parser = argparse.ArgumentParser(description=self.install.__doc__, prog="conan install")
-        parser.add_argument("path", help="path to a folder containing a recipe"
+        parser.add_argument("path_or_reference", help="Path to a folder containing a recipe"
                             " (conanfile.py or conanfile.txt) or to a recipe file. e.g., "
                             "./my_project/conanfile.txt. It could also be a reference")
         parser.add_argument("-g", "--generator", nargs=1, action=Extender,
                             help='Generators to use')
         parser.add_argument("-if", "--install-folder", action=OnceArgument,
                             help='Use this directory as the directory where to put the generator'
-                                 'files, conaninfo/conanbuildinfo.txt etc.')
+                                 'files. e.g., conaninfo/conanbuildinfo.txt')
 
         _add_manifests_arguments(parser)
 
         parser.add_argument("--no-imports", action='store_true', default=False,
                             help='Install specified packages but avoid running imports')
         parser.add_argument("-j", "--json", default=None, action=OnceArgument,
-                            help='Path to a json file where the install information '
-                                 'will be written')
+                            help='Path to a json file where the install information will be '
+                            'written')
 
         _add_common_install_arguments(parser, build_help=_help_build_policies)
 
@@ -290,9 +291,9 @@ class Command(object):
 
         try:
             try:
-                reference = ConanFileReference.loads(args.path)
+                reference = ConanFileReference.loads(args.path_or_reference)
             except ConanException:
-                self._conan.install(path=args.path,
+                self._conan.install(path=args.path_or_reference,
                                     settings=args.settings, options=args.options,
                                     env=args.env,
                                     remote=args.remote,
@@ -318,22 +319,20 @@ class Command(object):
                 self._outputer.json_install(self._conan.recorder.get_install_info(), args.json, cwd)
 
     def config(self, *args):
-        """Manages configuration. Edits the conan.conf or installs config files.
+        """Manages Conan configuration. Edits the conan.conf or installs config files.
         """
         parser = argparse.ArgumentParser(description=self.config.__doc__, prog="conan config")
 
         subparsers = parser.add_subparsers(dest='subcommand', help='sub-command help')
-        rm_subparser = subparsers.add_parser('rm', help='rm an existing config element')
-        set_subparser = subparsers.add_parser('set', help='set/add value')
-        get_subparser = subparsers.add_parser('get', help='get the value of existing element')
-        install_subparser = subparsers.add_parser('install',
-                                                  help='install a full configuration from a zip '
-                                                       'file, local or remote')
-
-        rm_subparser.add_argument("item", help="item to remove")
-        get_subparser.add_argument("item", nargs="?", help="item to print")
-        set_subparser.add_argument("item", help="key=value to set")
-        install_subparser.add_argument("item", nargs="?", help="configuration file to use")
+        rm_subparser = subparsers.add_parser('rm', help='Remove an existing config element')
+        set_subparser = subparsers.add_parser('set', help='Set a value for a configuration item')
+        get_subparser = subparsers.add_parser('get', help='Get the value of configuration item')
+        install_subparser = subparsers.add_parser('install', help='install a full configuration '
+                                                                  'from a local or remote zip file')
+        rm_subparser.add_argument("item", help="Item to remove")
+        get_subparser.add_argument("item", nargs="?", help="Item to print")
+        set_subparser.add_argument("item", help="'item=value' to set")
+        install_subparser.add_argument("item", nargs="?", help="Configuration file to use")
 
         install_subparser.add_argument("--verify-ssl", nargs="?", default="True",
                                        help='Verify SSL connection when downloading file')
@@ -344,7 +343,7 @@ class Command(object):
             try:
                 key, value = args.item.split("=", 1)
             except ValueError:
-                raise ConanException("Please specify key=value")
+                raise ConanException("Please specify 'key=value'")
             return self._conan.config_set(key, value)
         elif args.subcommand == "get":
             return self._conan.config_get(args.item)
@@ -355,9 +354,8 @@ class Command(object):
             return self._conan.config_install(args.item, verify_ssl)
 
     def info(self, *args):
-        """Gets information about the dependency graph of a recipe.
-        You can use it for your current project, by passing a path to a conanfile.py as the
-        reference, or for any existing package in your local cache.
+        """Gets information about the dependency graph of a recipe. It can be used with a recipe
+        or a reference for any existing package in your local cache.
         """
 
         info_only_options = ["id", "build_id", "remote", "url", "license", "requires", "update",
@@ -367,25 +365,14 @@ class Command(object):
         str_only_options = ", ".join(['"%s"' % field for field in info_only_options])
 
         parser = argparse.ArgumentParser(description=self.info.__doc__, prog="conan info")
-        parser.add_argument("reference", help="path to a folder containing a recipe"
+        parser.add_argument("path_or_reference", help="Path to a folder containing a recipe"
                             " (conanfile.py or conanfile.txt) or to a recipe file. e.g., "
                             "./my_project/conanfile.txt. It could also be a reference")
-        parser.add_argument("-n", "--only", nargs=1, action=Extender,
-                            help='show the specified fields only from: '
-                                 '%s or use --paths with options %s. Use --only None to show only '
-                                 'references.'
-                                 % (str_only_options, str_path_only_options))
         parser.add_argument("--paths", action='store_true', default=False,
                             help='Show package paths in local cache')
-        parser.add_argument("--package-filter", nargs='?',
-                            help='print information only for packages that match the filter'
-                                 'e.g., MyPackage/1.2@user/channel or MyPackage*')
         parser.add_argument("-bo", "--build-order",
                             help='given a modified reference, return an ordered list to build (CI)',
                             nargs=1, action=Extender)
-        parser.add_argument("-j", "--json", nargs='?', const="1", type=str,
-                            help='Only with --build_order option, return the information in a json.'
-                                 ' e.j --json=/path/to/filename.json or --json to output the json')
         parser.add_argument("-g", "--graph", action=OnceArgument,
                             help='Creates file with project dependencies graph. It will generate '
                             'a DOT or HTML file depending on the filename extension')
@@ -395,9 +382,18 @@ class Command(object):
                             "current folder, unless --profile, -s or -o is specified. If you "
                             "specify both install-folder and any setting/option "
                             "it will raise an error.")
-        build_help = 'given a build policy (same install command "build" parameter), return an ' \
-                     'ordered list of  ' \
-                     'packages that would be built from sources in install command (simulation)'
+        parser.add_argument("-j", "--json", nargs='?', const="1", type=str,
+                            help='Only with --build_order option, return the information in a json.'
+                                 ' e.j --json=/path/to/filename.json or --json to output the json')
+        parser.add_argument("-n", "--only", nargs=1, action=Extender,
+                            help="Show only the specified fields: %s. '--paths' information can "
+                            "also be filtered with options %s. Use '--only None' to show only "
+                            "references." % (str_only_options, str_path_only_options))
+        parser.add_argument("--package-filter", nargs='?',
+                            help='Print information only for packages that match the filter pattern'
+                                 ' e.g., MyPackage/1.2@user/channel or MyPackage*')
+        build_help = ("Given a build policy, return an ordered list of packages that would be built"
+                      " from sources during the install command")
 
         _add_common_install_arguments(parser, build_help=build_help)
         args = parser.parse_args(*args)
@@ -408,7 +404,7 @@ class Command(object):
 
         # BUILD ORDER ONLY
         if args.build_order:
-            ret = self._conan.info_build_order(args.reference,
+            ret = self._conan.info_build_order(args.path_or_reference,
                                                settings=args.settings,
                                                options=args.options,
                                                env=args.env,
@@ -425,7 +421,7 @@ class Command(object):
 
         # INSTALL SIMULATION, NODES TO INSTALL
         elif args.build is not None:
-            nodes, _ = self._conan.info_nodes_to_build(args.reference,
+            nodes, _ = self._conan.info_nodes_to_build(args.path_or_reference,
                                                        build_modes=args.build,
                                                        settings=args.settings,
                                                        options=args.options,
@@ -438,7 +434,7 @@ class Command(object):
 
         # INFO ABOUT DEPS OF CURRENT PROJECT OR REFERENCE
         else:
-            data = self._conan.info_get_graph(args.reference,
+            data = self._conan.info_get_graph(args.path_or_reference,
                                               remote=args.remote,
                                               settings=args.settings,
                                               options=args.options,
@@ -465,21 +461,18 @@ class Command(object):
                                     args.package_filter, args.paths, project_reference)
 
     def source(self, *args):
-        """ Calls your local conanfile.py 'source()' method.
-            I.e., downloads and unzip the package source.
+        """ Calls your local conanfile.py 'source()' method. e.g., Downloads and unzip the package
+        sources.
         """
         parser = argparse.ArgumentParser(description=self.source.__doc__, prog="conan source")
         parser.add_argument("path", help=_PATH_HELP)
         parser.add_argument("-sf", "--source-folder", action=OnceArgument,
                             help='Destination directory. Defaulted to current directory')
         parser.add_argument("-if", "--install-folder", action=OnceArgument,
-                            help="Optional. Local folder containing the conaninfo.txt and "
-                            "conanbuildinfo.txt "
-                            "files (from a previous conan install execution). Defaulted to the "
-                            "current directory. Optional, source method will run without the "
-                            "information retrieved from the conaninfo.txt and conanbuildinfo.txt, "
-                            "only required when using conditional source() based on settings, "
-                            "options, env_info and user_info ")
+                            help=_INSTALL_FOLDER_HELP + " Optional, source method will run without "
+                            "the information retrieved from the conaninfo.txt and "
+                            "conanbuildinfo.txt, only required when using conditional source() "
+                            "based on settings, options, env_info and user_info")
         args = parser.parse_args(*args)
 
         try:
@@ -497,40 +490,34 @@ class Command(object):
         return self._conan.source(args.path, args.source_folder, args.install_folder)
 
     def build(self, *args):
-        """ Calls your local conanfile.py 'build()' method.
-        The recipe will be built in the local directory specified by --build-folder,
-        reading the sources from --source-folder. If you are using a build helper, like CMake(), the
+        """Calls your local conanfile.py 'build()' method.
+        The recipe will be built in the local directory specified by --build-folder, reading the
+        sources from --source-folder. If you are using a build helper, like CMake(), the
         --package-folder will be configured as destination folder for the install step.
         """
 
         parser = argparse.ArgumentParser(description=self.build.__doc__, prog="conan build")
         parser.add_argument("path", help=_PATH_HELP)
-        parser.add_argument("-sf", "--source-folder", action=OnceArgument,
-                            help="local folder containing the sources. Defaulted to the directory "
-                                 "of the conanfile. A relative path can also be specified "
-                                 "(relative to the current directory)")
-        parser.add_argument("-bf", "--build-folder", action=OnceArgument,
-                            help="build folder, working directory of the build process. Defaulted "
-                                 "to the current directory. A relative path can also be specified "
-                                 "(relative to the current directory)")
-        parser.add_argument("-pf", "--package-folder", action=OnceArgument,
-                            help="folder to install the package (when the build system or build() "
-                                 "method does it). Defaulted to the '{build_folder}/package' folder"
-                                 ". A relative path can be specified, relative to the current "
-                                 " folder. Also an absolute path is allowed.")
-        parser.add_argument("-if", "--install-folder", action=OnceArgument,
-                            help="Optional. Local folder containing the conaninfo.txt and "
-                                 "conanbuildinfo.txt files (from a previous conan install "
-                                 "execution). Defaulted to --build-folder")
+        parser.add_argument("-b", "--build", default=None, action="store_true",
+                            help="Execute the build step (variable should_build=True). When "
+                            "specified, configure/install won't run unless --configure/--install "
+                            "specified")
+        parser.add_argument("-bf", "--build-folder", action=OnceArgument, help=_BUILD_FOLDER_HELP)
         parser.add_argument("-c", "--configure", default=None, action="store_true",
                             help="Execute the configuration step (variable should_configure=True)."
                             " When specified, build/install won't run unless --build/--install specified")
-        parser.add_argument("-b", "--build", default=None, action="store_true",
-                            help="Execute the build step (variable should_build=True)."
-                            " When specified, configure/install won't run unless --configure/--install specified")
         parser.add_argument("-i", "--install", default=None, action="store_true",
-                            help="Execute the install step (variable should_install=True)."
-                            " When specified, configure/build won't run unless --configure/--build specified")
+                            help="Execute the install step (variable should_install=True). When "
+                            "specified, configure/build won't run unless --configure/--build "
+                            "specified")
+        parser.add_argument("-if", "--install-folder", action=OnceArgument,
+                            help=_INSTALL_FOLDER_HELP)
+        parser.add_argument("-pf", "--package-folder", action=OnceArgument,
+                            help="Directory to install the package (when the build system or build() "
+                                 "method does it). Defaulted to the '{build_folder}/package' folder"
+                                 ". A relative path can be specified, relative to the current "
+                                 " folder. Also an absolute path is allowed.")
+        parser.add_argument("-sf", "--source-folder", action=OnceArgument, help=_SOURCE_FOLDER_HELP)
         args = parser.parse_args(*args)
 
         if args.build or args.configure or args.install:
@@ -547,33 +534,23 @@ class Command(object):
                                  should_install=install)
 
     def package(self, *args):
-        """ Calls your local conanfile.py 'package()' method.
-
-        This command works locally, in the user space, and it will copy artifacts from the
-        --build-folder and --source-folder folder to the --package-folder one.
-
-        It won't create a new package in the local cache, if you want to do it, use 'create' or use
-        'export-pkg' after a 'build' command.
+        """ Calls your local conanfile.py 'package()' method. This command works in the user space
+        and it will copy artifacts from the --build-folder and --source-folder folder to the
+        --package-folder one.
+        It won't create a new package in the local cache, if you want to do it, use 'conan create'
+        or 'conan export-pkg' after a 'conan build' command.
         """
         parser = argparse.ArgumentParser(description=self.package.__doc__, prog="conan package")
         parser.add_argument("path", help=_PATH_HELP)
-        parser.add_argument("-sf", "--source-folder", action=OnceArgument,
-                            help="local folder containing the sources. Defaulted to the directory "
-                                 "of the conanfile. A relative path can also be specified "
-                                 "(relative to the current directory)")
-        parser.add_argument("-bf", "--build-folder", action=OnceArgument,
-                            help="build folder, working directory of the build process. Defaulted "
-                                 "to the current directory. A relative path can also be specified "
-                                 "(relative to the current directory)")
+        parser.add_argument("-bf", "--build-folder", action=OnceArgument, help=_BUILD_FOLDER_HELP)
+        parser.add_argument("-if", "--install-folder", action=OnceArgument,
+                            help=_INSTALL_FOLDER_HELP)
         parser.add_argument("-pf", "--package-folder", action=OnceArgument,
                             help="folder to install the package. Defaulted to the "
                                  "'{build_folder}/package' folder. A relative path can be specified"
                                  " (relative to the current directory). Also an absolute path"
                                  " is allowed.")
-        parser.add_argument("-if", "--install-folder", action=OnceArgument,
-                            help="Optional. Local folder containing the conaninfo.txt and "
-                                 "conanbuildinfo.txt files (from a previous conan install "
-                                 "execution). Defaulted to --build-folder ")
+        parser.add_argument("-sf", "--source-folder", action=OnceArgument, help=_SOURCE_FOLDER_HELP)
         args = parser.parse_args(*args)
         try:
             if "@" in args.path and ConanFileReference.loads(args.path):
@@ -602,16 +579,14 @@ class Command(object):
         """
         parser = argparse.ArgumentParser(description=self.imports.__doc__, prog="conan imports")
         parser.add_argument("path",
-                            help="path to a recipe (conanfile.py). e.g., ./my_project/"
-                            "With --undo option, this parameter is the folder "
+                            help=_PATH_HELP + " With --undo option, this parameter is the folder "
                             "containing the conan_imports_manifest.txt file generated in a previous"
                             "execution. e.j: conan imports ./imported_files --undo ")
+        parser.add_argument("-if", "--install-folder", action=OnceArgument,
+                            help=_INSTALL_FOLDER_HELP)
         parser.add_argument("-imf", "--import-folder", action=OnceArgument,
                             help="Directory to copy the artifacts to. By default it will be the"
                                  " current directory")
-        parser.add_argument("-if", "--install-folder", action=OnceArgument,
-                            help="local folder containing the conaninfo.txt and conanbuildinfo.txt "
-                                 "files (from a previous conan install execution)")
         parser.add_argument("-u", "--undo", default=False, action="store_true",
                             help="Undo imports. Remove imported files")
         args = parser.parse_args(*args)
@@ -621,58 +596,46 @@ class Command(object):
 
         try:
             if "@" in args.path and ConanFileReference.loads(args.path):
-                raise ArgumentError(None, "Parameter 'path' cannot be a reference,"
-                                          " but a folder containing a conanfile.py or conanfile.txt"
-                                          " file.")
+                raise ArgumentError(None, "Parameter 'path' cannot be a reference. Use a folder "
+                                          "containing a conanfile.py or conanfile.txt file.")
         except ConanException:
             pass
 
         return self._conan.imports(args.path, args.import_folder, args.install_folder)
 
     def export_pkg(self, *args):
-        """Exports a recipe & creates a package with given files calling 'package'.
-           It executes the package() method applied to the local folders '--source-folder' and
-           '--build-folder' and creates a new package in the local cache for the specified
-           'reference' and for the specified '--settings', '--options' and or '--profile'.
+        """Exports a recipe & creates a package with given files calling the package() method
+        applied to the local folders '--source-folder' and '--build-folder' and creates a new
+        package in the local cache for the specified 'reference' and for the specified '--settings',
+        '--options' and or '--profile'.
         """
         parser = argparse.ArgumentParser(description=self.export_pkg.__doc__,
-                                         prog="conan export-pkg .")
+                                         prog="conan export-pkg")
         parser.add_argument("path", help=_PATH_HELP)
-        parser.add_argument("reference", help='user/channel, or a full package reference'
-                                              ' (Pkg/version@user/channel), if name and version '
-                                              ' are not declared in the recipe (conanfile.py)')
-        parser.add_argument("-sf", "--source-folder", action=OnceArgument,
-                            help="local folder containing the sources. Defaulted to the directory "
-                                 "of the conanfile. A relative path can also be specified "
-                                 "(relative to the current directory)")
-        parser.add_argument("-bf", "--build-folder", action=OnceArgument,
-                            help="build folder, working directory of the build process. Defaulted "
-                                 "to the current directory. A relative path can also be specified "
-                                 "(relative to the current directory)")
-        parser.add_argument("-pf", "--package-folder", action=OnceArgument,
-                            help="folder containing a locally created package. "
-                                 "If a value is giving, it won't call the recipe 'package()' "
-                                 "method, and will run a copy of the provided folder.")
+        parser.add_argument("reference", help="user/channel or pkg/version@user/channel "
+                                              "(if name and version are not declared in the "
+                                              "conanfile.py)")
+        parser.add_argument("-bf", "--build-folder", action=OnceArgument, help=_BUILD_FOLDER_HELP)
+        parser.add_argument("-e", "--env", nargs=1, action=Extender,
+                            help='Environment variables that will be set during the package build, '
+                                 '-e CXX=/usr/bin/clang++')
+        parser.add_argument('-f', '--force', default=False, action='store_true',
+                            help='Overwrite existing package if existing')
         parser.add_argument("-if", "--install-folder", action=OnceArgument,
-                            help="local folder containing the conaninfo.txt and conanbuildinfo.txt "
-                            "files (from a previous conan install execution). Defaulted to "
-                            "--build-folder. If these files are found in the specified folder, "
-                            "they will be used, then if you specify --profile, -s, -o, --env, "
-                            "it will raise an error.")
+                            help=_INSTALL_FOLDER_HELP + " If these files are found in the specified"
+                            " folder and any of '-e', '-o', '-pr' or '-s' arguments are used, it "
+                            "will raise an error.")
+        parser.add_argument("-o", "--options", nargs=1, action=Extender,
+                            help='Define options values, e.g., -o pkg:with_qt=true')
         parser.add_argument("-pr", "--profile", action=OnceArgument,
                             help='Profile for this package')
-        parser.add_argument("-o", "--options",
-                            help='Define options values, e.g., -o Pkg:with_qt=true',
-                            nargs=1, action=Extender)
-        parser.add_argument("-s", "--settings",
-                            help='Define settings values, e.g., -s compiler=gcc',
-                            nargs=1, action=Extender)
-        parser.add_argument("-e", "--env",
-                            help='Environment variables that will be set during the package build, '
-                                 '-e CXX=/usr/bin/clang++',
-                            nargs=1, action=Extender)
-        parser.add_argument('-f', '--force', default=False,
-                            action='store_true', help='Overwrite existing package if existing')
+        parser.add_argument("-pf", "--package-folder", action=OnceArgument,
+                            help="folder containing a locally created package. If a value is given,"
+                                 " it won't call the recipe 'package()' method, and will run a copy"
+                                 " of the provided folder.")
+        parser.add_argument("-s", "--settings", nargs=1, action=Extender,
+                            help='Define settings values, e.g., -s compiler=gcc')
+        parser.add_argument("-sf", "--source-folder", action=OnceArgument, help=_SOURCE_FOLDER_HELP)
 
         args = parser.parse_args(*args)
         name, version, user, channel = get_reference_fields(args.reference)
@@ -693,19 +656,16 @@ class Command(object):
                                       channel=channel)
 
     def export(self, *args):
-        """ Copies the recipe (conanfile.py & associated files) to your local cache.
-        Use the 'reference' param to specify a user and channel where to export.
-        Once the recipe is in the local cache it can be shared and reused. It can be uploaded
-        to any remote with the "conan upload" command.
+        """Copies the recipe (conanfile.py & associated files) to your local cache. Use the
+        'reference' param to specify a user and channel where to export it. Once the recipe is in
+        the local cache it can be shared, reused and to any remote with the 'conan upload' command.
         """
         parser = argparse.ArgumentParser(description=self.export.__doc__, prog="conan export")
         parser.add_argument("path", help=_PATH_HELP)
-        parser.add_argument("reference", help='user/channel, or a full package reference'
-                                              ' (Pkg/version@user/channel), if name and version '
-                                              ' are not declared in the recipe (conanfile.py)')
+        parser.add_argument("reference", help="user/channel, or Pkg/version@user/channel (if name "
+                                              "and version are not declared in the conanfile.py")
         parser.add_argument('-k', '-ks', '--keep-source', default=False, action='store_true',
-                            help='Optional. Do not remove the source folder in the local cache. '
-                                 'Use for testing purposes only')
+                            help=_KEEP_SOURCE_HELP)
         args = parser.parse_args(*args)
         name, version, user, channel = get_reference_fields(args.reference)
 
@@ -714,38 +674,29 @@ class Command(object):
                                   keep_source=args.keep_source)
 
     def remove(self, *args):
-        """Removes packages or binaries matching pattern from local cache or remote.
-        It can also be used to remove temporary source or build folders in the local conan cache.
-        If no remote is specified, the removal will be done by default in the local conan cache.
+        """Removes packages or binaries matching pattern from local cache or remote. It can also be
+        used to remove temporary source or build folders in the local conan cache. If no remote is
+        specified, the removal will be done by default in the local conan cache.
         """
         parser = argparse.ArgumentParser(description=self.remove.__doc__, prog="conan remove")
-        parser.add_argument('pattern', help='Pattern name, e.g., openssl/*')
-        parser.add_argument('-p', '--packages',
-                            help='By default, remove all the packages or select one, '
-                                 'specifying the package ID',
-                            nargs="*", action=Extender)
-        parser.add_argument('-b', '--builds',
-                            help='By default, remove all the build folders or select one, '
-                                 'specifying the package ID',
-                            nargs="*", action=Extender)
-
+        parser.add_argument('pattern_or_reference', help=_PATTERN_OR_REFERENCE_HELP)
+        parser.add_argument('-b', '--builds', nargs="*", action=Extender,
+                            help=("By default, remove all the build folders or select one, "
+                                  "specifying the package ID"))
+        parser.add_argument('-f', '--force', default=False, action='store_true',
+                            help='Remove without requesting a confirmation')
+        parser.add_argument("-o", "--outdated", default=False, action="store_true",
+                            help="Remove only outdated from recipe packages")
+        parser.add_argument('-p', '--packages', nargs="*", action=Extender,
+                            help="Select package to remove specifying the package ID")
+        parser.add_argument('-q', '--query', default=None, action=OnceArgument, help=_QUERY_HELP)
+        parser.add_argument('-r', '--remote', action=OnceArgument,
+                            help='Will remove from the specified remote')
         parser.add_argument('-s', '--src', default=False, action="store_true",
                             help='Remove source folders')
-        parser.add_argument('-f', '--force', default=False,
-                            action='store_true', help='Remove without requesting a confirmation')
-        parser.add_argument('-r', '--remote', help='Will remove from the specified remote',
-                            action=OnceArgument)
-        parser.add_argument('-q', '--query', default=None, action=OnceArgument,
-                            help='Packages query: "os=Windows AND '
-                                 '(arch=x86 OR compiler=gcc)".'
-                                 ' The "pattern" parameter '
-                                 'has to be a package recipe '
-                                 'reference: MyPackage/1.2'
-                                 '@user/channel')
-        parser.add_argument("-o", "--outdated", help="Remove only outdated from recipe packages",
-                            default=False, action="store_true")
         args = parser.parse_args(*args)
-        reference = self._check_query_parameter_and_get_reference(args.pattern, args.query)
+        reference = self._check_query_parameter_and_get_reference(args.pattern_or_reference,
+                                                                  args.query)
 
         if args.packages is not None and args.query:
             raise ConanException("'-q' and '-p' parameters can't be used at the same time")
@@ -753,58 +704,54 @@ class Command(object):
         if args.builds is not None and args.query:
             raise ConanException("'-q' and '-b' parameters can't be used at the same time")
 
-        return self._conan.remove(pattern=reference or args.pattern, query=args.query,
+        return self._conan.remove(pattern=reference or args.pattern_or_reference, query=args.query,
                                   packages=args.packages, builds=args.builds, src=args.src,
                                   force=args.force, remote=args.remote, outdated=args.outdated)
 
     def copy(self, *args):
-        """ Copies conan recipes and packages to another user/channel.
-        Useful to promote packages (e.g. from "beta" to "stable").
-        Also for moving packages from one user to another.
+        """Copies conan recipes and packages to another user/channel. Useful to promote packages
+        (e.g. from "beta" to "stable") or transfer them from one user to another.
         """
         parser = argparse.ArgumentParser(description=self.copy.__doc__, prog="conan copy")
         parser.add_argument("reference", default="",
                             help='package reference. e.g., MyPackage/1.2@user/channel')
         parser.add_argument("user_channel", default="",
-                            help='Destination user/channel. '
-                            'e.g., lasote/testing')
+                            help='Destination user/channel. e.g., lasote/testing')
         parser.add_argument("-p", "--package", nargs=1, action=Extender,
                             help='copy specified package ID')
-        parser.add_argument("--all", action='store_true',
-                            default=False,
+        parser.add_argument("--all", action='store_true', default=False,
                             help='Copy all packages from the specified package recipe')
-        parser.add_argument("--force", action='store_true',
-                            default=False,
+        parser.add_argument("--force", action='store_true', default=False,
                             help='Override destination packages and the package recipe')
         args = parser.parse_args(*args)
+
         if args.all and args.package:
             raise ConanException("Cannot specify both --all and --package")
 
         return self._conan.copy(reference=args.reference, user_channel=args.user_channel,
-                                force=args.force,
-                                packages=args.package or args.all)
+                                force=args.force, packages=args.package or args.all)
 
     def user(self, *parameters):
-        """ Authenticates against a remote with user/pass, caching the auth token.
-        Useful to avoid the user and password being requested later.
-        e.g. while you're uploading a package.
-        You can have more than one user (one per remote). Changing the user, or introducing the
-        password is only necessary to upload packages to a remote.
+        """Authenticates against a remote with user/pass, caching the auth token. Useful to avoid
+        the user and password being requested later. e.g. while you're uploading a package.
+        You can have one user for each remote. Changing the user, or introducing the
+        password is only necessary to perform changes in remote packages.
         """
         parser = argparse.ArgumentParser(description=self.user.__doc__, prog="conan user")
         parser.add_argument("name", nargs='?', default=None,
-                            help='Username you want to use. '
-                                 'If no name is provided it will show the current user.')
-        parser.add_argument("-r", "--remote", help='look in the specified remote server',
-                            action=OnceArgument)
-        parser.add_argument('-c', '--clean', default=False,
-                            action='store_true', help='Remove user and tokens for all remotes')
+                            help='Username you want to use. If no name is provided it will show the'
+                            ' current user')
+        parser.add_argument('-c', '--clean', default=False, action='store_true',
+                            help='Remove user and tokens for all remotes')
         parser.add_argument("-p", "--password", nargs='?', const="", type=str,
                             action=OnceArgument,
                             help='User password. Use double quotes if password with spacing, '
                                  'and escape quotes if existing. If empty, the password is '
                                  'requested interactively (not exposed)')
+        parser.add_argument("-r", "--remote", help='Use the specified remote server',
+                            action=OnceArgument)
         args = parser.parse_args(*parameters)  # To enable -h
+
         if args.clean:
             return self._conan.users_clean()
         if args.password is None:
@@ -816,44 +763,34 @@ class Command(object):
                                         password=args.password)
 
     def search(self, *args):
-        """ Searches package recipes and binaries in the local cache or in a remote.
-
-        If you provide a pattern, then it will search for existing package recipes matching that pattern.
-        If a full and complete package reference is provided, like Pkg/0.1@user/channel, then the existing
-        binary packages for that reference will be displayed.
-        You can search in a remote or in the local cache, if nothing is specified, the local conan cache is
-        assumed.
-        Search is case sensitive, exact case has to be used. For case insensitive file systems, like Windows,
-        case sensitive search can be forced with the --case-sensitive argument
+        """Searches package recipes and binaries in the local cache or in a remote.
+
+        If you provide a pattern, then it will search for existing package recipes matching it.
+        If a full reference is provided (pkg/0.1@user/channel) then the existing binary packages for
+        that reference will be displayed.
+        If no remote is specified, the serach will be done in the local cache.
+        Search is case sensitive, exact case has to be used. For case insensitive file systems, like
+        Windows, case sensitive search can be forced with '--case-sensitive'.
         """
         parser = argparse.ArgumentParser(description=self.search.__doc__, prog="conan search")
-        parser.add_argument('pattern', nargs='?', help='Pattern name, e.g. openssl/* or package'
-                                                       ' recipe reference if "-q" is used. e.g. '
-                                                       'MyPackage/1.2@user/channel')
-        parser.add_argument('--case-sensitive', default=False,
-                            action='store_true', help='Make a case-sensitive search. '
-                                                      'Use it to guarantee case-sensitive '
-                            'search in Windows or other case-insensitive filesystems')
-        parser.add_argument('-r', '--remote', help='Remote origin. `all` searches all remotes', action=OnceArgument)
+        parser.add_argument('pattern_or_reference', nargs='?', help=_PATTERN_OR_REFERENCE_HELP)
+        parser.add_argument('-o', '--outdated', default=False, action='store_true',
+                            help='Show only outdated from recipe packages')
+        parser.add_argument('-q', '--query', default=None, action=OnceArgument, help=_QUERY_HELP)
+        parser.add_argument('-r', '--remote', action=OnceArgument,
+                            help="Remote to search in. '-r all' searches all remotes")
+        parser.add_argument('--case-sensitive', default=False, action='store_true',
+                            help='Make a case-sensitive search. Use it to guarantee case-sensitive '
+                            'search in Windows or other case-insensitive file systems')
         parser.add_argument('--raw', default=False, action='store_true',
                             help='Print just the list of recipes')
         parser.add_argument('--table', action=OnceArgument,
-                            help='Outputs html file with a table of binaries. Only valid if '
-                                 '"pattern" is a package recipe reference')
-        parser.add_argument('-q', '--query', default=None, action=OnceArgument,
-                            help='Packages query: "os=Windows AND '
-                                 '(arch=x86 OR compiler=gcc)".'
-                                 ' The "pattern" parameter '
-                                 'has to be a package recipe '
-                                 'reference: MyPackage/1.2'
-                                 '@user/channel'),
-
-        parser.add_argument('-o', '--outdated', default=False, action='store_true',
-                            help='Show only outdated from recipe packages')
+                            help="Outputs html file with a table of binaries. Only valid for a "
+                            "reference search")
         args = parser.parse_args(*args)
 
         try:
-            reference = ConanFileReference.loads(args.pattern)
+            reference = ConanFileReference.loads(args.pattern_or_reference)
             if "*" in reference:
                 # Fixes a version with only a wilcard (valid reference) but not real reference
                 # e.j: conan search lib/*@lasote/stable
@@ -869,112 +806,94 @@ class Command(object):
                                                  packages_query, args.table)
         else:
             if args.table:
-                raise ConanException("'--table' argument can only be used with a "
-                                     "reference in the 'pattern' argument")
+                raise ConanException("'--table' argument can only be used with a reference")
 
-            refs = self._conan.search_recipes(args.pattern, remote=args.remote,
+            refs = self._conan.search_recipes(args.pattern_or_reference, remote=args.remote,
                                               case_sensitive=args.case_sensitive)
-            self._check_query_parameter_and_get_reference(args.pattern, args.query)
-            self._outputer.print_search_references(refs, args.pattern, args.raw)
+            self._check_query_parameter_and_get_reference(args.pattern_or_reference, args.query)
+            self._outputer.print_search_references(refs, args.pattern_or_reference, args.raw)
 
     def upload(self, *args):
-        """ Uploads a recipe and binary packages to a remote.
-
-            If you use the --force variable, it won't check the package date. It will override
-            the remote with the local package.
-            If you use a pattern instead of a conan recipe reference you can use the -c or
-            --confirm option to upload all the matching recipes.
-            If you use the --retry option you can specify how many times should conan try to upload
-            the packages in case of failure. The default is 2.
-            With --retry_wait you can specify the seconds to wait between upload attempts.
-            If no remote is specified, the first configured remote (by default conan-center, use
-            'conan remote list' to list the remotes) will be used.
+        """Uploads a recipe and binary packages to a remote.
+        If no remote is specified, the first configured remote (by default conan-center, use
+        'conan remote list' to list the remotes) will be used.
         """
         parser = argparse.ArgumentParser(description=self.upload.__doc__,
                                          prog="conan upload")
-        parser.add_argument('pattern', help='Pattern or package recipe reference, '
-                                            'e.g., "openssl/*", "MyPackage/1.2@user/channel"')
-        parser.add_argument("-p", "--package", default=None, help='package ID to upload',
-                            action=OnceArgument)
-        parser.add_argument("-r", "--remote", help='upload to this specific remote',
-                            action=OnceArgument)
-        parser.add_argument("--all", action='store_true',
-                            default=False, help='Upload both package recipe and packages')
-        parser.add_argument("--skip-upload", action='store_true',
-                            default=False, help='Do not upload anything, just run '
-                                                'the checks and the compression.')
-        parser.add_argument("--force", action='store_true',
-                            default=False,
+        parser.add_argument('pattern_or_reference', help=_PATTERN_OR_REFERENCE_HELP)
+        parser.add_argument("-p", "--package", default=None, action=OnceArgument,
+                            help='package ID to upload')
+        parser.add_argument("-r", "--remote", action=OnceArgument,
+                            help='upload to this specific remote')
+        parser.add_argument("--all", action='store_true', default=False,
+                            help='Upload both package recipe and packages')
+        parser.add_argument("--skip-upload", action='store_true', default=False,
+                            help='Do not upload anything, just run the checks and the compression')
+        parser.add_argument("--force", action='store_true', default=False,
                             help='Do not check conan recipe date, override remote with local')
-        parser.add_argument("--check", action='store_true',
-                            default=False,
+        parser.add_argument("--check", action='store_true', default=False,
                             help='Perform an integrity check, using the manifests, before upload')
-        parser.add_argument('-c', '--confirm', default=False,
-                            action='store_true',
-                            help='If pattern is given upload all matching recipes without '
-                                 'confirmation')
-        parser.add_argument('--retry', default=2, type=int,
-                            help='In case of fail retries to upload again the specified times',
-                            action=OnceArgument)
-        parser.add_argument('--retry-wait', default=5, type=int,
-                            help='Waits specified seconds before retry again',
-                            action=OnceArgument)
+        parser.add_argument('-c', '--confirm', default=False, action='store_true',
+                            help='Upload all matching recipes without confirmation')
+        parser.add_argument('--retry', default=2, type=int, action=OnceArgument,
+                            help="In case of fail retries to upload again the specified times. "
+                                 "Defaulted to 2")
+        parser.add_argument('--retry-wait', default=5, type=int, action=OnceArgument,
+                            help='Waits specified seconds before retry again')
         parser.add_argument("-no", "--no-overwrite", nargs="?", type=str, choices=["all", "recipe"],
-                            help="Uploads package only if recipe is the same as the remote one",
-                            action=OnceArgument, const="all")
+                            action=OnceArgument, const="all",
+                            help="Uploads package only if recipe is the same as the remote one")
 
         args = parser.parse_args(*args)
 
-        return self._conan.upload(pattern=args.pattern, package=args.package, remote=args.remote,
-                                  all_packages=args.all, force=args.force, confirm=args.confirm,
-                                  retry=args.retry, retry_wait=args.retry_wait,
-                                  skip_upload=args.skip_upload, integrity_check=args.check,
-                                  no_overwrite=args.no_overwrite)
+        return self._conan.upload(pattern=args.pattern_or_reference, package=args.package,
+                                  remote=args.remote, all_packages=args.all, force=args.force,
+                                  confirm=args.confirm, retry=args.retry,
+                                  retry_wait=args.retry_wait, skip_upload=args.skip_upload,
+                                  integrity_check=args.check, no_overwrite=args.no_overwrite)
 
     def remote(self, *args):
-        """ Manages the remote list and the package recipes associated to a remote.
+        """Manages the remote list and the package recipes associated to a remote.
         """
         parser = argparse.ArgumentParser(description=self.remote.__doc__, prog="conan remote")
         subparsers = parser.add_subparsers(dest='subcommand', help='sub-command help')
 
         # create the parser for the "a" command
-        subparsers.add_parser('list', help='list current remotes')
-        parser_add = subparsers.add_parser('add', help='add a remote')
-        parser_add.add_argument('remote', help='name of the remote')
-        parser_add.add_argument('url', help='url of the remote')
-        parser_add.add_argument('verify_ssl',
-                                help='Verify SSL certificated. Default True',
-                                default="True", nargs="?")
-        parser_add.add_argument("-i", "--insert", nargs="?", const=0, type=int,
-                                help="insert remote at specific index", action=OnceArgument)
-        parser_rm = subparsers.add_parser('remove', help='remove a remote')
-        parser_rm.add_argument('remote', help='name of the remote')
-        parser_upd = subparsers.add_parser('update', help='update the remote url')
-        parser_upd.add_argument('remote', help='name of the remote')
-        parser_upd.add_argument('url', help='url')
-        parser_upd.add_argument('verify_ssl',
-                                help='Verify SSL certificated. Default True',
-                                default="True", nargs="?")
-        parser_upd.add_argument("-i", "--insert", nargs="?", const=0, type=int,
-                                help="insert remote at specific index",
-                                action=OnceArgument)
-        parser_rename = subparsers.add_parser('rename', help='update the remote name')
-        parser_rename.add_argument('remote', help='the old remote name')
-        parser_rename.add_argument('new_remote', help='the new remote name')
+        subparsers.add_parser('list', help='List current remotes')
+        parser_add = subparsers.add_parser('add', help='Add a remote')
+        parser_add.add_argument('remote', help='Name of the remote')
+        parser_add.add_argument('url', help='URL of the remote')
+        parser_add.add_argument('verify_ssl', nargs="?", default="True",
+                                help='Verify SSL certificated. Default True')
+        parser_add.add_argument("-i", "--insert", nargs="?", const=0, type=int, action=OnceArgument,
+                                help="insert remote at specific index")
+        parser_rm = subparsers.add_parser('remove', help='Remove a remote')
+        parser_rm.add_argument('remote', help='Name of the remote')
+        parser_upd = subparsers.add_parser('update', help='Update the remote url')
+        parser_upd.add_argument('remote', help='Name of the remote')
+
+        parser_upd.add_argument('url', help='URL')
+        parser_upd.add_argument('verify_ssl', nargs="?", default="True",
+                                help='Verify SSL certificated. Default True')
+        parser_upd.add_argument("-i", "--insert", nargs="?", const=0, type=int, action=OnceArgument,
+                                help="Insert remote at specific index")
+        parser_rename = subparsers.add_parser('rename', help='Update the remote name')
+        parser_rename.add_argument('remote', help='The old remote name')
+        parser_rename.add_argument('new_remote', help='The new remote name')
 
         subparsers.add_parser('list_ref',
-                              help='list the package recipes and its associated remotes')
+                              help='List the package recipes and its associated remotes')
         parser_padd = subparsers.add_parser('add_ref',
-                                            help="associate a recipe's reference to a remote")
-        parser_padd.add_argument('reference', help='package recipe reference')
-        parser_padd.add_argument('remote', help='name of the remote')
+                                            help="Associate a recipe's reference to a remote")
+        parser_padd.add_argument('reference', help='Package recipe reference')
+        parser_padd.add_argument('remote', help='Name of the remote')
         parser_prm = subparsers.add_parser('remove_ref',
-                                           help="dissociate a recipe's reference and its remote")
-        parser_prm.add_argument('reference', help='package recipe reference')
-        parser_pupd = subparsers.add_parser('update_ref', help="update the remote associated "
-                                            "with a package recipe")
-        parser_pupd.add_argument('reference', help='package recipe reference')
-        parser_pupd.add_argument('remote', help='name of the remote')
+                                           help="Dissociate a recipe's reference and its remote")
+        parser_prm.add_argument('reference', help='Package recipe reference')
+        parser_pupd = subparsers.add_parser('update_ref', help="Update the remote associated with "
+                                            "a package recipe")
+        parser_pupd.add_argument('reference', help='Package recipe reference')
+        parser_pupd.add_argument('remote', help='Name of the remote')
         args = parser.parse_args(*args)
 
         reference = args.reference if hasattr(args, 'reference') else None
@@ -1018,30 +937,30 @@ class Command(object):
         # create the parser for the "profile" command
         subparsers.add_parser('list', help='List current profiles')
         parser_show = subparsers.add_parser('show', help='Show the values defined for a profile')
-        parser_show.add_argument('profile',  help="name of the profile in the '.conan/profiles' "
-                                                  "folder or path to a profile file")
+        parser_show.add_argument('profile', help="name of the profile in the '.conan/profiles' "
+                                                 "folder or path to a profile file")
 
         parser_new = subparsers.add_parser('new', help='Creates a new empty profile')
-        parser_new.add_argument('profile',  help="name for the profile in the '.conan/profiles' "
-                                                 "folder or path and name for a profile file")
-        parser_new.add_argument("--detect", action='store_true',
-                                default=False,
+        parser_new.add_argument('profile', help="Name for the profile in the '.conan/profiles' "
+                                                "folder or path and name for a profile file")
+        parser_new.add_argument("--detect", action='store_true', default=False,
                                 help='Autodetect settings and fill [settings] section')
 
         parser_update = subparsers.add_parser('update', help='Update a profile with desired value')
-        parser_update.add_argument('item', help='key="value to set", e.j: settings.compiler=gcc')
-        parser_update.add_argument('profile',  help="name of the profile in the '.conan/profiles' "
-                                                    "folder or path to a profile file")
+        parser_update.add_argument('item',
+                                   help="'item=value' to update. e.g., settings.compiler=gcc")
+        parser_update.add_argument('profile', help="Name of the profile in the '.conan/profiles' "
+                                                   "folder or path to a profile file")
 
         parser_get = subparsers.add_parser('get', help='Get a profile key')
-        parser_get.add_argument('item', help='key of the value to get, e.g: settings.compiler')
-        parser_get.add_argument('profile',  help="name of the profile in the '.conan/profiles' "
-                                                 "folder or path to a profile file")
+        parser_get.add_argument('item', help='Key of the value to get, e.g: settings.compiler')
+        parser_get.add_argument('profile', help="Name of the profile in the '.conan/profiles' "
+                                                "folder or path to a profile file")
 
         parser_remove = subparsers.add_parser('remove', help='Remove a profile key')
         parser_remove.add_argument('item', help='key, e.g: settings.compiler')
-        parser_remove.add_argument('profile',  help="name of the profile in the '.conan/profiles' "
-                                                    "folder or path to a profile file")
+        parser_remove.add_argument('profile', help="Name of the profile in the '.conan/profiles' "
+                                                   "folder or path to a profile file")
 
         args = parser.parse_args(*args)
 
@@ -1078,12 +997,12 @@ class Command(object):
                                  'conanfile if only a reference is specified and a conaninfo.txt '
                                  'file contents if the package is also specified',
                             default=None, nargs="?")
-        parser.add_argument("-p", "--package", default=None, help='package ID',
+        parser.add_argument("-p", "--package", default=None, help='Package ID',
                             action=OnceArgument)
-        parser.add_argument("-r", "--remote", help='Get from this specific remote',
-                            action=OnceArgument)
-        parser.add_argument("-raw", "--raw", help='Do not decorate the text', default=False,
-                            action='store_true')
+        parser.add_argument("-r", "--remote", action=OnceArgument,
+                            help='Get from this specific remote')
+        parser.add_argument("-raw", "--raw", action='store_true', default=False,
+                            help='Do not decorate the text')
         args = parser.parse_args(*args)
 
         ret, path = self._conan.get_path(args.reference, args.package, args.path, args.remote)
@@ -1095,11 +1014,10 @@ class Command(object):
         return
 
     def alias(self, *args):
-        """Creates and exports an 'alias package recipe'. An "alias" package is a
-        symbolic name (reference) for another package (target). When some
-        package depends on an alias, the target one will be retrieved and used
-        instead, so the alias reference, the symbolic name, does not appear
-        in the final dependency graph.
+        """Creates and exports an 'alias package recipe'. An "alias" package is a symbolic name
+        (reference) for another package (target). When some package depends on an alias, the target
+        one will be retrieved and used instead, so the alias reference, the symbolic name, does not
+        appear in the final dependency graph.
         """
         parser = argparse.ArgumentParser(description=self.alias.__doc__,
                                          prog="conan alias")
@@ -1110,7 +1028,7 @@ class Command(object):
         self._conan.export_alias(args.reference, args.target)
 
     def _show_help(self):
-        """ prints a summary of all commands
+        """Prints a summary of all commands
         """
         grps = [("Consumer commands", ("install", "config", "get", "info", "search")),
                 ("Creator commands", ("new", "create", "upload", "export", "export-pkg", "test")),
@@ -1254,25 +1172,23 @@ def _add_manifests_arguments(parser):
 
 
 def _add_common_install_arguments(parser, build_help):
-    parser.add_argument("-u", "--update", action='store_true', default=False,
-                        help="check updates exist from upstream remotes")
+    if build_help:
+        parser.add_argument("-b", "--build", action=Extender, nargs="?", help=build_help)
+
+    parser.add_argument("-e", "--env", nargs=1, action=Extender,
+                        help='Environment variables that will be set during the package build, '
+                             '-e CXX=/usr/bin/clang++')
+    parser.add_argument("-o", "--options", nargs=1, action=Extender,
+                        help='Define options values, e.g., -o Pkg:with_qt=true')
     parser.add_argument("-pr", "--profile", default=None, action=OnceArgument,
                         help='Apply the specified profile to the install command')
-    parser.add_argument("-r", "--remote", help='look in the specified remote server',
-                        action=OnceArgument)
-    parser.add_argument("-o", "--options",
-                        help='Define options values, e.g., -o Pkg:with_qt=true',
-                        nargs=1, action=Extender)
-    parser.add_argument("-s", "--settings",
+    parser.add_argument("-r", "--remote", action=OnceArgument,
+                        help='Look in the specified remote server')
+    parser.add_argument("-s", "--settings", nargs=1, action=Extender,
                         help='Settings to build the package, overwriting the defaults. e.g., '
-                             '-s compiler=gcc',
-                        nargs=1, action=Extender)
-    parser.add_argument("-e", "--env",
-                        help='Environment variables that will be set during the package build, '
-                             '-e CXX=/usr/bin/clang++',
-                        nargs=1, action=Extender)
-    if build_help:
-        parser.add_argument("-b", "--build", action=Extender, nargs="?", help=build_help)
+                             '-s compiler=gcc')
+    parser.add_argument("-u", "--update", action='store_true', default=False,
+                        help="Check updates exist from upstream remotes")
 
 
 _help_build_policies = '''Optional, use it to choose if you want to build from sources:
@@ -1286,8 +1202,8 @@ _help_build_policies = '''Optional, use it to choose if you want to build from s
                        Allows multiple --build parameters. 'pattern' is a fnmatch file pattern
                        of a package name.
 
-    Default behavior: If you don't specify anything, it will be similar to --build=never, but
-    package recipes can override it and decide to build with "build_policy"
+    Default behavior: If you don't specify anything, it will be similar to '--build=never', but
+    package recipes can override it with their 'build_policy' attribute in the conanfile.py.
 '''
 
 
diff --git a/conans/client/conan_api.py b/conans/client/conan_api.py
index 5f697710d..ac0cc3448 100644
--- a/conans/client/conan_api.py
+++ b/conans/client/conan_api.py
@@ -170,10 +170,10 @@ class ConanAPIV1(object):
             # Get the new command instance after migrations have been done
             requester = get_basic_requester(client_cache)
             _, _, remote_manager = ConanAPIV1.instance_remote_manager(
-                                                requester,
-                                                client_cache, user_io,
-                                                Version(client_version),
-                                                Version(MIN_SERVER_COMPATIBLE_VERSION))
+                requester,
+                client_cache, user_io,
+                Version(client_version),
+                Version(MIN_SERVER_COMPATIBLE_VERSION))
 
             # Adjust global tool variables
             set_global_instances(out, requester)
@@ -331,8 +331,6 @@ class ConanAPIV1(object):
                                   update=update,
                                   keep_build=keep_build)
 
-
-
     @api_method
     def export_pkg(self, conanfile_path, name, channel, source_folder=None, build_folder=None,
                    package_folder=None, install_folder=None, profile_name=None, settings=None,
diff --git a/conans/client/conan_command_output.py b/conans/client/conan_command_output.py
index 0b203cdd3..6c916f316 100644
--- a/conans/client/conan_command_output.py
+++ b/conans/client/conan_command_output.py
@@ -78,10 +78,10 @@ class CommandOutputer(object):
 
     def info_graph(self, graph_filename, deps_graph, project_reference, cwd):
         if graph_filename.endswith(".html"):
-            from conans.client.grapher import ConanHTMLGrapher
+            from conans.client.graph.grapher import ConanHTMLGrapher
             grapher = ConanHTMLGrapher(project_reference, deps_graph)
         else:
-            from conans.client.grapher import ConanGrapher
+            from conans.client.graph.grapher import ConanGrapher
             grapher = ConanGrapher(project_reference, deps_graph)
 
         cwd = os.path.abspath(cwd or os.getcwd())
@@ -95,7 +95,7 @@ class CommandOutputer(object):
 
     def print_search_packages(self, ordered_packages, pattern, recipe_hash, packages_query, table):
         if table:
-            from conans.client.grapher import html_binary_graph
+            from conans.client.graph.grapher import html_binary_graph
             html_binary_graph(pattern, ordered_packages, recipe_hash, table)
         else:
             printer = Printer(self.user_io.out)
diff --git a/conans/client/graph/__init__.py b/conans/client/graph/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/conans/client/build_requires.py b/conans/client/graph/build_requires.py
similarity index 100%
rename from conans/client/build_requires.py
rename to conans/client/graph/build_requires.py
diff --git a/conans/client/graph/graph.py b/conans/client/graph/graph.py
new file mode 100644
index 000000000..a51e7fd98
--- /dev/null
+++ b/conans/client/graph/graph.py
@@ -0,0 +1,235 @@
+from collections import namedtuple
+from conans.model.ref import PackageReference
+from conans.model.info import ConanInfo
+from conans.errors import conanfile_exception_formatter
+from collections import defaultdict
+
+
+class Node(namedtuple("Node", "conan_ref conanfile")):
+    """ The Node of the dependencies graph is defined by:
+    ref: ConanFileReference, if it is a user space one, user=channel=none
+    conanfile: the loaded conanfile object withs its values
+    """
+    def __repr__(self):
+        return repr(self.conanfile)
+
+    def __cmp__(self, other):
+        if other is None:
+            return -1
+        elif self.conan_ref is None:
+            return 0 if other.conan_ref is None else -1
+        elif other.conan_ref is None:
+            return 1
+
+        if self.conan_ref == other.conan_ref:
+            return 0
+        if self.conan_ref < other.conan_ref:
+            return -1
+
+        return 1
+
+    def __gt__(self, other):
+        return self.__cmp__(other) == 1
+
+    def __lt__(self, other):
+        return self.__cmp__(other) == -1
+
+    def __le__(self, other):
+        return self.__cmp__(other) in [0, -1]
+
+    def __ge__(self, other):
+        return self.__cmp__(other) in [0, 1]
+
+
+class DepsGraph(object):
+    """ DAG of dependencies
+    """
+    def __init__(self):
+        self.nodes = set()
+        self._neighbors = defaultdict(set)
+        self._inverse_neighbors = defaultdict(set)
+
+    def add_node(self, node):
+        self.nodes.add(node)
+
+    def add_edge(self, src, dst):
+        assert src in self.nodes and dst in self.nodes
+        self._neighbors[src].add(dst)
+        self._inverse_neighbors[dst].add(src)
+
+    def neighbors(self, node):
+        """ return all connected nodes (directionally) to the parameter one
+        """
+        return self._neighbors[node]
+
+    def inverse_neighbors(self, node):
+        """ return all the nodes which has param node has dependency
+        """
+        return self._inverse_neighbors[node]
+
+    def public_neighbors(self, node):
+        """ return nodes with direct reacheability by public dependencies
+        """
+        neighbors = self._neighbors[node]
+        _, conanfile = node
+
+        public_requires = [r.conan_reference for r in conanfile.requires.values() if not r.private]
+        result = [n for n in neighbors if n.conan_ref in public_requires]
+        return result
+
+    def propagate_info(self):
+        """ takes the exports from upper level and updates the imports
+        right now also the imports are propagated, but should be checked
+        E.g. Conan A, depends on B.  A=>B
+        B exports an include directory "my_dir", with root "/...../0123efe"
+        A imports are the exports of B, plus any other conans it depends on
+        A.imports.include_dirs = B.export.include_paths.
+        Note the difference, include_paths used to compute full paths as the user
+        defines export relative to its folder
+        """
+        ordered = self.by_levels()
+        for level in ordered:
+            for node in level:
+                _, conanfile = node
+                neighbors = self._neighbors[node]
+                direct_reqs = []  # of PackageReference
+                indirect_reqs = set()   # of PackageReference, avoid duplicates
+                for nref, nconan in neighbors:
+                    package_id = nconan.info.package_id()
+                    package_reference = PackageReference(nref, package_id)
+                    direct_reqs.append(package_reference)
+                    indirect_reqs.update(nconan.info.requires.refs())
+                    conanfile.options.propagate_downstream(nref, nconan.info.full_options)
+                    # Might be never used, but update original requirement, just in case
+                    conanfile.requires[nref.name].conan_reference = nref
+
+                # Make sure not duplicated
+                indirect_reqs.difference_update(direct_reqs)
+                # There might be options that are not upstream, backup them, might be
+                # for build-requires
+                conanfile.build_requires_options = conanfile.options.values
+                conanfile.options.clear_unused(indirect_reqs.union(direct_reqs))
+
+                conanfile.info = ConanInfo.create(conanfile.settings.values,
+                                                  conanfile.options.values,
+                                                  direct_reqs,
+                                                  indirect_reqs)
+
+                # Once we are done, call package_id() to narrow and change possible values
+                with conanfile_exception_formatter(str(conanfile), "package_id"):
+                    conanfile.package_id()
+        return ordered
+
+    def direct_requires(self):
+        nodes_by_level = self.inverse_levels()
+        open_nodes = nodes_by_level[1]
+        return open_nodes
+
+    def ordered_closure(self, node, flat):
+        closure = set()
+        current = self._neighbors[node]
+        while current:
+            new_current = set()
+            for n in current:
+                closure.add(n)
+                new_neighs = self.public_neighbors(n)
+                to_add = set(new_neighs).difference(current)
+                new_current.update(to_add)
+            current = new_current
+
+        result = [n for n in flat if n in closure]
+        return result
+
+    def public_closure(self, node):
+        closure = {}
+        current = self._neighbors[node]
+        while current:
+            new_current = set()
+            for n in current:
+                closure[n.conan_ref.name] = n
+                new_neighs = self.public_neighbors(n)
+                to_add = set(new_neighs).difference(current)
+                new_current.update(to_add)
+            current = new_current
+
+        return closure
+
+    def _inverse_closure(self, references):
+        closure = set()
+        current = [n for n in self.nodes if str(n.conan_ref) in references or "ALL" in references]
+        closure.update(current)
+        while current:
+            new_current = set()
+            for n in current:
+                closure.add(n)
+                new_neighs = self._inverse_neighbors[n]
+                to_add = set(new_neighs).difference(current)
+                new_current.update(to_add)
+            current = new_current
+        return closure
+
+    def build_order(self, references):
+        levels = self.inverse_levels()
+        closure = self._inverse_closure(references)
+        result = []
+        for level in reversed(levels):
+            new_level = [n.conan_ref for n in level if (n in closure and n.conan_ref)]
+            if new_level:
+                result.append(new_level)
+        return result
+
+    def by_levels(self):
+        return self._order_levels(self._neighbors)
+
+    def inverse_levels(self):
+        return self._order_levels(self._inverse_neighbors)
+
+    def _order_levels(self, neighbours):
+        """ order by node degree. The first level will be the one which nodes dont have
+        dependencies. Second level will be with nodes that only have dependencies to
+        first level nodes, and so on
+        return [[node1, node34], [node3], [node23, node8],...]
+        """
+        current_level = []
+        result = [current_level]
+        opened = self.nodes.copy()
+        while opened:
+            current = opened.copy()
+            for o in opened:
+                o_neighs = neighbours[o]
+                if not any(n in opened for n in o_neighs):
+                    current_level.append(o)
+                    current.discard(o)
+            current_level.sort()
+            # now initialize new level
+            opened = current
+            if opened:
+                current_level = []
+                result.append(current_level)
+
+        return result
+
+    def private_nodes(self, built_private_nodes):
+        """ computes a list of nodes living in the private zone of the deps graph,
+        together with the list of nodes that privately require it
+        """
+        closure = set()
+        nodes_by_level = self.by_levels()
+        open_nodes = nodes_by_level[-1]
+        closure.update(open_nodes)
+        while open_nodes:
+            new_open_nodes = set()
+            for node in open_nodes:
+                if node in built_private_nodes:
+                    neighbors = self.public_neighbors(node)
+                else:
+                    neighbors = self._neighbors[node]
+                new_open_nodes.update(set(neighbors).difference(closure))
+                closure.update(neighbors)
+            open_nodes = new_open_nodes
+
+        private_nodes = self.nodes.difference(closure)
+        result = []
+        for node in private_nodes:
+            result.append(node)
+        return result
diff --git a/conans/client/deps_builder.py b/conans/client/graph/graph_builder.py
similarity index 58%
rename from conans/client/deps_builder.py
rename to conans/client/graph/graph_builder.py
index 65aa8f9cb..db8dcc7e7 100644
--- a/conans/client/deps_builder.py
+++ b/conans/client/graph/graph_builder.py
@@ -1,246 +1,12 @@
-""" This module is responsible for computing the dependencies (graph) for a given entry
-point, which could be both a user conanfile or an installed one
-"""
+import time
+
 from conans.model.conan_file import get_env_context_manager
 from conans.model.requires import Requirements
-from collections import namedtuple
-from conans.model.ref import PackageReference, ConanFileReference
-from conans.model.info import ConanInfo
+from conans.model.ref import ConanFileReference
 from conans.errors import ConanException, conanfile_exception_formatter, ConanExceptionInUserConanfileMethod
 from conans.client.output import ScopedOutput
-import time
 from conans.util.log import logger
-from collections import defaultdict
-
-
-class Node(namedtuple("Node", "conan_ref conanfile")):
-    """ The Node of the dependencies graph is defined by:
-    ref: ConanFileReference, if it is a user space one, user=channel=none
-    conanfile: the loaded conanfile object withs its values
-    """
-    def __repr__(self):
-        return repr(self.conanfile)
-
-    def __cmp__(self, other):
-        if other is None:
-            return -1
-        elif self.conan_ref is None:
-            return 0 if other.conan_ref is None else -1
-        elif other.conan_ref is None:
-            return 1
-
-        if self.conan_ref == other.conan_ref:
-            return 0
-        if self.conan_ref < other.conan_ref:
-            return -1
-
-        return 1
-
-    def __gt__(self, other):
-        return self.__cmp__(other) == 1
-
-    def __lt__(self, other):
-        return self.__cmp__(other) == -1
-
-    def __le__(self, other):
-        return self.__cmp__(other) in [0, -1]
-
-    def __ge__(self, other):
-        return self.__cmp__(other) in [0, 1]
-
-
-class DepsGraph(object):
-    """ DAG of dependencies
-    """
-    def __init__(self):
-        self.nodes = set()
-        self._neighbors = defaultdict(set)
-        self._inverse_neighbors = defaultdict(set)
-
-    def add_node(self, node):
-        self.nodes.add(node)
-
-    def add_edge(self, src, dst):
-        assert src in self.nodes and dst in self.nodes
-        self._neighbors[src].add(dst)
-        self._inverse_neighbors[dst].add(src)
-
-    def neighbors(self, node):
-        """ return all connected nodes (directionally) to the parameter one
-        """
-        return self._neighbors[node]
-
-    def inverse_neighbors(self, node):
-        """ return all the nodes which has param node has dependency
-        """
-        return self._inverse_neighbors[node]
-
-    def public_neighbors(self, node):
-        """ return nodes with direct reacheability by public dependencies
-        """
-        neighbors = self._neighbors[node]
-        _, conanfile = node
-
-        public_requires = [r.conan_reference for r in conanfile.requires.values() if not r.private]
-        result = [n for n in neighbors if n.conan_ref in public_requires]
-        return result
-
-    def propagate_info(self):
-        """ takes the exports from upper level and updates the imports
-        right now also the imports are propagated, but should be checked
-        E.g. Conan A, depends on B.  A=>B
-        B exports an include directory "my_dir", with root "/...../0123efe"
-        A imports are the exports of B, plus any other conans it depends on
-        A.imports.include_dirs = B.export.include_paths.
-        Note the difference, include_paths used to compute full paths as the user
-        defines export relative to its folder
-        """
-        ordered = self.by_levels()
-        for level in ordered:
-            for node in level:
-                _, conanfile = node
-                neighbors = self._neighbors[node]
-                direct_reqs = []  # of PackageReference
-                indirect_reqs = set()   # of PackageReference, avoid duplicates
-                for nref, nconan in neighbors:
-                    package_id = nconan.info.package_id()
-                    package_reference = PackageReference(nref, package_id)
-                    direct_reqs.append(package_reference)
-                    indirect_reqs.update(nconan.info.requires.refs())
-                    conanfile.options.propagate_downstream(nref, nconan.info.full_options)
-                    # Might be never used, but update original requirement, just in case
-                    conanfile.requires[nref.name].conan_reference = nref
-
-                # Make sure not duplicated
-                indirect_reqs.difference_update(direct_reqs)
-                # There might be options that are not upstream, backup them, might be
-                # for build-requires
-                conanfile.build_requires_options = conanfile.options.values
-                conanfile.options.clear_unused(indirect_reqs.union(direct_reqs))
-
-                conanfile.info = ConanInfo.create(conanfile.settings.values,
-                                                  conanfile.options.values,
-                                                  direct_reqs,
-                                                  indirect_reqs)
-
-                # Once we are done, call package_id() to narrow and change possible values
-                with conanfile_exception_formatter(str(conanfile), "package_id"):
-                    conanfile.package_id()
-        return ordered
-
-    def direct_requires(self):
-        nodes_by_level = self.inverse_levels()
-        open_nodes = nodes_by_level[1]
-        return open_nodes
-
-    def ordered_closure(self, node, flat):
-        closure = set()
-        current = self._neighbors[node]
-        while current:
-            new_current = set()
-            for n in current:
-                closure.add(n)
-                new_neighs = self.public_neighbors(n)
-                to_add = set(new_neighs).difference(current)
-                new_current.update(to_add)
-            current = new_current
-
-        result = [n for n in flat if n in closure]
-        return result
-
-    def public_closure(self, node):
-        closure = {}
-        current = self._neighbors[node]
-        while current:
-            new_current = set()
-            for n in current:
-                closure[n.conan_ref.name] = n
-                new_neighs = self.public_neighbors(n)
-                to_add = set(new_neighs).difference(current)
-                new_current.update(to_add)
-            current = new_current
-
-        return closure
-
-    def _inverse_closure(self, references):
-        closure = set()
-        current = [n for n in self.nodes if str(n.conan_ref) in references or "ALL" in references]
-        closure.update(current)
-        while current:
-            new_current = set()
-            for n in current:
-                closure.add(n)
-                new_neighs = self._inverse_neighbors[n]
-                to_add = set(new_neighs).difference(current)
-                new_current.update(to_add)
-            current = new_current
-        return closure
-
-    def build_order(self, references):
-        levels = self.inverse_levels()
-        closure = self._inverse_closure(references)
-        result = []
-        for level in reversed(levels):
-            new_level = [n.conan_ref for n in level if (n in closure and n.conan_ref)]
-            if new_level:
-                result.append(new_level)
-        return result
-
-    def by_levels(self):
-        return self._order_levels(self._neighbors)
-
-    def inverse_levels(self):
-        return self._order_levels(self._inverse_neighbors)
-
-    def _order_levels(self, neighbours):
-        """ order by node degree. The first level will be the one which nodes dont have
-        dependencies. Second level will be with nodes that only have dependencies to
-        first level nodes, and so on
-        return [[node1, node34], [node3], [node23, node8],...]
-        """
-        current_level = []
-        result = [current_level]
-        opened = self.nodes.copy()
-        while opened:
-            current = opened.copy()
-            for o in opened:
-                o_neighs = neighbours[o]
-                if not any(n in opened for n in o_neighs):
-                    current_level.append(o)
-                    current.discard(o)
-            current_level.sort()
-            # now initialize new level
-            opened = current
-            if opened:
-                current_level = []
-                result.append(current_level)
-
-        return result
-
-    def private_nodes(self, built_private_nodes):
-        """ computes a list of nodes living in the private zone of the deps graph,
-        together with the list of nodes that privately require it
-        """
-        closure = set()
-        nodes_by_level = self.by_levels()
-        open_nodes = nodes_by_level[-1]
-        closure.update(open_nodes)
-        while open_nodes:
-            new_open_nodes = set()
-            for node in open_nodes:
-                if node in built_private_nodes:
-                    neighbors = self.public_neighbors(node)
-                else:
-                    neighbors = self._neighbors[node]
-                new_open_nodes.update(set(neighbors).difference(closure))
-                closure.update(neighbors)
-            open_nodes = new_open_nodes
-
-        private_nodes = self.nodes.difference(closure)
-        result = []
-        for node in private_nodes:
-            result.append(node)
-        return result
+from conans.client.graph.graph import DepsGraph, Node
 
 
 class DepsGraphBuilder(object):
diff --git a/conans/client/grapher.py b/conans/client/graph/grapher.py
similarity index 100%
rename from conans/client/grapher.py
rename to conans/client/graph/grapher.py
diff --git a/conans/client/require_resolver.py b/conans/client/graph/require_resolver.py
similarity index 100%
rename from conans/client/require_resolver.py
rename to conans/client/graph/require_resolver.py
diff --git a/conans/client/importer.py b/conans/client/importer.py
index 707630d2b..65ba05b24 100644
--- a/conans/client/importer.py
+++ b/conans/client/importer.py
@@ -62,6 +62,7 @@ def _report_save_manifest(copied_files, output, dest_folder, manifest_name):
         manifest = FileTreeManifest(date, file_dict)
         save(os.path.join(dest_folder, manifest_name), str(manifest))
 
+
 def _make_files_writable(file_names):
     if not get_env("CONAN_READ_ONLY_CACHE", False):
         return
@@ -69,6 +70,7 @@ def _make_files_writable(file_names):
     for file_name in file_names:
         os.chmod(file_name, os.stat(file_name).st_mode | stat.S_IWRITE)
 
+
 def run_imports(conanfile, dest_folder, output):
     if not hasattr(conanfile, "imports"):
         return []
diff --git a/conans/client/manager.py b/conans/client/manager.py
index 3d7e737f3..d80231622 100644
--- a/conans/client/manager.py
+++ b/conans/client/manager.py
@@ -3,10 +3,10 @@ import os
 from collections import Counter
 
 from conans.client import packager
-from conans.client.build_requires import BuildRequires
+from conans.client.graph.build_requires import BuildRequires
 from conans.client.client_cache import ClientCache
 from conans.client.cmd.export import cmd_export, _execute_export
-from conans.client.deps_builder import DepsGraphBuilder
+from conans.client.graph.graph_builder import DepsGraphBuilder
 from conans.client.generators import write_generators
 from conans.client.generators.text import TXTGenerator
 from conans.client.importer import run_imports, undo_imports, run_deploy
@@ -18,7 +18,7 @@ from conans.client.printer import Printer
 from conans.client.profile_loader import read_conaninfo_profile
 from conans.client.proxy import ConanProxy
 from conans.client.remover import ConanRemover
-from conans.client.require_resolver import RequireResolver
+from conans.client.graph.require_resolver import RequireResolver
 from conans.client.source import config_source_local
 from conans.client.tools import cross_building, get_cross_building_settings
 from conans.client.userio import UserIO


Test patch:
diff --git a/conans/test/command/config_test.py b/conans/test/command/config_test.py
index 2d6d64c77..16db9dd1b 100644
--- a/conans/test/command/config_test.py
+++ b/conans/test/command/config_test.py
@@ -43,8 +43,7 @@ class ConfigTest(unittest.TestCase):
 
         error = self.client.run('config set proxies.http:Value', ignore_error=True)
         self.assertTrue(error)
-        self.assertIn("Please specify key=value",
-                      self.client.user_io.out)
+        self.assertIn("Please specify 'key=value'", self.client.user_io.out)
 
     def define_test(self):
         self.client.run("config set general.fakeos=Linux")
diff --git a/conans/test/command/search_test.py b/conans/test/command/search_test.py
index a1b2f1065..d063d76a2 100644
--- a/conans/test/command/search_test.py
+++ b/conans/test/command/search_test.py
@@ -205,8 +205,8 @@ helloTest/1.4.10@fenix/stable""".format(remote)
 
     def search_html_table_with_no_reference_test(self):
         self.client.run("search Hello* --table=table.html", ignore_error=True)
-        self.assertIn("ERROR: '--table' argument can only be used with a reference in the 'pattern'"
-                      " argument", self.client.user_io.out)
+        self.assertIn("ERROR: '--table' argument can only be used with a reference",
+                      self.client.user_io.out)
 
     def recipe_pattern_search_test(self):
         self.client.run("search Hello*")
@@ -322,10 +322,10 @@ helloTest/1.4.10@fenix/stable""".format(remote)
                                    "WindowsPackageSHA"], remote)
 
             q = '(os="Linux" OR os=Windows) AND use_Qt=True'
-            self._assert_pkg_q(q, ["PlatformIndependantSHA",  "WindowsPackageSHA"], remote)
+            self._assert_pkg_q(q, ["PlatformIndependantSHA", "WindowsPackageSHA"], remote)
 
             q = '(os="Linux" OR os=Windows) AND use_Qt=True AND nonexistant_option=3'
-            self._assert_pkg_q(q, ["PlatformIndependantSHA",  "WindowsPackageSHA"], remote)
+            self._assert_pkg_q(q, ["PlatformIndependantSHA", "WindowsPackageSHA"], remote)
 
             q = '(os="Linux" OR os=Windows) AND use_Qt=True OR nonexistant_option=3'
             self._assert_pkg_q(q, ["PlatformIndependantSHA",
diff --git a/conans/test/functional/deps_graph_test.py b/conans/test/functional/deps_graph_test.py
index 38df51172..aec505c2c 100644
--- a/conans/test/functional/deps_graph_test.py
+++ b/conans/test/functional/deps_graph_test.py
@@ -1,5 +1,5 @@
 import unittest
-from conans.client.deps_builder import DepsGraph, Node
+from conans.client.graph.graph_builder import DepsGraph, Node
 from conans.model.ref import ConanFileReference
 from conans.model.conan_file import ConanFile
 from conans.model.settings import Settings
diff --git a/conans/test/model/transitive_reqs_test.py b/conans/test/model/transitive_reqs_test.py
index c045a588f..50c99ac62 100644
--- a/conans/test/model/transitive_reqs_test.py
+++ b/conans/test/model/transitive_reqs_test.py
@@ -5,7 +5,7 @@ from collections import namedtuple
 
 from conans.test.utils.tools import TestBufferConanOutput
 from conans.paths import CONANFILE
-from conans.client.deps_builder import DepsGraphBuilder
+from conans.client.graph.graph_builder import DepsGraphBuilder
 from conans.model.ref import ConanFileReference
 from conans.model.options import OptionsValues, option_not_exist_msg, option_wrong_value_msg
 from conans.client.loader import ConanFileLoader
diff --git a/conans/test/model/version_ranges_test.py b/conans/test/model/version_ranges_test.py
index 1388de0d2..d35a7c2d1 100644
--- a/conans/test/model/version_ranges_test.py
+++ b/conans/test/model/version_ranges_test.py
@@ -2,7 +2,7 @@ import unittest
 from conans.test.utils.tools import TestBufferConanOutput
 from conans.paths import CONANFILE
 import os
-from conans.client.deps_builder import DepsGraphBuilder
+from conans.client.graph.graph_builder import DepsGraphBuilder
 from conans.model.ref import ConanFileReference
 from conans.client.loader import ConanFileLoader
 from conans.util.files import save, list_folder_subdirs
@@ -10,7 +10,7 @@ from conans.model.settings import Settings
 from conans.model.requires import Requirements
 from conans.test.utils.test_files import temp_folder
 from collections import namedtuple
-from conans.client.require_resolver import RequireResolver, satisfying
+from conans.client.graph.require_resolver import RequireResolver, satisfying
 import re
 from parameterized import parameterized
 from conans.model.profile import Profile