Compare commits

..
Author SHA1 Message Date
Murphy c7c8d8b00c Fix tests 2022-03-15 11:33:38 +01:00
Murphy a37e4f14d4 Raising exception when using pacakge not installed in use cmd 2022-03-15 11:19:43 +01:00
Murphy bef51a6550 checkout master when clonning a repo 2022-03-15 11:11:37 +01:00
Murphy 3a85250650 Fix some pylint lints 2022-03-14 21:38:31 +01:00
Murphy 3ac84323ed Fix minor issues 2022-03-14 21:35:24 +01:00
Murphy 08c8472b24 Update profiles.json 2022-03-13 19:13:20 +01:00
Murphy 1b81a4f99e Add tests to package manager 2022-03-13 19:05:31 +01:00
Murphy 56af97b8cb Refactor package manager 2022-03-13 19:05:17 +01:00
Murphy 329b07ecca Refactoring package manager 2022-02-28 11:27:04 +01:00
Murphy f564b2ec68 Add dependency to release-job 2022-02-28 11:23:17 +01:00
Murphy e54f5f3acb Add unit tests to CI 2022-02-28 11:22:00 +01:00
Murphy 8e8d3e867e Fix some lints 2022-02-28 11:18:31 +01:00
Murphy 2ef3b14455 Refactor package manager and add tests 2022-02-28 09:00:35 +01:00
Murphy d65e7e2077 Refactor r2env core and add tests 2022-02-13 17:54:07 +01:00
Murphy ac6fac0fe5 Refactor r2env core and add tests 2022-02-13 13:22:26 +01:00
Murphy eeea848e86 Refactor repl and add tests 2022-02-12 20:53:58 +01:00
asoler 62a34e1811 Refactoring Repl 2022-01-30 18:58:39 +01:00
murphy d241288254 Fix some codechecks 2021-12-08 20:53:22 +01:00
murphy d1e4c9cdae Update gitignore 2021-12-08 18:48:24 +01:00
murphy 09c8251b07 Add 5.5.2 version 2021-12-08 18:34:51 +01:00
17 changed files with 191 additions and 281 deletions

No files matched your search

-70
View File
@@ -1,70 +0,0 @@
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL"
on:
push:
branches: [ master ]
pull_request:
# The branches below must be a subset of the branches above
branches: [ master ]
schedule:
- cron: '34 6 * * 0'
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
language: [ 'python' ]
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
# Learn more about CodeQL language support at https://git.io/codeql-language-support
steps:
- name: Checkout repository
uses: actions/checkout@v2
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v1
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# queries: ./path/to/local/query, your-org/your-repo/queries@main
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v1
# ℹ️ Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
# and modify them (or add more) to build your code if your project
# uses a compiled language
#- run: |
# make bootstrap
# make release
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v1
-23
View File
@@ -1,23 +0,0 @@
on:
pull_request: {}
push:
branches:
- main
- master
paths:
- .github/workflows/semgrep.yml
schedule:
# random HH:MM to avoid a load spike on GitHub Actions at 00:00
- cron: 34 10 * * *
name: Semgrep
jobs:
semgrep:
name: Scan
runs-on: ubuntu-20.04
env:
SEMGREP_APP_TOKEN: ${{ secrets.SEMGREP_APP_TOKEN }}
container:
image: returntocorp/semgrep
steps:
- uses: actions/checkout@v3
- run: semgrep ci
+4 -7
View File
@@ -1,20 +1,17 @@
PYTHON?=python3
PIP?=pip3
all:
$(PIP) install .
pip install .
pub:
rm -rf dist
$(PYTHON) setup.py sdist
twine check dist/*
twine upload -u __token__ --repository-url https://upload.pypi.org/legacy/ --verbose dist/*
#twine upload --repository=pypi --verbose dist/*
twine upload --repository=pypi --verbose dist/*
install:
$(PIP) install .
pip install .
uninstall:
$(PIP) uninstall r2env
pip uninstall r2env
.PHONY: all clean pub install uninstall
-1
View File
@@ -64,7 +64,6 @@ versions - list installed packages
list - list all packages available to r2env
shell - enter a new shell with PATH env var set
purge - remove ~/.r2env
update - update list of available profiles
Environment
-3
View File
@@ -1,3 +0,0 @@
from r2env.repl import main
main()
+147
View File
@@ -0,0 +1,147 @@
{
"r2frida": {
"source": "https://github.com/nowsecure/r2frida",
"versions": [
{
"id": "git",
"packages": {}
}
]
},
"r2dec": {
"source": "https://github.com/wargio/r2dec-js",
"versions": [
{
"id": "git",
"packages": {}
}
]
},
"r2ghidra": {
"source": "https://github.com/radareorg/r2ghidra",
"versions": [
{
"id": "git",
"packages": {}
}
]
},
"r0": {
"source": "https://github.com/radareorg/r0",
"versions": [
{
"id": "git",
"packages": {}
}
]
},
"radare2": {
"source": "https://github.com/radareorg/radare2",
"versions": [
{
"id": "5.3.0",
"packages": {
"w64": "radare2-5.3.0-w64.zip",
"deb_x64": "radare2_5.3.0_amd64.deb"
}
},
{
"id": "5.3.1",
"packages": {
"w64": "radare2-5.3.1-w64.zip",
"mac_x64": "radare2-5.3.1.pkg",
"deb_x64": "radare2_5.3.1_amd64.deb"
}
},
{
"id": "5.4.0",
"packages": {
"w64": "radare2-5.4.0-w64.zip",
"mac_x64": "radare2-5.4.0.pkg",
"deb_x64": "radare2_5.4.0_amd64.deb"
}
},
{
"id": "5.4.2",
"packages": {
"w32": "radare2-5.4.2-w32.zip",
"w64": "radare2-5.4.2-w64.zip",
"mac_x64": "radare2-5.4.2-amd64.pkg",
"mac_arm64": "radare2-5.4.2-m1.pkg",
"deb_i386": "radare2_5.4.2_i386.deb",
"deb_x64": "radare2_5.4.2_amd64.deb"
}
},
{
"id": "5.5.0",
"packages": {
"w32": "radare2-5.5.0-w32.zip",
"w64": "radare2-5.5.0-w64.zip",
"mac_x64": "radare2-5.5.0-amd64.pkg",
"mac_arm64": "radare2-5.5.0-m1.pkg",
"deb_i386": "radare2_5.5.0_i386.deb",
"deb_x64": "radare2_5.5.0_amd64.deb"
}
},
{
"id": "5.5.2",
"packages": {
"w32": "radare2-5.5.2-w32.zip",
"w64": "radare2-5.5.2-w64.zip",
"mac_x64": "radare2-5.5.2-amd64.pkg",
"mac_arm64": "radare2-5.5.2-m1.pkg",
"deb_i386": "radare2_5.5.2_i386.deb",
"deb_x64": "radare2_5.5.2_amd64.deb"
}
},
{
"id": "5.5.4",
"packages": {
"w32": "radare2-5.5.4-w32.zip",
"w64": "radare2-5.5.4-w64.zip",
"mac_x64": "radare2-5.5.4-amd64.pkg",
"mac_arm64": "radare2-5.5.4-m1.pkg",
"deb_i386": "radare2_5.5.4_i386.deb",
"deb_x64": "radare2_5.5.4_amd64.deb"
}
},
{
"id": "5.6.0",
"packages": {
"w32": "radare2-5.6.0-w32.zip",
"w64": "radare2-5.6.0-w64.zip",
"mac_x64": "radare2-5.6.0-amd64.pkg",
"mac_arm64": "radare2-5.6.0-m1.pkg",
"deb_i386": "radare2_5.6.0_i386.deb",
"deb_x64": "radare2_5.6.0_amd64.deb"
}
},
{
"id": "5.6.2",
"packages": {
"w32": "radare2-5.6.2-w32.zip",
"w64": "radare2-5.6.2-w64.zip",
"mac_x64": "radare2-5.6.2-amd64.pkg",
"mac_arm64": "radare2-5.6.2-m1.pkg",
"deb_i386": "radare2_5.6.2_i386.deb",
"deb_x64": "radare2_5.6.2_amd64.deb"
}
},
{
"id": "5.6.4",
"packages": {
"w32": "radare2-5.6.4-w32.zip",
"w64": "radare2-5.6.4-w64.zip",
"mac_x64": "radare2-5.6.4-amd64.pkg",
"mac_arm64": "radare2-5.6.4-m1.pkg",
"deb_i386": "radare2_5.6.4_i386.deb",
"deb_x64": "radare2_5.6.4_amd64.deb"
}
},
{
"id": "git",
"packages": {}
}
]
}
}
+7 -13
View File
@@ -67,8 +67,6 @@ class R2Env:
self.check_if_r2env_initialized()
use_meson = kwargs["use_meson"] if "use_meson" in kwargs else False
use_dist = kwargs["use_dist"] if "use_dist" in kwargs else False
if "@" not in package:
package = f"{package}@git"
if not self._check_package_format(package):
raise R2EnvException("[x] Invalid package format.")
try:
@@ -108,17 +106,17 @@ class R2Env:
@staticmethod
def version():
thispath = os.path.dirname(os.path.realpath(__file__))
with open(f"{thispath}/version.txt", "r", encoding="utf-8") as version:
print_console(version.read())
with open(thispath + "/version.txt", "r", encoding="utf-8") as version:
return version.read()
def shell(self, cmd=None, **_kwargs):
def shell(self, cmd="", **_kwargs):
bin_path = os.path.join(self._r2env_path, "bin")
if host_platform() == "windows":
os.system(f"set PATH={bin_path};%PATH% && cmd")
return True
pkgconfig_path = os.path.join(self._r2env_path, "lib", "pkgconfig")
bin_path = os.path.join(self._r2env_path, "bin")
export_ps1 = f"export PS1=\"r2env ({self._get_current_version()})\\$ \";"
export_ps1 = "export PS1=\"r2env\\$ \";"
export_pkg_config = f"export PKG_CONFIG_PATH=\"{pkgconfig_path}\";"
export_path = f"export PATH=\"{bin_path}:$PATH\";"
cmd_shell = "$SHELL -f"
@@ -128,11 +126,10 @@ class R2Env:
full_cmd = f"export LD_LIBRARY_PATH=\"{library_path}\";" + full_cmd
if host_platform() == "osx":
library_path = os.path.join(self._r2env_path, "lib")
# XXX this doesnt work on sip-enabled macs, that's why we use install_name_tool after install
full_cmd = f"export DYLD_LIBRARY_PATH=\"{library_path}\";" + full_cmd
if cmd is None:
return os.system(full_cmd) == 0
return os.system(f"{full_cmd} -c '{cmd}'") == 0
if cmd.strip() == "":
return os.system(full_cmd)
return os.system(full_cmd + " -c '" + cmd + "'")
@staticmethod
def _load_config():
@@ -170,9 +167,6 @@ class R2Env:
with open(version_file, 'w', encoding="utf-8") as file_desc:
file_desc.write(package)
def update_version_profiles(self):
PackageManager.update_radare2_profiles(self._r2env_path)
def check_if_r2env_initialized(self):
if not os.path.isdir(self._r2env_path):
raise R2EnvException("Not r2env initialized. Execute 'r2env init' first.")
+21 -128
View File
@@ -5,10 +5,8 @@ import shutil
import time
from urllib.error import URLError
import zipfile
import json
import wget
import requests
from r2env.exceptions import PackageManagerException
from r2env.tools import load_json_file, git_fetch, git_clean, print_console, ERROR, exit_if_not_exists, host_distname
@@ -21,7 +19,7 @@ class PackageManager:
DOWNLOAD_URL = "https://github.com/radareorg/radare2/releases/download/"
def __init__(self, r2env_path):
self._packages = self._load_profiles(r2env_path)
self._packages = self._load_profiles()
self._r2env_path = r2env_path
def get_package_path(self, package_name):
@@ -40,110 +38,13 @@ class PackageManager:
return res
@staticmethod
def _load_profiles(r2env_path):
filename = os.path.join(r2env_path, 'profiles.json')
# if profiles.json doesn't exist, generate it now
if not os.path.exists(filename):
print_console(f"NOTE: {filename} does not exist. Generating it now.")
PackageManager.update_radare2_profiles(r2env_path)
def _load_profiles():
filename = os.path.join(os.path.dirname(__file__), 'config', 'profiles.json')
profiles = load_json_file(filename)
if not profiles:
raise PackageManagerException("No profiles configured.")
return profiles
@staticmethod
def update_radare2_profiles(r2env_path):
gh_release_info_req = requests.get(
"https://api.github.com/repos/radareorg/radare2/releases",
{"headers": ["X-GitHub-Api-Version: 2022-11-28", "Accept: application/vnd.github+json"]},
timeout=10 # 10-second timeout for API request
)
gh_release_info_req.raise_for_status() # raise an error if the request got a bad return code
gh_release_info = gh_release_info_req.json()
radare2_versions = [{'id': 'git', 'packages': {}}] # include the git version by default
for release in gh_release_info:
version = {'id': release['tag_name'], 'packages': {}}
# generate a list of downloadable assets for this release that r2env can use
for asset in release['assets']:
# note: you're about to see 100 lines of hackery to deal with inconsistent naming schemes
# the goal is to include as many valid assets as is reasonable without including any that are not valid
# separate file extension
asset_name, asset_ext = os.path.splitext(asset['name'])
# normalize 'seperators' before splitting into components
asset_ref = asset_name.replace('_', '-').split('-')
# filter out things like r2ios_sdk and r2blob
if asset_ref[0] != 'radare2':
continue
# Some assets don't have the version number in the name, which breaks the following processing.
# None of them are of interest anyway, so just skip them.
if release['tag_name'] not in asset_ref:
continue
# remove the beginning 'radare2'
asset_ref.remove('radare2')
# we don't need to care about the release id when checking, so remove it
asset_ref.remove(release['tag_name'])
# once "radare2" and the version number have been removed from asset_ref,
# if all that's left matches a filter, save it.
_VERSION_FILTERS = {
'.zip': { # used for Windows builds among other things
'w32': [['w32']],
'w64': [['w64']]
},
'.deb': {
'deb_i386': [['i386']],
'deb_x64': [['amd64']]
},
'.pkg': { # macOS bundle
'mac_arm64': [['m1']],
'mac_x64': [[], ['amd64'], ['x64'], ['macos']]
}
}
if asset_ext in _VERSION_FILTERS:
for platform, refs in _VERSION_FILTERS[asset_ext].items():
if asset_ref in refs:
version['packages'][platform] = asset['name']
break
radare2_versions.append(version)
profiles = {
'r2frida': {
'source': 'https://github.com/nowsecure/r2frida',
'versions': [{'id': 'git', 'packages': {}}]
},
'r2dec': {
'source': 'https://github.com/wargio/r2dec-js',
'versions': [{'id': 'git', 'packages': {}}]
},
'r2yara': {
'source': 'https://github.com/radareorg/r2yara',
'versions': [{'id': 'git', 'packages': {}}]
},
'r2ghidra': {
'source': 'https://github.com/radareorg/r2ghidra',
'versions': [{'id': 'git', 'packages': {}}]
},
'r0': {
'source': 'https://github.com/radareorg/r0',
'versions': [{'id': 'git', 'packages': {}}]
},
'radare2': {
'source': 'https://github.com/radareorg/radare2',
'versions': radare2_versions[::-1]
}
}
if not os.path.isdir(r2env_path):
os.makedirs(r2env_path)
with open(os.path.join(r2env_path, 'profiles.json'), 'w', encoding='utf-8') as f:
json.dump(profiles, f)
def install_package(self, profile, version, use_meson, use_dist):
log_path = os.path.join(self._r2env_path, self.LOG_DIR)
timestamp = round(time.monotonic() * 1000)
@@ -156,17 +57,11 @@ class PackageManager:
os.makedirs(source_path)
if not os.path.isdir(dst_dir):
os.makedirs(dst_dir)
if self._if_package_not_available(profile, version):
if os.path.isdir(dst_dir):
shutil.rmtree(dst_dir)
raise PackageManagerException(
f"{profile}@{version} package not available. Use 'list' command to see available packages.")
self._exit_if_package_not_available(profile, version)
if use_dist:
if self._install_from_dist(profile, version):
print_console(f"[*] Binary package {profile}@{version} installed successfully")
else:
if os.path.isdir(dst_dir):
shutil.rmtree(dst_dir)
raise PackageManagerException(f"[x] Failed to install {profile}@{version}.")
else:
if self._build_from_source(profile, version, source_path, dst_dir, logfile, use_meson=use_meson):
@@ -198,12 +93,11 @@ class PackageManager:
raise PackageManagerException(f"[x] Unable to find installed package {package_name}")
def _get_pkgname(self, profile, version, cos):
if profile in self._packages:
for pkgv in self._packages[profile]["versions"]:
if pkgv["id"] == version:
for pkgd in pkgv["packages"].keys():
if pkgd == cos:
return pkgv["packages"][pkgd]
for pkgv in self._packages[profile]["versions"]:
if pkgv["id"] == version:
for pkgd in pkgv["packages"].keys():
if pkgd == cos:
return pkgv["packages"][pkgd]
return None
def _get_disturl(self, profile, version, cos):
@@ -296,8 +190,6 @@ class PackageManager:
@staticmethod
def _build_using_acr(source_path, dst_path, logfile, r2env_path):
"""Only works in Unix systems"""
if host_distname() is not None and host_distname() in "w64":
raise PackageManagerException("acr is not supported on Windows platform. Use meson instead.")
exit_if_not_exists(['make'])
print_console("[-] Building package using acr...")
extra_flags = ""
@@ -318,19 +210,20 @@ class PackageManager:
exit_if_not_exists(['meson', 'ninja'])
print_console("[-] Building package using meson ...")
config_path = r2env_path + "/lib/pkgconfig"
# TODO: ensure source_path logfile or dst_path have no spaces
cmd = f"(export PKG_CONFIG_PATH=\"{config_path}\";" \
f"cd \"{source_path}\" && rm -rf build && " \
f"meson build --buildtype=release --prefix={dst_path} -Dlocal=true 2>&1 && " \
f"cd {source_path} && rm -rf build && " \
f"meson . build --buildtype=release --prefix={dst_path} -Dlocal=true 2>&1 && " \
f"ninja -C build && " \
f"ninja -C build install) > {logfile} && " \
f"for a in {dst_path}/bin/* ; do install_name_tool -add_rpath {dst_path}/lib $a ; done"
f"ninja -C build install) > {logfile}"
print_console(f"Executing {cmd}")
return os.system(cmd) == 0
def _if_package_not_available(self, profile, version):
if profile in self._packages:
for available_version in self._packages[profile]["versions"]:
if available_version['id'] == version:
return False
return True
def _exit_if_package_not_available(self, profile, version):
pkg_found = False
for available_version in self._packages[profile]["versions"]:
if available_version['id'] == version:
pkg_found = True
break
if not pkg_found:
raise PackageManagerException(
f"{profile}@{version} package not available. Use 'list' command to see available packages.")
+2 -9
View File
@@ -31,7 +31,6 @@ class REPL:
list - list all packages available to r2env.
shell - enter a new shell with PATH env var set.
purge - remove ~/.r2env
update - update list of available profiles
Environment
@@ -56,7 +55,6 @@ class REPL:
"install": self._core.install,
"installed": self._core.list_installed_packages,
"uninstall": self._core.uninstall,
"update": self._core.update_version_profiles,
"rm": self._core.uninstall,
"use": self._core.use,
"purge": self._core.purge,
@@ -67,9 +65,9 @@ class REPL:
def show_help(self):
print_console(self.HELP_MESSAGE)
def run_action(self, action_args): # noqa: C901
def run_action(self, action_args):
args = []
if not action_args:
if not action_args or len(action_args.args) == 0:
self.show_help()
raise ActionException("No action selected")
if action_args.version:
@@ -78,9 +76,6 @@ class REPL:
if action_args.list:
list_method = self.actions["list"]
list_method()
if len(action_args.args) == 0:
self.show_help()
raise ActionException("No action selected")
if len(action_args.args) > 1:
args = action_args.args[1:]
action = action_args.args[0]
@@ -94,8 +89,6 @@ class REPL:
raise ActionException(f"Action {action} requires a package as an argument.")
if action in self.actions_with_arguments:
self.actions[action](args[0], use_meson=action_args.meson, use_dist=action_args.package)
elif action in "shell" and len(args) > 0:
self.actions[action](args[0])
else:
self.actions[action]()
+5 -5
View File
@@ -134,8 +134,8 @@ class TestCore(unittest.TestCase):
@patch("r2env.core.R2Env.check_if_r2env_initialized")
def test_install_successfully_failed(self, mock_initialized):
mock_initialized.return_value = True
package = "radare2@"
version = ""
package = "radare2"
version = "5.3.0"
with self.assertRaises(R2EnvException):
R2Env().install(f"{package}{version}", use_dist=True)
@@ -262,7 +262,7 @@ class TestCore(unittest.TestCase):
cmd = "r2 -v"
R2Env().shell(cmd)
mock_system.assert_called_with(f"export LD_LIBRARY_PATH=\"{r2env_path}/lib\";"
f"export PS1=\"r2env ()\\$ \";"
f"export PS1=\"r2env\\$ \";"
f"export PKG_CONFIG_PATH=\"{r2env_path}/lib/pkgconfig\";"
f"export PATH=\"{r2env_path}/bin:$PATH\";"
f"$SHELL -f -c \'{cmd}\'")
@@ -277,7 +277,7 @@ class TestCore(unittest.TestCase):
cmd = "r2 -v"
R2Env().shell(cmd)
mock_system.assert_called_with(f"export DYLD_LIBRARY_PATH=\"{r2env_path}/lib\";"
f"export PS1=\"r2env ()\\$ \";"
f"export PS1=\"r2env\\$ \";"
f"export PKG_CONFIG_PATH=\"{r2env_path}/lib/pkgconfig\";"
f"export PATH=\"{r2env_path}/bin:$PATH\";"
f"$SHELL -f -c \'{cmd}\'")
@@ -291,7 +291,7 @@ class TestCore(unittest.TestCase):
mock_load_json_file.return_value = {"r2env_path": r2env_path}
cmd = "r2 -v"
R2Env().shell(cmd)
mock_system.assert_called_with(f"export PS1=\"r2env ()\\$ \";"
mock_system.assert_called_with(f"export PS1=\"r2env\\$ \";"
f"export PKG_CONFIG_PATH=\"{r2env_path}/lib/pkgconfig\";"
f"export PATH=\"{r2env_path}/bin:$PATH\";"
f"$SHELL -f -c \'{cmd}\'")
-6
View File
@@ -395,9 +395,3 @@ class TestPackageManager(unittest.TestCase):
mock_distname.return_value = "non_existent"
with self.assertRaises(PackageManagerException):
self.package_manager._uninstall_from_dist("radare2", "1.0.0")
@patch("r2env.package_manager.host_distname")
def test_acr_not_supported_on_windows(self, mock_distname):
mock_distname.return_value = "w64"
with self.assertRaises(PackageManagerException):
self.package_manager._build_using_acr("source", "dest", "logfile", "r2env")
+2 -7
View File
@@ -81,12 +81,7 @@ def git_fetch(url, version, source_path):
f"Verify the source path is not dirty. Error: {err}") \
from err
if version != "git":
try:
repo.git.checkout(version)
except git.GitCommandError:
# try again after pulling new tags from origin
repo.git.fetch("origin", "--tags")
repo.git.checkout(version)
repo.git.checkout(version)
sms = repo.submodules
for sm in sms:
if not sm.module_exists():
@@ -105,7 +100,7 @@ def exists(tool):
def exit_if_not_exists(tools):
for tool in tools:
if not exists(tool):
raise PackageManagerException(f"[x] {tool} is required. Please install it first")
raise PackageManagerException("[x] {} is required. Please install it first")
def load_json_file(filepath):
+1 -1
View File
@@ -1 +1 @@
0.5.9
0.4.2
-1
View File
@@ -1,5 +1,4 @@
dploy>=0.1.2
colorama>=0.4.4
wget
requests
GitPython
-1
View File
@@ -35,7 +35,6 @@ install_requires=
dploy >= 0.1.2
colorama >= 0.4.4
GitPython
requests
setup_requires =
setuptools_scm >= 1.15
include_package_data = True
+1 -4
View File
@@ -5,8 +5,5 @@ from setuptools import setup
setup(
setup_requires=['pbr'],
pbr=True,
package_files=[
('config', ['r2env/config/config.json']),
('', ['version.txt'])
]
package_files=[('config', ['r2env/config/config.json', 'r2env/config/profiles.json'])]
)
+1 -2
View File
@@ -3,11 +3,10 @@ envlist = py{38,39,310}-{tests},{py38,py39,310}-codecheck-{pylint,flake8,bandit}
skipsdist = True
[testenv]
allowlist_externals = bash
deps = -r {toxinidir}/requirements/test.txt
passenv = *
commands =
py{38,39,310}-tests: bash {toxinidir}/run_tests.sh unit
py{38,39,310}-tests: {toxinidir}/run_tests.sh unit
py{38,39,310}-codecheck-pylint: pylint r2env
py{38,39,310}-codecheck-flake8: flake8 r2env
py{38,39,310}-codecheck-bandit: bandit -c .bandit.yml -r r2env