mirror of
https://github.com/radareorg/r2env.git
synced 2026-11-07 23:03:20 -10:00
Compare commits
50
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8c0577ad14 | ||
|
|
50f444dab0 | ||
|
|
db4e174ecf | ||
|
|
9ada5d4322 | ||
|
|
47c5b9feab | ||
|
|
e94f9c07af | ||
|
|
ef703be9fe | ||
|
|
b0c2e38ece | ||
|
|
aa4a5170cd | ||
|
|
01e2b5efaa | ||
|
|
d58b97085c | ||
|
|
e15c4249a3 | ||
|
|
2a7f1893f1 | ||
|
|
378adc688a | ||
|
|
092eda37ea | ||
|
|
068f103a89 | ||
|
|
6c0c26aa0b | ||
|
|
29fa15b555 | ||
|
|
fdd5602970 | ||
|
|
684d6d5211 | ||
|
|
bf6ff7d2db | ||
|
|
30e319f3fb | ||
|
|
7c948fab24 | ||
|
|
b9089e9b2d | ||
|
|
0fa2cf4a87 | ||
|
|
35f1c4152e | ||
|
|
7ece62f905 | ||
|
|
4323295829 | ||
|
|
444974cf0a | ||
|
|
9b60d72a55 | ||
|
|
c9e7123fad | ||
|
|
48ca2997e9 | ||
|
|
57db2d1f7a | ||
|
|
4d03c87bf1 | ||
|
|
eb7dfa643a | ||
|
|
f8fbc50505 | ||
|
|
8606f42ceb | ||
|
|
a37787570a | ||
|
|
58a2e071ab | ||
|
|
96fd4aab0a | ||
|
|
ff9fd6fa3d | ||
|
|
be5154450d | ||
|
|
24bfde5f9b | ||
|
|
129e96b506 | ||
|
|
26919c415a | ||
|
|
e9e08436cb | ||
|
|
3613127925 | ||
|
|
3c0dd5a10e | ||
|
|
a455d306b4 | ||
|
|
7513c6d1b6 |
No files matched your search
@@ -1,10 +1,14 @@
|
||||
name: CI
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
# schedule:
|
||||
# - cron: '0 0 * * 1'
|
||||
|
||||
@@ -13,6 +17,7 @@ jobs:
|
||||
pylint:
|
||||
name: codecheck-pylint
|
||||
runs-on: ubuntu-20.04
|
||||
continue-on-error: true
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
@@ -23,6 +28,7 @@ jobs:
|
||||
flake8:
|
||||
name: codecheck-flake8
|
||||
runs-on: ubuntu-20.04
|
||||
continue-on-error: true
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
@@ -38,15 +44,38 @@ jobs:
|
||||
uses: actions/checkout@v2
|
||||
- name: Install
|
||||
run: sudo pip install . --force-reinstall
|
||||
- name: Initializing
|
||||
run: r2env init
|
||||
- name: Execute r2env
|
||||
run: r2env list
|
||||
- name: Install r2 using r2env
|
||||
run: |
|
||||
r2env init
|
||||
r2env install radare2@latest
|
||||
- name: Execute latest r2 version
|
||||
[ "`r2env | wc -l`" -gt 10 ] # measure help message
|
||||
[ "`r2env -l | wc -l`" -gt 6 ] # measure pkgs
|
||||
r2env install radare2@git
|
||||
- name: Execute git version of r2
|
||||
run: |
|
||||
r2env use radare2@latest
|
||||
r2env use radare2@git
|
||||
$HOME/.r2env/bin/r2 -v
|
||||
r2env shell "r2 -v"
|
||||
- name: Uninstalling
|
||||
run: sudo pip uninstall -y r2env && rm -rf $HOME/.r2env
|
||||
release-job:
|
||||
name: Publish package
|
||||
runs-on: ubuntu-20.04
|
||||
needs: [integration-tests, flake8, pylint]
|
||||
if: github.event_name == 'release' && github.event.action == 'published'
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
- name: Install Dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install -r requirements/dist.txt
|
||||
- name: Build
|
||||
run: python setup.py sdist
|
||||
- name: Publish
|
||||
uses: pypa/gh-action-pypi-publish@release/v1
|
||||
with:
|
||||
user: __token__
|
||||
password: ${{ secrets.TWINE_PASSWORD }}
|
||||
@@ -0,0 +1,70 @@
|
||||
# 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
|
||||
@@ -1,3 +1,8 @@
|
||||
.idea
|
||||
**/__pycache__/
|
||||
venv
|
||||
.DS_Store
|
||||
AUTHORS
|
||||
ChangeLog
|
||||
dist/*
|
||||
r2env.egg-info
|
||||
@@ -4,7 +4,9 @@ all:
|
||||
pip install .
|
||||
|
||||
pub:
|
||||
twine upload --repository-url https://upload.pypi.org/legacy/ --verbose dist/*
|
||||
rm -rf dist
|
||||
$(PYTHON) setup.py sdist
|
||||
twine upload --repository=pypi --verbose dist/*
|
||||
|
||||
install:
|
||||
pip install .
|
||||
|
||||
@@ -1,53 +1,29 @@
|
||||
r2env
|
||||
=====
|
||||
# r2env
|
||||
|
||||
[](https://github.com/radareorg/r2env/actions/workflows/ci.yml)
|
||||
|
||||
This repository contains the tool available via pip to install
|
||||
and manage multiple versions of radare2 and its plugins.
|
||||
Create self-contained environments with multiple versions of radare2
|
||||
and plugins, make it easy to switch between them.
|
||||
|
||||
r2-tools doesn't conflict with r2pm in the sense that it's not
|
||||
going to support all the packages and plugins and it's
|
||||
* Build from source or install the system package if available.
|
||||
|
||||
r2env supports source and binary packages.
|
||||
## Installation
|
||||
|
||||
Dependencies
|
||||
------------
|
||||
r2env is available via PIP.
|
||||
|
||||
* r2env should be self contained
|
||||
* `pip install -U -f r2env`
|
||||
|
||||
Some tools may be used if installed in the system, making some
|
||||
packages available, but we may try to use python-version if
|
||||
possible, so it don't depend on system packages.
|
||||
If you want to try it directly from source.
|
||||
|
||||
Package description
|
||||
-------------------
|
||||
INI, JSON or python class, loaded at runtime, but it is k=v stuff
|
||||
* `pip install .`
|
||||
|
||||
* name: iaito
|
||||
* platform: windows
|
||||
* version: 5.2.1
|
||||
* source: https://path/to/zip
|
||||
## Usage
|
||||
|
||||
Actions
|
||||
-------
|
||||
* install / uninstall
|
||||
* link / unlink
|
||||
* update - pip install -U r2env
|
||||
* upgrade - upgrade r2 and all the deps in sync
|
||||
First we need to initialize the working directory:
|
||||
|
||||
|
||||
How to install
|
||||
--------------
|
||||
|
||||
r2env is available via PIP. (`pip install r2env`)
|
||||
|
||||
To build + install from source just run: `make`
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
First of all you may want to initialize the `.r2env` directory somewhere with `cd .. ; r2env init`.
|
||||
```
|
||||
r2env init
|
||||
```
|
||||
|
||||
Listing available packages is done via `r2env list`.
|
||||
|
||||
@@ -56,18 +32,56 @@ Source packages are managed with the `add`, `rm`, `use` and `unused`.
|
||||
For example: Installing radare2 (assumes @git version)
|
||||
|
||||
```
|
||||
cd /tmp
|
||||
r2env init
|
||||
r2env add radare2
|
||||
r2env use radare2@git
|
||||
r2env shell r2 -v
|
||||
r2env shell "r2 -v"
|
||||
```
|
||||
|
||||
r2pm vs r2env
|
||||
-------------
|
||||
## Help
|
||||
|
||||
```
|
||||
Usage: r2env [-flags] [action] [args...]
|
||||
|
||||
Flags:
|
||||
|
||||
-h, --help - show this help
|
||||
-v, --version - display r2env version
|
||||
-m, --meson - use meson instead of acr
|
||||
-p, --package - install the dist package instead of building
|
||||
-l, --list - list available and installed packages
|
||||
|
||||
Actions:
|
||||
|
||||
init - create ~/.r2env directory
|
||||
config - display current .r2env settings
|
||||
add [pkg] - build and install given package. See -p and -m
|
||||
use [pkg] - use r2 package defined. pkg should be a release version or git.
|
||||
rm [pkg] - remove package from ~/.r2env
|
||||
path - show path of current r2 in use
|
||||
version - show version of r2env
|
||||
versions - list installed packages
|
||||
list - list all packages available to r2env
|
||||
shell - enter a new shell with PATH env var set
|
||||
purge - remove ~/.r2env
|
||||
|
||||
Environment
|
||||
|
||||
R2ENV_PATH - specify different path other than ~/.r2env
|
||||
|
||||
```
|
||||
|
||||
## r2pm vs r2env
|
||||
|
||||
r2env aims to provide a packaging for r2 with support for binary packages and for all major platforms.
|
||||
|
||||
r2pm focus on providing more packages, it's written in shellscript, so it doesnt run on windows and requires r2 to work.
|
||||
|
||||
Therefor r2env is kind of `nvm` from nodejs or `pyenv` from python. A way to run multiple different versions of r2 in the system.
|
||||
|
||||
This repository contains the tool available via pip to install
|
||||
and manage multiple versions of radare2 and its plugins.
|
||||
|
||||
r2-tools doesn't conflict with r2pm in the sense that it's not
|
||||
going to support all the packages and plugins and it's
|
||||
|
||||
@@ -1,10 +1,37 @@
|
||||
{
|
||||
"radare0": {
|
||||
"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": "latest",
|
||||
"packages:": {}
|
||||
"id": "git",
|
||||
"packages": {}
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -13,20 +40,52 @@
|
||||
"versions": [
|
||||
{
|
||||
"id": "5.3.0",
|
||||
"packages:": {
|
||||
"packages": {
|
||||
"w64": "radare2-5.3.0-w64.zip",
|
||||
"deb_x64": "radare2_5.3.0_amd64.deb"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "5.3.1",
|
||||
"packages:": {
|
||||
|
||||
"packages": {
|
||||
"w64": "radare2-5.3.1-w64.zip",
|
||||
"mac_x64": "radare2-5.3.1.pkg",
|
||||
"deb_x64": "radare2_5.3.1_amd64.deb"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "latest",
|
||||
"packages:": {}
|
||||
"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": "git",
|
||||
"packages": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
+49
-19
@@ -1,7 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
|
||||
import json
|
||||
import sys
|
||||
@@ -38,43 +38,56 @@ class R2Env:
|
||||
print_console("[*] Current r2env config:")
|
||||
print_console(json.dumps(self._config))
|
||||
|
||||
def list_packages(self):
|
||||
self.list_available_packages()
|
||||
self.list_installed_packages()
|
||||
|
||||
def list_available_packages(self):
|
||||
print_console("[*] List of available Radare packages")
|
||||
print_console("- Available")
|
||||
packages = self._package_manager.list_available_packages()
|
||||
for profile in packages:
|
||||
print_console(" - {} packages:".format(profile), WARNING)
|
||||
print_console(" - {}:".format(profile), WARNING)
|
||||
for version in packages[profile]['versions']:
|
||||
print_console(" {}@{}".format(profile, version['id']), formatter=1)
|
||||
dists = ", ".join(version['packages'].keys())
|
||||
print_console(" - {}@{} - {}".format(profile, version['id'], dists), formatter=1)
|
||||
|
||||
def list_installed_packages(self):
|
||||
self.exit_if_r2env_not_initialized()
|
||||
print_console("[*] Installed Radare packages")
|
||||
print_console("- Installed")
|
||||
for pkg in self._package_manager.list_installed_packages():
|
||||
if pkg == self._get_current_version():
|
||||
print_console(" [*] {}".format(pkg))
|
||||
print_console(" - {} (in use)".format(pkg))
|
||||
else:
|
||||
print_console(" - {}".format(pkg))
|
||||
|
||||
def install(self, package, use_meson=False):
|
||||
def install(self, package, use_meson=False, use_dist=False):
|
||||
self.exit_if_r2env_not_initialized()
|
||||
if not self._check_package_format(package):
|
||||
print_console("[x] Invalid Package format.", level=ERROR)
|
||||
print_console("[x] Invalid package format.", level=ERROR)
|
||||
return
|
||||
profile, version = package.split('@')
|
||||
self._package_manager.install_package(profile, version, use_meson=use_meson)
|
||||
print_console("[*] Magic Done! Remember to add the $HOME/.r2env/bin folder to your PATH.")
|
||||
try:
|
||||
profile, version = package.split('@')
|
||||
except:
|
||||
profile = package
|
||||
version = "git"
|
||||
self._package_manager.install_package(profile, version, use_meson=use_meson, use_dist=use_dist)
|
||||
print_console("[*] Add $HOME/.r2env/bin to your PATH or use 'r2env shell'.")
|
||||
|
||||
def uninstall(self, package):
|
||||
def uninstall(self, package, use_meson, use_dist):
|
||||
self.exit_if_r2env_not_initialized()
|
||||
if not self._check_package_format(package):
|
||||
print_console("[x] Invalid Package format.", level=ERROR)
|
||||
print_console("[x] Invalid package format.", level=ERROR)
|
||||
return
|
||||
self._package_manager.uninstall_package(package)
|
||||
self._package_manager.uninstall_package(package, use_dist)
|
||||
|
||||
def purge(self):
|
||||
print("Removing " + self._r2env_path)
|
||||
shutil.rmtree(self._r2env_path)
|
||||
|
||||
def use(self, package=None):
|
||||
self.exit_if_r2env_not_initialized()
|
||||
if not package:
|
||||
print_console("[x] Package not defined. Please use 'r2env use' with one installed package. ", ERROR)
|
||||
print_console("[x] Package not defined.", ERROR)
|
||||
self.list_installed_packages()
|
||||
return
|
||||
cur_ver = self._get_current_version()
|
||||
@@ -87,11 +100,21 @@ class R2Env:
|
||||
|
||||
@staticmethod
|
||||
def version():
|
||||
with open("version.txt", "r") as version:
|
||||
thispath = os.path.dirname(os.path.realpath(__file__))
|
||||
with open(thispath + "/version.txt", "r") as version:
|
||||
return version.read()
|
||||
|
||||
def shell(self, cmd=""):
|
||||
line = "export PS1=\"r2env\\$ \";export PATH=\"" + self._r2env_path + "/bin:$PATH\"; $SHELL -f"
|
||||
if os.name== "nt":
|
||||
os.system("set PATH="+self._r2env_path+"\\bin;%PATH% && cmd")
|
||||
return True
|
||||
line = "export PS1=\"r2env\\$ \";export PKG_CONFIG_PATH=\""
|
||||
line = line + self._r2env_path+"/lib/pkgconfig\";export PATH=\""
|
||||
line = line + self._r2env_path + "/bin:$PATH\"; $SHELL -f"
|
||||
if os.path.isfile("/default.prop"): # hack for pre-dtag builds of r2
|
||||
line = "export LD_LIBRARY_PATH=\"" + self._r2env_path + "/lib\";" + line
|
||||
if os.uname().sysname == "Darwin":
|
||||
line = "export DYLD_LIBRARY_PATH=\"" + self._r2env_path + "/lib\";" + line
|
||||
if cmd.strip() == "":
|
||||
return os.system(line)
|
||||
return os.system(line + " -c '" + cmd + "'")
|
||||
@@ -100,18 +123,25 @@ class R2Env:
|
||||
def _load_config():
|
||||
filename = os.path.join(os.path.dirname(__file__), 'config', 'config.json')
|
||||
config = load_json_file(filename)
|
||||
ep = os.getenv("R2ENV_PATH")
|
||||
if ep is not None:
|
||||
config["r2env_path"] = ep
|
||||
if not config:
|
||||
sys.exit(-1)
|
||||
return config
|
||||
|
||||
@staticmethod
|
||||
def _get_default_path():
|
||||
# TODO: try to find an .r2env starting in current directory
|
||||
return os.path.join(Path.home(), ".r2env")
|
||||
|
||||
@staticmethod
|
||||
def _check_package_format(package):
|
||||
regexp = re.compile(r"\w+\d@(?:\d\.\d\.\d|latest)")
|
||||
return regexp.match(package)
|
||||
if package == "":
|
||||
return True
|
||||
return True
|
||||
# regexp = re.compile(r"\w+\d@(?:\d\.\d\.\d|git)")
|
||||
# return regexp.match(package)
|
||||
|
||||
def _get_current_version(self):
|
||||
version_file = os.path.join(self._r2env_path, self.VERSION_FILE)
|
||||
|
||||
+115
-21
@@ -2,11 +2,13 @@
|
||||
|
||||
import os
|
||||
import shutil
|
||||
import wget
|
||||
import sys
|
||||
import time
|
||||
|
||||
from r2env.tools import load_json_file, git_fetch, git_clean, print_console, ERROR, exit_if_not_exists
|
||||
from zipfile import ZipFile
|
||||
|
||||
from r2env.tools import load_json_file, git_fetch, git_clean, print_console, ERROR, exit_if_not_exists, host_distname
|
||||
|
||||
class PackageManager:
|
||||
|
||||
@@ -41,7 +43,7 @@ class PackageManager:
|
||||
sys.exit(-1)
|
||||
return profiles
|
||||
|
||||
def install_package(self, profile, version, use_meson):
|
||||
def install_package(self, profile, version, use_meson, use_dist):
|
||||
log_path = os.path.join(self._r2env_path, self.LOG_DIR)
|
||||
logfile = os.path.join(log_path, "{}_{}_{}_build.txt".format(profile, version, round(time.monotonic() * 1000)))
|
||||
source_path = os.path.join(os.path.join(self._r2env_path, self.SOURCE_DIR, profile))
|
||||
@@ -53,7 +55,12 @@ class PackageManager:
|
||||
if not os.path.isdir(dst_dir):
|
||||
os.makedirs(dst_dir)
|
||||
self._exit_if_package_not_available(profile, version)
|
||||
if self._build_from_source(profile, version, source_path, dst_dir, logfile, use_meson=use_meson):
|
||||
if use_dist:
|
||||
if self._install_from_dist(profile, version, source_path, dst_dir, logfile, use_meson=use_meson):
|
||||
print_console("[*] Binary package {}@{} installed successfully".format(profile, version))
|
||||
else:
|
||||
print_console("Error.")
|
||||
elif self._build_from_source(profile, version, source_path, dst_dir, logfile, use_meson=use_meson):
|
||||
print_console("[*] Package {}@{} installed successfully".format(profile, version))
|
||||
else:
|
||||
print_console("[x] Something wrong happened during the build process. Check {} for more information.".format
|
||||
@@ -61,23 +68,105 @@ class PackageManager:
|
||||
if os.path.isdir(dst_dir):
|
||||
shutil.rmtree(dst_dir)
|
||||
|
||||
def uninstall_package(self, package_name):
|
||||
def uninstall_package(self, package_name, use_dist):
|
||||
pkg_found = False
|
||||
for package in self.list_installed_packages():
|
||||
if package_name == package:
|
||||
pkg_found = True
|
||||
pkg_dir = os.path.join(os.path.join(self._r2env_path, self.PACKAGES_DIR), package_name)
|
||||
try:
|
||||
shutil.rmtree(pkg_dir)
|
||||
print_console("Removed package {}".format(package_name))
|
||||
except OSError as err:
|
||||
print_console("[x] Unable to remove package {0}. Error: {1}".format(package_name, err), ERROR)
|
||||
if use_dist:
|
||||
kv = package.split("@")
|
||||
self._uninstall_from_dist(kv[0], kv[1])
|
||||
else:
|
||||
pkg_dir = os.path.join(os.path.join(self._r2env_path, self.PACKAGES_DIR), package_name)
|
||||
try:
|
||||
shutil.rmtree(pkg_dir)
|
||||
print_console("Removed package {}".format(package_name))
|
||||
except OSError as err:
|
||||
print_console("[x] Unable to remove package {0}. Error: {1}".format(package_name, err), ERROR)
|
||||
break
|
||||
if not pkg_found:
|
||||
print_console("[x] Unable to find installed package {0}".format(package_name), ERROR)
|
||||
|
||||
def _build_from_package(self):
|
||||
pass
|
||||
def _get_pkgname(self, profile, version, cos):
|
||||
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):
|
||||
gh = "https://github.com/radareorg/radare2/releases/download/"
|
||||
f = self._get_pkgname(profile, version, cos)
|
||||
if f is not None:
|
||||
return "/".join([gh, version, f])
|
||||
return None
|
||||
|
||||
def _install_from_dist(self, profile, version, source_path, dst_path, logfile, use_meson=False):
|
||||
print_console("[*] Installing {}@{} package from binary dist".format(profile, version))
|
||||
dn = host_distname()
|
||||
disturl = self._get_disturl(profile, version, dn)
|
||||
pkgname = self._get_pkgname(profile, version, dn)
|
||||
ofile = "/".join([self._r2env_path, "src", pkgname])
|
||||
# os.system("wget -O " + ofile + " -qc " + disturl)
|
||||
wget.download(disturl, ofile);
|
||||
try:
|
||||
sysname = os.uname().sysname
|
||||
except:
|
||||
sysname = "Windows"
|
||||
# TODO: checksum
|
||||
if sysname == "Darwin":
|
||||
if os.system("sudo installer -pkg " + ofile + " -target /") == 0:
|
||||
return True
|
||||
if sysname == "Windows":
|
||||
with ZipFile(ofile, 'r') as z:
|
||||
z.extractall()
|
||||
dst = os.path.sep.join([self._r2env_path, "bin"])
|
||||
for f in z.namelist():
|
||||
if f.endswith(".exe") or f.endswith(".dll") and f.find("bin") != -1:
|
||||
fname = os.path.basename(f)
|
||||
d = os.path.sep.join([dst, fname])
|
||||
dname = os.path.dirname(d)
|
||||
if not os.path.isdir(dname):
|
||||
os.makedirs(dname, 493) # 0755)
|
||||
shutil.copyfile(f, d)
|
||||
print(f)
|
||||
f = os.path.sep.join([self._r2env_path, "bin", "radare2.exe"])
|
||||
d = os.path.sep.join([self._r2env_path, "bin", "r2.exe"])
|
||||
shutil.copyfile(f, d)
|
||||
if sysname == "Linux" and os.path.exists("/usr/bin/dpkg"):
|
||||
if os.system("sudo dpkg -i " + ofile) == 0:
|
||||
return True
|
||||
if os.path.isfile("/default.prop"): # termux
|
||||
if os.system("apt install radare2") == 0:
|
||||
return True
|
||||
return False
|
||||
return False
|
||||
|
||||
def _uninstall_from_dist(self, profile, version):
|
||||
print_console("[*] Uninstalling {}@{} package from binary dist".format(profile, version))
|
||||
try:
|
||||
sysname = os.uname().sysname
|
||||
except:
|
||||
sysname = "Windows"
|
||||
if sysname == "Darwin":
|
||||
pkgname = "org.radare.radare2"
|
||||
os.system("pkgutil --pkg-info " + pkgname)
|
||||
os.system("cd / && pkgutil --only-files --files "+pkgname+" | tr '\\n' '\\0' | xargs -n 1 -0 sudo rm -f")
|
||||
os.system("cd / && pkgutil --only-dirs --files "+pkgname+" | tail -r | tr '\\n' '\\0' | xargs -n 1 -0 sudo rmdir 2>/dev/null")
|
||||
os.system("sudo pkgutil --forget " + pkgname)
|
||||
if sysname == "Linux" and os.path.exists("/usr/bin/dpkg"):
|
||||
try:
|
||||
pkgname = profile.split("@")[0]
|
||||
except:
|
||||
pkgname = profile
|
||||
if os.system("sudo dpkg -r " + pkgname) == 0:
|
||||
return True
|
||||
if os.path.isfile("/default.prop"): # termux
|
||||
if os.system("sudo dpkg -r radare2") == 0:
|
||||
return True
|
||||
return False
|
||||
return True
|
||||
|
||||
def _build_from_source(self, profile, version, source_path, dst_path, logfile, use_meson=False):
|
||||
exit_if_not_exists(['git'])
|
||||
@@ -87,24 +176,29 @@ class PackageManager:
|
||||
print_console("[-] Cleaning Repo")
|
||||
git_clean(source_path)
|
||||
if use_meson:
|
||||
return self._build_using_meson(source_path, dst_path, logfile)
|
||||
return self._build_using_acr(source_path, dst_path, logfile)
|
||||
return self._build_using_meson(source_path, dst_path, logfile, self._r2env_path)
|
||||
return self._build_using_acr(source_path, dst_path, logfile, self._r2env_path)
|
||||
|
||||
@staticmethod
|
||||
def _build_using_acr(source_path, dst_path, logfile):
|
||||
def _build_using_acr(source_path, dst_path, logfile, r2env_path):
|
||||
"""Only works in Unix systems"""
|
||||
exit_if_not_exists(['make'])
|
||||
print_console("[-] Building package using acr ...")
|
||||
cmd = "(cd {0} && rm -rf shlr/capstone && ./configure --with-rpath --prefix={1} 2>&1 && make -j4 2>&1" \
|
||||
"&& make install) > {2}".format(source_path, dst_path, logfile)
|
||||
print_console("[-] Building package using acr...")
|
||||
extra_flags = ""
|
||||
if os.path.isfile("/default.prop"):
|
||||
extra_flags = " --with-compiler=termux"
|
||||
cmd = "(export PKG_CONFIG_PATH=\"{4}\";cd {0} && rm -rf shlr/capstone && ./configure {1}" \
|
||||
" --with-rpath --prefix={2} 2>&1 && make -j4 2>&1" \
|
||||
"&& make install) > {3}".format(source_path, extra_flags, dst_path, logfile, r2env_path + "/lib/pkgconfig")
|
||||
print(cmd)
|
||||
return os.system(cmd) == 0
|
||||
|
||||
@staticmethod
|
||||
def _build_using_meson(source_path, dst_path, logfile):
|
||||
def _build_using_meson(source_path, dst_path, logfile, r2env_path):
|
||||
exit_if_not_exists(['meson', 'ninja'])
|
||||
print_console("[-] Building package using meson ...")
|
||||
cmd = "(cd {0} && rm -rf build && meson . build --buildtype=release --prefix={1} -Dlocal=true 2>&1" \
|
||||
"&& ninja -C build && ninja -C build install) > {2}".format(source_path, dst_path, logfile)
|
||||
cmd = "(export PKG_CONFIG_PATH=\"{4}\";cd {0} && rm -rf build && meson . build --buildtype=release --prefix={1} -Dlocal=true 2>&1" \
|
||||
"&& ninja -C build && ninja -C build install) > {2}".format(source_path, dst_path, logfile,r2env_path + "/lib/pkgconfig")
|
||||
return os.system(cmd) == 0
|
||||
|
||||
def _exit_if_package_not_available(self, profile, version):
|
||||
|
||||
+73
-39
@@ -8,18 +8,31 @@ from r2env.core import R2Env
|
||||
|
||||
|
||||
HELP_MESSAGE = """
|
||||
Usage: r2env [action] [args...]
|
||||
Usage: r2env [-flags] [action] [args...]
|
||||
|
||||
Flags:
|
||||
|
||||
-h, --help - show this help.
|
||||
-v, --version - display r2env version.
|
||||
-m, --meson - use meson instead of acr.
|
||||
-p, --package - install the dist package instead of building
|
||||
-l, --list - list available and installed packages
|
||||
|
||||
Actions:
|
||||
|
||||
init - create .r2env in current directory
|
||||
config - display current .r2env settings
|
||||
install [pkg] - build and install given package. Use --meson to use it as the build system.
|
||||
uninstall [pkg] - remove selected package
|
||||
use [pkg] - use r2 package defined. pkg should be a release version or latest.
|
||||
version - show the current Radare version and its origin
|
||||
versions - List all Radare versions installed
|
||||
list - list all Radare packages available to r2env
|
||||
shell - open a new shell with PATH env var set
|
||||
init - create ~/.r2env directory.
|
||||
config - display current .r2env settings.
|
||||
add [pkg] - build and install given package. See -p and -m
|
||||
use [pkg] - stow a specific version to be the default.
|
||||
rm [pkg] - remove package from ~/.r2env
|
||||
path - show path of current r2 in use.
|
||||
list - list all packages available to r2env.
|
||||
shell - enter a new shell with PATH env var set.
|
||||
purge - remove ~/.r2env
|
||||
|
||||
Environment
|
||||
|
||||
R2ENV_PATH - specify different path other than ~/.r2env
|
||||
|
||||
"""
|
||||
|
||||
@@ -28,60 +41,81 @@ def show_help():
|
||||
print_console(HELP_MESSAGE)
|
||||
|
||||
|
||||
actions_with_argument = ["install", "uninstall", "use"]
|
||||
actions_with_arguments = ["shell"]
|
||||
def show_version():
|
||||
print_console(R2Env().version())
|
||||
|
||||
|
||||
actions_with_argument = ["add", "install", "rm", "uninstall"]
|
||||
actions_with_arguments = ["sh", "shell", "use"]
|
||||
actions = {
|
||||
"init": R2Env().init,
|
||||
"version": R2Env().get_r2_path,
|
||||
"config": R2Env().show_config,
|
||||
"list": R2Env().list_available_packages,
|
||||
"install": R2Env().install,
|
||||
"v": show_version,
|
||||
"version": show_version,
|
||||
"path": R2Env().get_r2_path,
|
||||
"sh": R2Env().shell,
|
||||
"shell": R2Env().shell,
|
||||
"config": R2Env().show_config,
|
||||
"ls": R2Env().list_packages,
|
||||
"list": R2Env().list_packages,
|
||||
"add": R2Env().install,
|
||||
"install": R2Env().install,
|
||||
"installed": R2Env().list_installed_packages,
|
||||
"uninstall": R2Env().uninstall,
|
||||
"rm": R2Env().uninstall,
|
||||
"use": R2Env().use,
|
||||
"versions": R2Env().list_installed_packages,
|
||||
"purge": R2Env().purge,
|
||||
"h": show_help,
|
||||
"help": show_help
|
||||
}
|
||||
|
||||
|
||||
def run_action(action, args, use_meson):
|
||||
if action not in actions:
|
||||
print_console("[X] Action not found", ERROR)
|
||||
def run_action(argp):
|
||||
action = ""
|
||||
args = []
|
||||
if len(argp.args) > 0:
|
||||
action = argp.args[0]
|
||||
if len(argp.args) > 1:
|
||||
args = argp.args[1:]
|
||||
if argp.version:
|
||||
print_console(R2Env().version())
|
||||
elif argp.list:
|
||||
actions["list"]()
|
||||
elif action == "":
|
||||
show_help()
|
||||
elif action not in actions:
|
||||
print_console("Invalid action", ERROR)
|
||||
elif action in actions_with_arguments:
|
||||
actions[action](" ".join(args))
|
||||
elif action in actions_with_argument:
|
||||
exit_if_not_argument_is_set(args, action)
|
||||
if action == "install":
|
||||
actions[action](args[0], use_meson=use_meson)
|
||||
else:
|
||||
actions[action](args[0])
|
||||
actions[action](args[0], use_meson=argp.meson, use_dist=argp.package)
|
||||
else:
|
||||
actions[action]()
|
||||
|
||||
|
||||
def exit_if_not_argument_is_set(args, action):
|
||||
if len(args) < 1:
|
||||
if action == "use":
|
||||
print_console("[x] Package not defined. Please use 'r2env use' with one installed package. ", ERROR)
|
||||
actions["versions"]()
|
||||
if action in ["use", "rm", "uninstall"]:
|
||||
print_console("[x] Package not defined.", ERROR)
|
||||
R2Env().list_installed_packages()
|
||||
else:
|
||||
print_console("[x] Missing package argument. ( as for example: radare2@latest)", ERROR)
|
||||
print_console("[x] Missing package argument. ( as for example: radare2@latest)", ERROR)
|
||||
print_console("[x] Missing package argument.", ERROR)
|
||||
R2Env().list_available_packages()
|
||||
sys.exit(-1)
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("action", help="run specified action. (Run r2env help for more information)",
|
||||
action="store", default=["help"])
|
||||
parser.add_argument('args', metavar='args', nargs='*', type=str, help='Specified arguments')
|
||||
parser.add_argument("-v", "--version", help="Show r2env version", action="store_true")
|
||||
parser.add_argument("-m", "--meson", help="Use meson as your build system.", action="store_true")
|
||||
args = parser.parse_args()
|
||||
if args.version:
|
||||
print_console(R2Env().version())
|
||||
return
|
||||
run_action(args.action, args.args, args.meson)
|
||||
parser.add_argument("args", help="run specified action. (Run r2env help for more information)",
|
||||
action="store", nargs="*", default=[])
|
||||
#parser.add_argument('args', metavar='args', nargs='+', type=str, help='Specified arguments')
|
||||
parser.add_argument("-v", "--version", dest="version", help="Show r2env version", action="store_true")
|
||||
parser.add_argument("-m", "--meson", dest="meson", help="Use meson instead of acr to compile", action="store_true")
|
||||
parser.add_argument("-p", "--package", dest="package", help="Use binary package for target system if available", action="store_true")
|
||||
parser.add_argument("-l", "--list", dest="list", help="List available and installed packages", action="store_true")
|
||||
parser.print_help = show_help
|
||||
argp = parser.parse_args()
|
||||
run_action(argp)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
+35
-1
@@ -19,6 +19,9 @@ def print_console(msg, level=INFO, formatter=0):
|
||||
tabs, color = ["", ""]
|
||||
for _ in range(formatter):
|
||||
tabs += " "
|
||||
if os.name == 'nt':
|
||||
print(tabs + msg)
|
||||
return
|
||||
if level == ERROR:
|
||||
color = Fore.RED
|
||||
elif level == WARNING:
|
||||
@@ -34,14 +37,45 @@ def host_platform():
|
||||
return "unix"
|
||||
|
||||
|
||||
# TODO :improve to support all archs
|
||||
def host_distname():
|
||||
try:
|
||||
sysname = os.uname().sysname
|
||||
machine = os.uname().machine
|
||||
except:
|
||||
sysname = "w64"
|
||||
machine = "amd64"
|
||||
if sysname == "Darwin":
|
||||
if machine == "x86_64":
|
||||
return "mac_x64"
|
||||
if machine == "arm64":
|
||||
return "mac_arm64"
|
||||
return None
|
||||
if sysname == "Linux":
|
||||
if not os.path.exists("/usr/bin/dpkg"):
|
||||
return None
|
||||
if machine == "x86_64":
|
||||
return "deb_x64"
|
||||
return "deb_i386"
|
||||
if os.name == "nt":
|
||||
return "w64"
|
||||
if os.path.isfile("/default.prop"):
|
||||
return "android"
|
||||
return None
|
||||
|
||||
|
||||
def git_fetch(url, version, source_path):
|
||||
if os.path.isdir(os.path.join(source_path, ".git")):
|
||||
repo = Repo(source_path)
|
||||
repo.remotes.origin.pull("master")
|
||||
else:
|
||||
repo = Repo.clone_from(url, source_path)
|
||||
if version != "latest":
|
||||
if version != "git":
|
||||
repo.git.checkout(version)
|
||||
sms = repo.submodules
|
||||
for sm in sms:
|
||||
if not sm.module_exists():
|
||||
sm.update()
|
||||
|
||||
|
||||
def git_clean(source_path):
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
0.3.0
|
||||
0.4.2
|
||||
@@ -1,3 +1,4 @@
|
||||
dploy>=0.1.2
|
||||
colorama>=0.4.4
|
||||
wget
|
||||
GitPython
|
||||
@@ -0,0 +1,5 @@
|
||||
-r build.txt
|
||||
pip
|
||||
pbr
|
||||
setuptools
|
||||
twine
|
||||
@@ -1,11 +1,12 @@
|
||||
[metadata]
|
||||
license_file = LICENSE
|
||||
version = 0.2.2
|
||||
name = r2env
|
||||
author = 'pancake, murphy'
|
||||
author_email = '[email protected], [email protected]'
|
||||
author = pancake
|
||||
# author_email = '[email protected], [email protected]'
|
||||
author_email = [email protected]
|
||||
description = radare2 multiple version and environment installation tool
|
||||
long_description = file:README.md
|
||||
long_description_content_type = text/markdown
|
||||
url = https://www.radare.org/
|
||||
project_urls =
|
||||
Source = https://github.com/radareorg/r2env
|
||||
|
||||
Reference in new issue
Block a user