Repository: ESMCI/cime

Issue:
preview_namelists should give helpful error message if you haven't already run case.setup
Currently you get a cryptic error message if you run preview_namelists without first running case.setup.

It should simply say something like, "You need to run case.setup first"


Discussion:

Resolving patch:
diff --git a/utils/python/CIME/XML/machines.py b/utils/python/CIME/XML/machines.py
--- a/utils/python/CIME/XML/machines.py
+++ b/utils/python/CIME/XML/machines.py
@@ -35,15 +35,15 @@ def __init__(self, infile=None, files=None, machine=None):
 
         # Append the contents of $HOME/.cime/config_machines.xml if it exists
         # This could cause problems if node matchs are repeated when only one is expected
-        infile = os.path.join(os.environ.get("HOME"),".cime","config_machines.xml")
-        logger.debug("Infile: %s" , infile)
-        if os.path.exists(infile):
-            GenericXML.read(self, infile)
+        local_infile = os.path.join(os.environ.get("HOME"),".cime","config_machines.xml")
+        logger.debug("Infile: %s" , local_infile)
+        if os.path.exists(local_infile):
+            GenericXML.read(self, local_infile)
 
         if machine is None:
             machine = self.probe_machine_name()
 
-        expect(machine is not None, "Could not initialize machine object")
+        expect(machine is not None, "Could not initialize machine object from %s or %s"%(infile, local_infile))
         self.set_machine(machine)
 
     def get_machines_dir(self):
diff --git a/utils/python/CIME/buildnml.py b/utils/python/CIME/buildnml.py
--- a/utils/python/CIME/buildnml.py
+++ b/utils/python/CIME/buildnml.py
@@ -6,7 +6,6 @@
 
 from CIME.XML.standard_module_setup import *
 from CIME.utils import expect, handle_standard_logging_options, setup_standard_logging_options
-from CIME.case import Case
 import sys, os, argparse, doctest
 
 logger = logging.getLogger(__name__)
@@ -33,22 +32,22 @@ def parse_input(argv):
     return args.caseroot
 
 ###############################################################################
-def build_xcpl_nml(argv, compclass):
+#pylint: disable=unused-argument
+def build_xcpl_nml(case, caseroot, compname):
 ###############################################################################
-
-    caseroot = parse_input(argv)
-
-    compname = "x" + compclass
-
-    caseroot = parse_input(argv)
-
-    with Case(caseroot) as case:
-        rundir = case.get_value("RUNDIR")
-        ninst  = case.get_value("NINST_%s" % compclass.upper())
-        nx     = case.get_value("%s_NX" % compclass.upper())
-        ny     = case.get_value("%s_NY" % compclass.upper())
-        if compname == "xrof":
-            flood_mode = case.get_value('XROF_FLOOD_MODE')
+    compclasses = case.get_values("COMP_CLASSES")
+    compclass = None
+    for compclass in compclasses:
+        if case.get_value("COMP_%s"%compclass) == compname:
+            break
+    expect(compclass is not None,
+           "Could not identify compclass for compname %s"%compname)
+    rundir = case.get_value("RUNDIR")
+    ninst  = case.get_value("NINST_%s" % compclass.upper())
+    nx     = case.get_value("%s_NX" % compclass.upper())
+    ny     = case.get_value("%s_NY" % compclass.upper())
+    if compname == "xrof":
+        flood_mode = case.get_value('XROF_FLOOD_MODE')
 
     extras = []
     dtype = 1
diff --git a/utils/python/CIME/preview_namelists.py b/utils/python/CIME/preview_namelists.py
--- a/utils/python/CIME/preview_namelists.py
+++ b/utils/python/CIME/preview_namelists.py
@@ -4,7 +4,7 @@
 
 from CIME.XML.standard_module_setup import *
 
-import glob, shutil
+import glob, shutil, imp
 logger = logging.getLogger(__name__)
 
 def create_dirs(case):
@@ -60,8 +60,20 @@ def create_namelists(case):
         model_str = model.lower()
         config_file = case.get_value("CONFIG_%s_FILE" % model_str.upper())
         config_dir = os.path.dirname(config_file)
-        cmd = os.path.join(config_dir, "buildnml")
-        run_cmd_no_fail("%s %s" % (cmd, caseroot), verbose=True)
+        if model_str == "drv":
+            compname = "drv"
+        else:
+            compname = case.get_value("COMP_%s" % model_str.upper())
+        try:
+            mod = imp.load_source("buildnml",
+                                  os.path.join(config_dir, "buildnml"))
+            logger.info("Calling %s buildnml"%compname)
+            mod.buildnml(case, caseroot, compname)
+        except AttributeError:
+            cmd = os.path.join(config_dir, "buildnml")
+            run_cmd_no_fail("%s %s" % (cmd, caseroot), verbose=True)
+        except:
+            raise
 
     # refresh case xml object from file
     case.read_xml()


Test patch:
diff --git a/utils/python/tests/scripts_regression_tests.py b/utils/python/tests/scripts_regression_tests.py
--- a/utils/python/tests/scripts_regression_tests.py
+++ b/utils/python/tests/scripts_regression_tests.py
@@ -1889,6 +1889,8 @@ def _main_func():
                                         from_dir=cimeroot).splitlines())
         #TODO - get rid of this
         list_of_directories_to_ignore = ("xmlconvertors", "pointclm", "point_clm", "tools", "machines", "apidocs", "unit_test")
+        testnames = []
+        cnt = 0
         for file_ in files_to_test:
             # Dont test template files
             test_this = True
@@ -1898,7 +1900,14 @@ def _main_func():
                     break
             if test_this:
                 pylint_test = make_pylint_test(file_, cimeroot)
-                setattr(B_CheckCode, 'test_pylint_%s'%os.path.basename(file_), pylint_test)
+                testname = "test_pylint_%s"%(os.path.basename(file_))
+                # if two files have the same name this will generate
+                # different test names so that both are tested
+                if testname in testnames:
+                    testname += "_%s"%cnt
+                    cnt = cnt + 1
+                testnames.append(testname)
+                setattr(B_CheckCode, testname, pylint_test)
 
     unittest.main(verbosity=2, catchbreak=True)