def _check_solution(self, filename, prefer_installed=True): # Test that the solution described in the scenario file matches with # what the SAT solver computes. # Given scenario = Scenario.from_yaml( os.path.join(os.path.dirname(__file__), filename) ) request = scenario.request # When pool = Pool(scenario.remote_repositories) pool.add_repository(scenario.installed_repository) policy = InstalledFirstPolicy(pool, scenario.installed_repository, prefer_installed=prefer_installed) solver = DependencySolver( pool, scenario.remote_repositories, scenario.installed_repository, policy=policy, ) # Then try: transaction = solver.solve(request) except SatisfiabilityError as failure: if not scenario.failed: msg = "Solver unexpectedly failed" if failure.reason: msg += " because {0}".format(failure.reason) self.fail(msg) else: if scenario.failed: msg = "Solver unexpectedly succeeded, but {0}." self.fail(msg.format(scenario.failure)) self.assertEqualOperations(transaction.operations, scenario.operations)
def _check_solution(self, filename, prefer_installed=True): # Test that the solution described in the scenario file matches with # what the SAT solver computes. # Given scenario = Scenario.from_yaml( os.path.join(os.path.dirname(__file__), filename) ) request = scenario.request # When pool = Pool(scenario.remote_repositories) pool.add_repository(scenario.installed_repository) solver = DependencySolver( pool, scenario.remote_repositories, scenario.installed_repository, ) # Then try: transaction = solver.solve(request) except SatisfiabilityError as failure: self.assertFailureEqual(pool, failure, scenario) else: if scenario.failed: msg = "Solver unexpectedly succeeded, but {0}" self.fail(msg.format(scenario.failure['raw'])) self.assertEqualOperations(transaction.operations, scenario.operations) if (scenario.pretty_operations or transaction.operations != transaction.pretty_operations): self.assertEqualOperations(transaction.pretty_operations, scenario.pretty_operations)
def test_requirements_are_not_complete(self): # Given scenario = Scenario.from_yaml(io.StringIO(u""" packages: - MKL 10.3-1 - numpy 1.8.1-1; depends (MKL == 10.3-1) request: - operation: install requirement: numpy """)) r_msg = textwrap.dedent("""\ Conflicting requirements: Requirements: 'numpy' <- 'MKL == 10.3-1' +numpy-1.8.1-1 was ignored because it depends on missing packages Requirements: 'numpy' Install command rule (+numpy-1.8.1-1) """) packages = tuple(p for r in scenario.remote_repositories for p in r) # When requirements = [job.requirement for job in scenario.request.jobs] result = requirements_are_complete(packages, requirements) # Then self.assertFalse(result.is_satisfiable) self.assertMultiLineEqual(result.message, r_msg)
def test_requirements_are_not_complete(self): # Given scenario = Scenario.from_yaml( io.StringIO(u""" packages: - MKL 10.3-1 - numpy 1.8.1-1; depends (MKL == 10.3-1) request: - operation: install requirement: numpy """)) r_msg = textwrap.dedent("""\ Conflicting requirements: Requirements: 'numpy' <- 'MKL == 10.3-1' +numpy-1.8.1-1 was ignored because it depends on missing packages Requirements: 'numpy' Install command rule (+numpy-1.8.1-1) """) packages = tuple(p for r in scenario.remote_repositories for p in r) # When requirements = [job.requirement for job in scenario.request.jobs] result = requirements_are_complete(packages, requirements) # Then self.assertFalse(result.is_satisfiable) self.assertMultiLineEqual(result.message, r_msg)
def test_requirements_are_not_satisfiable(self): # Given scenario = Scenario.from_yaml(io.StringIO(u""" packages: - MKL 10.2-1 - MKL 10.3-1 - numpy 1.7.1-1; depends (MKL == 10.3-1) - numpy 1.8.1-1; depends (MKL == 10.3-1) request: - operation: "install" requirement: "numpy" - operation: "install" requirement: "MKL != 10.3-1" """)) r_msg = textwrap.dedent("""\ Conflicting requirements: Requirements: 'numpy' <- 'MKL == 10.3-1' <- 'MKL' Can only install one of: (+MKL-10.3-1 | +MKL-10.2-1) Requirements: 'numpy' <- 'MKL == 10.3-1' numpy-1.8.1-1 requires (+MKL-10.3-1) Requirements: 'numpy' Install command rule (+numpy-1.7.1-1 | +numpy-1.8.1-1) """) packages = tuple(p for r in scenario.remote_repositories for p in r) requirements = [job.requirement for job in scenario.request.jobs] # When result = requirements_are_satisfiable(packages, requirements) # Then self.assertFalse(result.is_satisfiable) self.assertMultiLineEqual(result.message, r_msg)
def main(argv=None): argv = argv or sys.argv[1:] p = argparse.ArgumentParser() p.add_argument("scenario", help="Path to the YAML scenario file.") p.add_argument("--print-ids", action="store_true") p.add_argument("--no-prune", dest="prune", action="store_false") p.add_argument("--no-prefer-installed", dest="prefer_installed", action="store_false") p.add_argument("-d", "--debug", default=0, action="count") p.add_argument("--simple", action="store_true", help="Show a simpler description of the transaction.") p.add_argument("--strict", action="store_true", help="Use stricter error checking for package metadata.") ns = p.parse_args(argv) logging.basicConfig( format=('%(asctime)s %(levelname)-8.8s [%(name)s:%(lineno)s]' ' %(message)s'), datefmt='%Y-%m-%d %H:%M:%S', level=('INFO', 'WARNING', 'DEBUG')[ns.debug]) scenario = Scenario.from_yaml(ns.scenario) solve_and_print(scenario.request, scenario.remote_repositories, scenario.installed_repository, ns.print_ids, prune=ns.prune, prefer_installed=ns.prefer_installed, debug=ns.debug, simple=ns.simple, strict=ns.strict)
def test_requirements_are_not_satisfiable(self): # Given scenario = Scenario.from_yaml( io.StringIO(u""" packages: - MKL 10.2-1 - MKL 10.3-1 - numpy 1.7.1-1; depends (MKL == 10.3-1) - numpy 1.8.1-1; depends (MKL == 10.3-1) request: - operation: "install" requirement: "numpy" - operation: "install" requirement: "MKL != 10.3-1" """)) r_msg = textwrap.dedent("""\ Conflicting requirements: Requirements: 'numpy' <- 'MKL == 10.3-1' <- 'MKL' Can only install one of: (+MKL-10.3-1 | +MKL-10.2-1) Requirements: 'numpy' <- 'MKL == 10.3-1' numpy-1.8.1-1 requires (+MKL-10.3-1) Requirements: 'numpy' Install command rule (+numpy-1.7.1-1 | +numpy-1.8.1-1) """) packages = tuple(p for r in scenario.remote_repositories for p in r) requirements = [job.requirement for job in scenario.request.jobs] # When result = requirements_are_satisfiable(packages, requirements) # Then self.assertFalse(result.is_satisfiable) self.assertMultiLineEqual(result.message, r_msg)
def main(argv=None): argv = argv or sys.argv[1:] p = argparse.ArgumentParser() p.add_argument("scenario", help="Path to the YAML scenario file.") ns = p.parse_args(argv) scenario = Scenario.from_yaml(ns.scenario) print_rules(scenario.request, scenario.remote_repositories, scenario.installed_repository)
def test_packages_are_consistent(self): # Given scenario = Scenario.from_yaml(io.StringIO(u""" packages: - MKL 10.3-1 - numpy 1.8.1-1; depends (MKL == 10.3-1) """)) # When packages = tuple(p for r in scenario.remote_repositories for p in r) result = packages_are_consistent(packages) # Then self.assertTrue(result)
def test_packages_are_consistent(self): # Given scenario = Scenario.from_yaml( io.StringIO(u""" packages: - MKL 10.3-1 - numpy 1.8.1-1; depends (MKL == 10.3-1) """)) # When packages = tuple(p for r in scenario.remote_repositories for p in r) result = packages_are_consistent(packages) # Then self.assertTrue(result)
def main(argv=None): argv = argv or sys.argv[1:] p = argparse.ArgumentParser() p.add_argument("scenario", help="Path to the YAML scenario file.") p.add_argument("--solve", action="store_true", help=("Feed the solution to './minisat' and" " show the resulting solution.")) p.add_argument("--debug", action="count", help="increase the logging verbosity.") ns = p.parse_args(argv) fmt = '%(asctime)s %(levelname)-8.8s [%(name)s:%(lineno)s] %(message)s' logging.basicConfig(format=fmt, datefmt='%Y-%m-%d %H:%M:%S', level='INFO' if ns.debug else 'WARNING') scenario = Scenario.from_yaml(ns.scenario) pool, solver, requirement_ids = initialize(scenario.request, scenario.remote_repositories, scenario.installed_repository, debug=ns.debug) dimacs = '\n'.join(to_dimacs(pool, solver.clauses)) if ns.solve: PIPE = subprocess.PIPE try: cmd = ['./minisat', '-strict', '/dev/stdin', '/dev/stdout'] proc = subprocess.Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE) except OSError as e: msg = str(e) + ": {!r}".format(' '.join(cmd)) raise OSError(msg) output, stderr = proc.communicate(dimacs.encode('ascii')) output = output.decode('ascii') output = [l.strip() for l in output.splitlines()] SAT, model = output[:2] if SAT == 'SAT' and model[-2:] == ' 0': solution_ids = set(int(i) for i in model.split()[:-1]) transaction = from_dimacs_solution(pool, scenario.installed_repository, requirement_ids, solution_ids) print(transaction) else: print(dimacs)
def main(argv=None): argv = argv or sys.argv[1:] p = argparse.ArgumentParser() p.add_argument("scenario", help="Path to the YAML scenario file.") p.add_argument("--solve", action="store_true", help=("Feed the solution to './minisat' and" " show the resulting solution.")) p.add_argument("--debug", action="count", help="increase the logging verbosity.") ns = p.parse_args(argv) fmt = '%(asctime)s %(levelname)-8.8s [%(name)s:%(lineno)s] %(message)s' logging.basicConfig( format=fmt, datefmt='%Y-%m-%d %H:%M:%S', level='INFO' if ns.debug else 'WARNING' ) scenario = Scenario.from_yaml(ns.scenario) pool, solver, requirement_ids = initialize( scenario.request, scenario.remote_repositories, scenario.installed_repository, debug=ns.debug) dimacs = '\n'.join(to_dimacs(pool, solver.clauses)) if ns.solve: PIPE = subprocess.PIPE try: cmd = ['./minisat', '-strict', '/dev/stdin', '/dev/stdout'] proc = subprocess.Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE) except OSError as e: msg = str(e) + ": {!r}".format(' '.join(cmd)) raise OSError(msg) output, stderr = proc.communicate(dimacs.encode('ascii')) output = output.decode('ascii') output = [l.strip() for l in output.splitlines()] SAT, model = output[:2] if SAT == 'SAT' and model[-2:] == ' 0': solution_ids = set(int(i) for i in model.split()[:-1]) transaction = from_dimacs_solution( pool, scenario.installed_repository, requirement_ids, solution_ids) print(transaction) else: print(dimacs)
def main(argv=None): argv = argv or sys.argv[1:] p = argparse.ArgumentParser() p.add_argument("scenario", help="Path to the YAML scenario file.") p.add_argument("--print-ids", action="store_true") p.add_argument("--no-prune", dest="prune", action="store_false") p.add_argument("--no-prefer-installed", dest="prefer_installed", action="store_false") p.add_argument("--debug", action="store_true") ns = p.parse_args(argv) scenario = Scenario.from_yaml(ns.scenario) solve_and_print(scenario.request, scenario.remote_repositories, scenario.installed_repository, ns.print_ids, prune=ns.prune, prefer_installed=ns.prefer_installed, debug=ns.debug)
def test_repository_is_not_consistent(self): # Given scenario = Scenario.from_yaml(io.StringIO(u""" packages: - numpy 1.8.1-1; depends (MKL == 10.3-1) """)) r_msg = textwrap.dedent("""\ Conflicting requirements: Requirements: 'numpy == 1.8.1-1' <- 'MKL == 10.3-1' +numpy-1.8.1-1 was ignored because it depends on missing packages Requirements: 'numpy == 1.8.1-1' Install command rule (+numpy-1.8.1-1) """) # When packages = tuple(p for r in scenario.remote_repositories for p in r) result = packages_are_consistent(packages) # Then self.assertFalse(result.is_satisfiable) self.assertMultiLineEqual(result.message, r_msg)
def test_repository_is_not_consistent(self): # Given scenario = Scenario.from_yaml( io.StringIO(u""" packages: - numpy 1.8.1-1; depends (MKL == 10.3-1) """)) r_msg = textwrap.dedent("""\ Conflicting requirements: Requirements: 'numpy == 1.8.1-1' <- 'MKL == 10.3-1' +numpy-1.8.1-1 was ignored because it depends on missing packages Requirements: 'numpy == 1.8.1-1' Install command rule (+numpy-1.8.1-1) """) # When packages = tuple(p for r in scenario.remote_repositories for p in r) result = packages_are_consistent(packages) # Then self.assertFalse(result.is_satisfiable) self.assertMultiLineEqual(result.message, r_msg)
def test_requirements_are_complete(self): # Given scenario = Scenario.from_yaml(io.StringIO(u""" packages: - MKL 10.3-1 - numpy 1.8.1-1; depends (MKL == 10.3-1) request: - operation: install requirement: numpy ^= 1.8.1 - operation: install requirement: MKL == 10.3-1 """)) packages = tuple(p for r in scenario.remote_repositories for p in r) # When requirements = [job.requirement for job in scenario.request.jobs] result = requirements_are_complete(packages, requirements) # Then self.assertTrue(result.is_satisfiable) self.assertEqual(result.message, "")
def test_requirements_are_complete(self): # Given scenario = Scenario.from_yaml( io.StringIO(u""" packages: - MKL 10.3-1 - numpy 1.8.1-1; depends (MKL == 10.3-1) request: - operation: install requirement: numpy ^= 1.8.1 - operation: install requirement: MKL == 10.3-1 """)) packages = tuple(p for r in scenario.remote_repositories for p in r) # When requirements = [job.requirement for job in scenario.request.jobs] result = requirements_are_complete(packages, requirements) # Then self.assertTrue(result.is_satisfiable) self.assertEqual(result.message, "")
def main(argv=None): argv = argv or sys.argv[1:] default_composer_root = os.path.expanduser( os.path.join("~/src/projects/composer-git") ) p = argparse.ArgumentParser() p.add_argument("scenario", help="Path to the YAML scenario file.") p.add_argument("templates", help="PHP templates.", nargs="+") p.add_argument("--composer-root", help="Composer root.", default=default_composer_root) ns = p.parse_args(argv) remote_definition = "remote.json" installed_definition = "installed.json" scenario = Scenario.from_yaml(ns.scenario) template_variables = scenario_to_php_template_variables(scenario, remote_definition, installed_definition) template_variables["composer_bootstrap"] = os.path.join( ns.composer_root, "src", "bootstrap.php" ) for template in ns.templates: suffix = ".in" assert template.endswith(suffix), \ "Templates should end w/ the {0!r} suffix".format(suffix) with open(template, "rt") as fpin: output = template[:-len(suffix)] with open(output, "wt") as fpout: data = jinja2.Template(fpin.read()).render(**template_variables) fpout.write(data)