diff --git a/.github/workflows/on_pull_request.yaml b/.github/workflows/on_pull_request.yaml index 7abade093..5b00eec65 100644 --- a/.github/workflows/on_pull_request.yaml +++ b/.github/workflows/on_pull_request.yaml @@ -7,6 +7,12 @@ on: jobs: lint: runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + flags: + - --debug --test --uv + - --debug --test steps: - name: checkout-code uses: actions/checkout@main @@ -27,5 +33,5 @@ jobs: msg: apply code formatting and linting auto-fixes - name: test-startup run: | - export COMMANDLINE_ARGS="--debug --test" + export COMMANDLINE_ARGS="${{ matrix.flags }}" python launch.py diff --git a/installer.py b/installer.py index a00a12624..913da981e 100644 --- a/installer.py +++ b/installer.py @@ -52,6 +52,7 @@ args = Dot({ 'reinstall': False, 'version': False, 'ignore': False, + 'uv': False, }) git_commit = "unknown" submodules_commit = { @@ -235,22 +236,25 @@ def uninstall(package, quiet = False): @lru_cache() -def pip(arg: str, ignore: bool = False, quiet: bool = False): +def pip(arg: str, ignore: bool = False, quiet: bool = False, forcePip = False): + uv = args.uv and not forcePip + pipCmd = "uv pip" if uv else "pip" + uvMode = "[uv] " if uv else "" arg = arg.replace('>=', '==') if not quiet and '-r ' not in arg: - log.info(f'Install: package="{arg.replace("install", "").replace("--upgrade", "").replace("--no-deps", "").replace("--force", "").replace(" ", " ").strip()}"') + log.info(f'Install: package="{arg.replace("install", "").replace("--upgrade", "").replace("--no-deps", "").replace("--force", "").replace(" ", " ").strip()}" mode={"uv" if uv else "pip"}') env_args = os.environ.get("PIP_EXTRA_ARGS", "") - log.debug(f'Running: pip="{pip_log}{arg} {env_args}"') - result = subprocess.run(f'"{sys.executable}" -m pip {pip_log}{arg} {env_args}', shell=True, check=False, env=os.environ, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + log.debug(f'Running: {pipCmd}="{pip_log}{arg} {env_args}"') + result = subprocess.run(f'"{sys.executable}" -m {pipCmd} {pip_log}{arg} {env_args}', shell=True, check=False, env=os.environ, stdout=subprocess.PIPE, stderr=subprocess.PIPE) txt = result.stdout.decode(encoding="utf8", errors="ignore") if len(result.stderr) > 0: txt += ('\n' if len(txt) > 0 else '') + result.stderr.decode(encoding="utf8", errors="ignore") txt = txt.strip() - debug(f'Install pip: {txt}') + debug(f'Install {pipCmd}: {txt}') if result.returncode != 0 and not ignore: global errors # pylint: disable=global-statement errors += 1 - log.error(f'Error running pip: {arg}') + log.error(f'Error running {pipCmd}: {arg}') log.debug(f'Pip output: {txt}') return txt @@ -264,7 +268,7 @@ def install(package, friendly: str = None, ignore: bool = False, reinstall: bool quick_allowed = False if args.reinstall or reinstall or not installed(package, friendly, quiet=quiet): deps = '' if not no_deps else '--no-deps ' - res = pip(f"install --upgrade {deps}{package}", ignore=ignore) + res = pip(f"install{' --upgrade' if not args.uv else ''} {deps}{package}", ignore=ignore, forcePip=(package == "uv")) try: import imp # pylint: disable=deprecated-module imp.reload(pkg_resources) @@ -1223,6 +1227,7 @@ def add_args(parser): group.add_argument('--version', default = False, action='store_true', help = "Print version information") group.add_argument('--ignore', default = os.environ.get("SD_IGNORE",False), action='store_true', help = "Ignore any errors and attempt to continue") group.add_argument('--safe', default = os.environ.get("SD_SAFE",False), action='store_true', help = "Run in safe mode with no user extensions") + group.add_argument('--uv', default = os.environ.get("SD_UV",False), action='store_true', help = "Use uv instead of pip to install the packages") group = parser.add_argument_group('Logging options') group.add_argument("--log", type=str, default=os.environ.get("SD_LOG", None), help="Set log file, default: %(default)s") diff --git a/launch.py b/launch.py index f1d8b7ec5..1db8a81f6 100755 --- a/launch.py +++ b/launch.py @@ -204,6 +204,8 @@ def main(): installer.log.info(f'Platform: {installer.print_dict(installer.get_platform())}') if not args.skip_env: installer.set_environment() + if args.uv: + installer.install("uv", "uv") installer.check_torch() installer.check_onnx() installer.check_diffusers()