def do_upgrade_requirements(self, arg, timeout=(3*60)): """ 1. Convert via 'pip-compile' *.in requirements files to *.txt 2. Append 'piprot' informations to *.txt requirements. Direct start with: $ pylucid_admin upgrade_requirements """ requirements_path = self.requirements.get_requirement_path() for requirement_in in requirements_path.glob("*.in"): requirement_in = Path(requirement_in).name if requirement_in.startswith("basic_"): continue requirement_out = requirement_in.replace(".in", ".txt") self.stdout.write("_"*79 + "\n") # We run pip-compile in ./requirements/ and add only the filenames as arguments # So pip-compile add no path to comments ;) return_code = VerboseSubprocess( "pip-compile", "--verbose", "--upgrade", "-o", requirement_out, requirement_in, cwd=str(requirements_path), timeout=timeout ).verbose_call(check=True) if not requirement_in.startswith("test_"): req_out = Path(requirements_path, requirement_out) with req_out.open("r") as f: requirement_out_content = f.read() for version_prefix in VERSION_PREFIXES: if not version_prefix in requirement_out_content: raise RuntimeError("ERROR: %r not found!" % version_prefix) self.stdout.write("_"*79 + "\n") output = [ "\n#\n# list of out of date packages made with piprot:\n#\n" ] sp=VerboseSubprocess("piprot", "--outdated", requirement_out, cwd=str(requirements_path)) for line in sp.iter_output(): print(line, end="", flush=True) output.append("# %s" % line) self.stdout.write("\nUpdate file %r\n" % requirement_out) filepath = Path(requirements_path, requirement_out).resolve() assert filepath.is_file(), "File not exists: %r" % filepath with open(filepath, "a") as f: f.writelines(output)
def pylucid_admin_run(self, *args): args = ("pylucid_boot", ) + args try: return VerboseSubprocess(*args).verbose_output(check=False) except subprocess.CalledProcessError as err: print(err.output) self.fail("Subprocess error: %s" % err)
def test_create(self): destination = Path(self.temp_path, self._testMethodName) self.assertFalse(destination.is_dir()) output = VerboseSubprocess( "pylucid_admin", "create_page_instance", str(destination), self._testMethodName).verbose_output(check=False) print(output) self.assertIn("Page instance created here: '%s'" % destination, output) self.assertEqual( set([p.name for p in destination.iterdir()]), {'manage.py', 'media', 'static', self._testMethodName}) # Check patched manage.py with Path(destination, "manage.py").open("r") as f: shebang = f.readlines(1)[0] self.assertEqual(shebang, "%s\n" % get_python3_shebang()) content = f.read() print(content) self.assertIn( 'os.environ.setdefault("DJANGO_SETTINGS_MODULE", "%s.settings")' % self._testMethodName, content) # Check patched settings.py with Path(destination, self._testMethodName, "settings.py").open("r") as f: content = f.read() print(content) self.assertIn('DOC_ROOT = "%s"' % destination, content) self.assertIn('ROOT_URLCONF = "%s.urls"' % self._testMethodName, content)
def do_change_editable_address(self, arg): """ Replace git remote url from github read-only 'https' to 'git@' e.g.: OLD: https://github.com/jedie/PyLucid.git NEW: [email protected]:jedie/PyLucid.git **This is only developer with github write access ;)** git remote set-url origin https://github.com/jedie/python-creole.git Direct start with: $ pylucid_admin change_editable_address """ src_path = self.requirements.src_path # Path instance pointed to 'src' directory for p in src_path.iterdir(): if not p.is_dir(): continue if str(p).endswith(".bak"): continue print("\n") print("*"*79) print("Change: %s..." % p) try: output = VerboseSubprocess( "git", "remote", "-v", cwd=str(p), ).verbose_output(check=False) except subprocess.CalledProcessError: print("Skip.") continue (name, url) = re.findall(r"(\w+?)\s+([^\s]*?)\s+", output)[0] print("Change %r url: %r" % (name, url)) new_url=url.replace("https://github.com/", "[email protected]:") if new_url == url: print("ERROR: url not changed!") continue VerboseSubprocess("git", "remote", "set-url", name, new_url, cwd=str(p)).verbose_call(check=False) VerboseSubprocess("git", "remote", "-v", cwd=str(p)).verbose_call(check=False)
def test_project_manage(self, *args, timeout=1000, check=False): cwd = self.path_helper.base.parent # e.g.: PyLucid-env/src/pylucid/pylucid_page_instance assert cwd.is_dir(), "ERROR: Path not exists: %r" % cwd args = ["./pylucid_page_instance/manage.py"] + list(args) manage_path = Path(cwd, args[0]) assert manage_path.is_file(), "ERROR: File not found: '%s'" % manage_path return VerboseSubprocess(*args, cwd=str(cwd), timeout=timeout).verbose_call(check=check)
def test_boot_into_existing_path(self): with isolated_filesystem(): temp_path = Path().cwd() # isolated_filesystem does made a chdir to /tmp/... with self.assertRaises(subprocess.CalledProcessError) as cm: VerboseSubprocess("pylucid_boot", "boot", str(temp_path)).verbose_output(check=False) caller_process_error = cm.exception output = caller_process_error.output print(output) self.assertIn("ERROR: Path '%s' already exists!" % temp_path, output)
def test_change_editable_address(self): """ All test runs on Travis-CI install PyLucid as editable! See .travis.yml """ requirements = Requirements(package_path=PACKAGE_PATH) self.assertFalse(requirements.normal_mode) pylucid_src_path = Path(requirements.src_path, "pylucid") print("pylucid_src_path: %r" % pylucid_src_path) self.assertTrue(pylucid_src_path.is_dir()) self.assertTrue(str(pylucid_src_path).endswith("/src/pylucid")) git_path = Path(pylucid_src_path, ".git") print("git_path: %r" % git_path) self.assertTrue(git_path.is_dir()) # Needed while developing with github write access url ;) output = VerboseSubprocess( "git", "remote", "set-url", "origin", "https://github.com/jedie/PyLucid.git", cwd=str(pylucid_src_path) ).verbose_output(check=True) # print(output) # Check if change was ok: output = VerboseSubprocess( "git", "remote", "-v", cwd=str(pylucid_src_path) ).verbose_output(check=True) # print(output) self.assertIn("https://github.com/jedie/PyLucid.git", output) self.assertNotIn("*****@*****.**", output) output = self.pylucid_admin_run("change_editable_address") print(output) self.assertIn("[email protected]:jedie/PyLucid.git", output)
def call_manage_py(self, *args, check=False, **kwargs): """ Call manage.py from created page instance in temp dir. """ args = ("./manage.py",) + args # pylucid_page_instance/manage.py use os.environ.setdefault # We must remove "DJANGO_SETTINGS_MODULE" from environ! env=os.environ.copy() del(env["DJANGO_SETTINGS_MODULE"]) kwargs.update({ "cwd": str(self.manage_file_path.parent), "env": env, }) try: return VerboseSubprocess(*args, **kwargs).verbose_output(check=check) except subprocess.CalledProcessError as err: print(err.output) self.fail(err)
def do_update_env(self, arg): """ Update all packages in virtualenv. Direct start with: $ pylucid_admin update_env (Call this command only in a activated virtualenv.) """ if not in_virtualenv(): self.stdout.write( "\nERROR: Only allowed in activated virtualenv!\n\n") return pip3_path = Path(sys.prefix, "bin", "pip3") if not pip3_path.is_file(): print("ERROR: pip not found here: '%s'" % pip3_path) return print("pip found here: '%s'" % pip3_path) pip3_path = str(pip3_path) return_code = VerboseSubprocess(pip3_path, "install", "--upgrade", "pip").verbose_call(check=False) # Update the requirements files by... if self.requirements.normal_mode: # ... update 'pylucid' PyPi package return_code = VerboseSubprocess( pip3_path, "install", "--upgrade", *PYLUCID_NORMAL_REQ).verbose_call(check=False) else: # ... git pull pylucid sources return_code = VerboseSubprocess( "git", "pull", "origin", cwd=str(self.package_path)).verbose_call(check=False) return_code = VerboseSubprocess( pip3_path, "install", "--editable", ".", cwd=str(self.package_path)).verbose_call(check=False) requirement_file_path = str( self.requirements.get_requirement_file_path()) # Update with requirements files: self.stdout.write("Use: '%s'\n" % requirement_file_path) return_code = VerboseSubprocess( "pip3", "install", "--exists-action", "b", # action when a path already exists: (b)ackup "--upgrade", "--requirement", requirement_file_path, timeout=120 # extended timeout for slow Travis ;) ).verbose_call(check=False) if not self.requirements.normal_mode: # Run pip-sync only in developer mode return_code = VerboseSubprocess( "pip-sync", requirement_file_path, cwd=str(self.package_path)).verbose_call(check=False) # 'reinstall' pylucid editable, because it's not in 'requirement_file_path': return_code = VerboseSubprocess( pip3_path, "install", "--editable", ".", cwd=str(self.package_path)).verbose_call(check=False) self.stdout.write("Please restart %s\n" % self.self_filename) sys.exit(0)
def do_pip_freeze(self, arg): """ Just run 'pip freeze' """ return_code = VerboseSubprocess("pip3", "freeze").verbose_call(check=False)