def find_and_build_deps()

in tools/python/packapp/__main__.py [0:0]


def find_and_build_deps(args):
    app_path = pathlib.Path(args.path)
    req_txt = app_path / 'requirements.txt'

    if not req_txt.exists():
        die('missing requirements.txt file.  '
            'If you do not have any requirements, please pass --no-deps.')

    packages = []

    # First, we need to figure out the complete list of dependencies
    # without actually installing them.  Use straight `pip download`
    # for that.
    with tempfile.TemporaryDirectory(prefix='azureworker') as td:
        run_or_die([
           sys.executable, '-m', 'pip', 'download', '-r', str(req_txt), '--dest', td
        ], verbose=args.verbose)

        files = os.listdir(td)

        for filename in files:
            m = re.match(r'^(?P<name>.+?)-(?P<ver>.*?)-.*\.whl$', filename)
            if m:
                # This is a wheel.
                packages.append((m.group('name'), m.group('ver')))
            else:
                # This is a sdist.
                m = re.match(r'^(?P<namever>.+)(\.tar\.gz|\.tgz|\.zip)$',
                             filename)
                if m:
                    name, _, ver = m.group('namever').rpartition('-')
                    if name and ver:
                        packages.append((name, ver))

    # Now that we know all dependencies, download or build wheels
    # for them for the correct platform and Python verison.
    with tempfile.TemporaryDirectory(prefix='azureworker') as td:
        for name, ver in packages:
            ensure_wheel(name, ver, args=args, dest=td)

        with tempfile.TemporaryDirectory(prefix='azureworkervenv') as venv:
            venv = pathlib.Path(venv)
            pyver = args.python_version
            python = f'python{pyver[0]}.{pyver[1]}'

            if args.platform == 'windows':
                sp = venv / 'Lib' / 'site-packages'
                headers = venv / 'Include'
                scripts = venv / 'Scripts'
                data = venv
            elif args.platform == 'linux' and python == "python3.6":
                sp = venv / 'lib' / python / 'site-packages'
                headers = venv / 'include' / 'site' / python
                scripts = venv / 'bin'
                data = venv
            elif args.platform == 'linux':
                sp = venv / 'lib' / 'site-packages'
                headers = venv / 'include' / 'site' / python
                scripts = venv / 'bin'
                data = venv
            else:
                die(f'unsupported platform: {args.platform}')

            maker = distlib.scripts.ScriptMaker(None, None)

            for filename in os.listdir(td):
                if not filename.endswith('.whl'):
                    continue

                wheel = distlib.wheel.Wheel(os.path.join(td, filename))

                paths = {
                    'prefix': venv,
                    'purelib': sp,
                    'platlib': sp,
                    'headers': headers / wheel.name,
                    'scripts': scripts,
                    'data': data
                }

                for dn in paths.values():
                    os.makedirs(dn, exist_ok=True)

                # print(paths, maker)
                wheel.install(paths, maker)

            for root, dirs, files in os.walk(venv):
                for file in files:
                    src = os.path.join(root, file)
                    rpath = app_path / args.packages_dir_name / \
                        os.path.relpath(src, venv)
                    dir_name, _ = os.path.split(rpath)
                    os.makedirs(dir_name, exist_ok=True)
                    shutil.copyfile(src, rpath)