-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Release v1.2.0: Support for python3.5 fixed, auto detect args
- Loading branch information
1 parent
4546f59
commit 6cc2a46
Showing
3 changed files
with
208 additions
and
61 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -109,4 +109,90 @@ The advantages of ELF*2*deb is; | |
|
||
* can be installed using `pip install elf2deb` or used a as a standalone executable `./elf2deb.pyz` | ||
|
||
* simple, small size (7 kB), and few dependencies (python3 and requests) | ||
* simple, small size (< 10 kB), and few dependencies: `>= python3.5` (+ `requests` if need to download a license file) | ||
|
||
## More examples (interactive!) | ||
|
||
In version 1.2.0 a interactive menu was added to ELF*2*deb: | ||
|
||
```bash | ||
$ git clone https://github.com/NicolaiSoeborg/ELF2deb.git && cd ELF2deb/ | ||
$ make # to make 'elf2deb.pyz' (or use pip to install globally, or carry/copy elf2deb.pyz around) | ||
$ ./elf2deb.pyz elf2deb.pyz # package 'elf2deb.pyz' using elf2deb (very meta!) | ||
Package info: | ||
author_mail: [email protected] | ||
author_name: Nicolai Søborg | ||
binary_files: ['elf2deb.pyz'] | ||
dependencies: | ||
homepage: None | ||
license: None | ||
license_file: <_io.TextIOWrapper name='/.../ELF2deb/LICENSE' mode='r' encoding='UTF-8'> | ||
license_holder: None | ||
license_year: None | ||
package_name: ELF2deb | ||
package_version: 0.0.1 | ||
==> Does this look correct? (y/n/q): n | ||
|
||
Properties: | ||
[1] author_mail | ||
[2] author_name | ||
[3] binary_files | ||
[4] dependencies | ||
[5] homepage | ||
[6] license | ||
[7] license_file | ||
[8] license_holder | ||
[9] license_year | ||
[10] package_name | ||
[11] package_version | ||
==> Which property to change? (1..11): 4 | ||
==> Which value should dependencies be changed to? python3, python3-requests | ||
|
||
Package info: | ||
author_mail: [email protected] | ||
author_name: Nicolai Søborg | ||
binary_files: ['elf2deb.pyz'] | ||
dependencies: python3, python3-requests | ||
homepage: None | ||
license: None | ||
license_file: <_io.TextIOWrapper name='/home/nsq/pakker/test/ELF2deb/LICENSE' mode='r' encoding='UTF-8'> | ||
license_holder: None | ||
license_year: None | ||
package_name: ELF2deb | ||
package_version: 0.0.1 | ||
==> Does this look correct? (y/n/q): n | ||
[...] | ||
==> Which value should package_version be changed to? 1.2.0 | ||
[...] | ||
==> Does this look correct? (y/n/q): y | ||
Copying templates... done! | ||
Copying files... done! | ||
Run: | ||
* cd elf2deb-1.2.0 | ||
* vim debian/control # change description, dont add empty lines | ||
* debuild -us -uc # remove -us -uc if you want to sign the deb file | ||
|
||
$ cd elf2deb-1.2.0 | ||
$ vim debian/control | ||
$ debuild -us -uc | ||
[...] | ||
dpkg-deb: building package 'elf2deb' in '../elf2deb_1.2.0_amd64.deb'. | ||
|
||
$ dpkg-deb --info ../elf2deb_1.2.0_amd64.deb | ||
new Debian package, version 2.0. | ||
size 5100 bytes: control archive=624 bytes. | ||
383 bytes, 12 lines control | ||
189 bytes, 3 lines md5sums | ||
Package: elf2deb | ||
Version: 1.2.0 | ||
Architecture: amd64 | ||
Maintainer: Nicolai Søborg <[email protected]> | ||
Installed-Size: 20 | ||
Depends: python3, python3-requests | ||
Section: misc | ||
Priority: optional | ||
Multi-Arch: foreign | ||
Description: tool to easily package any binary to a deb file | ||
ELF2deb makes it easy to package simple binaries to a deb file | ||
to help deploy files across debian environments. | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,74 @@ | ||
import argparse | ||
import os | ||
import shutil | ||
from subprocess import run, DEVNULL | ||
from pathlib import Path | ||
from zipfile import ZipFile | ||
|
||
__version__ = "1.1.0" | ||
__version__ = "1.2.0" | ||
TEMPLATE_DIR = "templates/" | ||
|
||
def main(): | ||
args = get_args() | ||
|
||
# Create app dir: | ||
package_dir = Path("{package_name}-{package_version}".format(**vars(args))) | ||
if package_dir.exists(): | ||
if (input("Folder {} already exists. Delete? (y/n) ".format(package_dir)).lower() == "y"): | ||
shutil.rmtree(str(package_dir)) | ||
package_dir.mkdir(exist_ok=True) | ||
|
||
print("Copying templates... ", end='', flush=True) | ||
try: | ||
# If running from a .pyz file: | ||
me = ZipFile(os.path.dirname(__file__), "r") | ||
except: | ||
# If running from pip: | ||
me = ZipFile(os.path.dirname(__file__) + '/elf2deb.pyz' , "r") | ||
for template in me.filelist: | ||
if template.filename.startswith("__"): | ||
continue # skip dunder files | ||
|
||
target_filename = template.filename[len(TEMPLATE_DIR):] | ||
if template.filename.endswith('/'): | ||
(package_dir / target_filename).mkdir(exist_ok=True) | ||
else: | ||
data = me.read(template).decode().format(**vars(args)) | ||
(package_dir / target_filename).write_text(data) | ||
|
||
if args.license is not None: | ||
copyright_file = package_dir / 'debian/copyright' | ||
copyright_file.write_text(get_copyright(args)) | ||
elif args.license_file is not None: | ||
copyright_file = package_dir / 'debian/copyright' | ||
copyright_file.write_text(args.license_file.read()) | ||
|
||
# Make debian/rules executable: | ||
mode = os.stat(str(package_dir / 'debian/rules')).st_mode | ||
mode |= (mode & 0o444) >> 2 # copy R bits to X | ||
os.chmod(str(package_dir / 'debian/rules'), mode) | ||
print("done!") | ||
|
||
print("Copying files... ", end='', flush=True) | ||
makefile = open(str(package_dir / 'Makefile'), 'at') | ||
for i, binary in enumerate(args.binary_files): | ||
# Copy binary to package base dir: | ||
shutil.copy(binary, str(package_dir / os.path.basename(binary))) | ||
if i > 0: | ||
# Update makefile (TODO: update template to support a list of binaries) | ||
makefile.write('\tcp {} $(DESTDIR)$(PREFIX)/bin/\n'.format(binary)) | ||
makefile.close() | ||
print("done!") | ||
|
||
run(['dch', '--create', '--empty', '--distribution', 'unstable', '--package', args.package_name, '--newversion', args.package_version], cwd=str(package_dir)) | ||
run(['dch', '--append', 'Packaged using ELF2deb v{}'.format(__version__)], stderr=DEVNULL, cwd=str(package_dir)) | ||
|
||
print("Run:") | ||
print(" * cd {}".format(package_dir)) | ||
print(" * vim debian/control # change description, dont add empty lines") | ||
print(" * debuild -us -uc # remove -us -uc if you want to sign the deb file") | ||
|
||
|
||
def get_copyright(args): | ||
import requests | ||
from datetime import datetime | ||
|
@@ -36,8 +98,44 @@ def get_copyright(args): | |
return license_txt | ||
|
||
|
||
def main(): | ||
import argparse | ||
def auto_config(): | ||
config = {} | ||
|
||
# Check if a "LICENSE" file is in cwd: | ||
for f in filter(lambda x: x.is_file(), Path.cwd().iterdir()): | ||
if "LICENSE" in f.name.upper(): | ||
config['license_file'] = f | ||
|
||
args_required = not ('license_file' in config) | ||
return args_required, config | ||
|
||
|
||
def verify_auto_config(args): | ||
while True: | ||
items = sorted(vars(args).items()) | ||
print("Package info:") | ||
for k, v in items: | ||
print('{}: {}'.format(k, v)) | ||
ans = input("==> Does this look correct? (y/n/q) ").lower() | ||
if ans == 'y': | ||
return args | ||
elif ans == 'n': | ||
print("\nProperties:") | ||
for i, (k, _) in enumerate(items): | ||
print('[{}] {}'.format(i+1, k)) | ||
while True: | ||
change_idx = int(input("\n==> Which property to change? ({}..{}) ".format(1, len(items)))) - 1 | ||
if 0 <= change_idx < len(items): | ||
break | ||
prop = items[change_idx][0] | ||
new_value = input("==> Which value should {} be changed to? ".format(prop)) | ||
args.__dict__[prop] = new_value # change args | ||
elif ans == 'q': | ||
exit(1) | ||
|
||
|
||
def get_args(): | ||
args_required, config = auto_config() | ||
|
||
parser = argparse.ArgumentParser(prog="ELF2deb") | ||
parser.add_argument( | ||
|
@@ -46,13 +144,13 @@ def main(): | |
|
||
package_group = parser.add_argument_group("package info") | ||
package_group.add_argument( | ||
"--package_name", required=True, help="The name of the deb package" | ||
"--package_name", required=args_required, help="The name of the deb package" | ||
) | ||
package_group.add_argument( | ||
"--package_version", required=True, help="The version of the package" | ||
"--package_version", required=args_required, help="The version of the package" | ||
) | ||
package_group.add_argument( | ||
"--homepage", help="The webpage of the package" | ||
"--homepage", "--webpage", help="The webpage of the package" | ||
) | ||
package_group.add_argument( | ||
"--dependencies", default="", help="Dependencies specified in the deb package (comma seperated)" | ||
|
@@ -80,64 +178,26 @@ def main(): | |
"binary_files", help="The binaries you want to package.", nargs="+" | ||
) | ||
|
||
# Parse arguments: | ||
args = parser.parse_args() | ||
|
||
args.author_name = os.getenv("DEBFULLNAME") | ||
args.author_mail = os.getenv("DEBEMAIL") | ||
args.author_name = os.getenv("DEBFULLNAME", os.getlogin()) | ||
args.author_mail = os.getenv("DEBEMAIL", "[email protected]") | ||
|
||
if not args_required: | ||
args_before = frozenset([args.license_file, args.package_name, args.package_version]) | ||
args.license_file = args.license_file or config['license_file'].open() | ||
args.package_name = args.package_name or Path.cwd().name | ||
args.package_version = args.package_version or "0.0.1" | ||
if args_before != frozenset([args.license_file, args.package_name, args.package_version]): | ||
args = verify_auto_config(args) | ||
|
||
# Fix homepage (TODO: figure out how to include this in the template file) | ||
args.homepage = 'Homepage: {}'.format(args.homepage) if args.homepage else '' | ||
|
||
# Create app dir: | ||
package_dir = Path("{package_name}-{package_version}".format(**vars(args))) | ||
if package_dir.exists(): | ||
if (input("Folder {} already exists. Delete? (y/n) ".format(package_dir)).lower() == "y"): | ||
shutil.rmtree(str(package_dir)) | ||
package_dir.mkdir(exist_ok=True) | ||
|
||
print("Copying templates... ", end='', flush=True) | ||
try: | ||
me = ZipFile(os.path.dirname(__file__), "r") | ||
except: | ||
me = ZipFile(os.path.dirname(__file__) + '/elf2deb.pyz' , "r") | ||
for template in me.filelist: | ||
if template.filename == os.path.basename(__file__): | ||
continue # skip this file | ||
|
||
target_filename = template.filename[len(TEMPLATE_DIR):] | ||
if template.is_dir(): | ||
(package_dir / target_filename).mkdir(exist_ok=True) | ||
else: | ||
date = me.read(template).decode().format(**vars(args)) | ||
(package_dir / target_filename).write_text(date) | ||
|
||
if args.license is not None: | ||
copyright_file = package_dir / 'debian/copyright' | ||
copyright_file.write_text(get_copyright(args)) | ||
elif args.license_file is not None: | ||
copyright_file = package_dir / 'debian/copyright' | ||
copyright_file.write_text(args.license_file.read()) | ||
|
||
# Make debian/rules executable: | ||
mode = os.stat(str(package_dir / 'debian/rules')).st_mode | ||
mode |= (mode & 0o444) >> 2 # copy R bits to X | ||
os.chmod(str(package_dir / 'debian/rules'), mode) | ||
print("done!") | ||
|
||
print("Copying files... ", end="", flush=True) | ||
makefile = open(str(package_dir / 'Makefile'), 'at') | ||
for i, binary in enumerate(args.binary_files): | ||
shutil.copy(binary, str(package_dir / os.path.basename(binary))) | ||
if i > 0: | ||
makefile.write('\tcp {} $(DESTDIR)$(PREFIX)/bin/\n'.format(binary)) | ||
makefile.close() | ||
print("done!") | ||
# Make sure package name is lowercase: | ||
args.package_name = args.package_name.lower() | ||
|
||
run(['dch', '--create', '--empty', '--distribution', 'unstable', '--package', args.package_name, '--newversion', args.package_version], cwd=str(package_dir)) | ||
run(['dch', '--append', 'Packaged using ELF2deb v{}'.format(__version__)], stderr=DEVNULL, cwd=str(package_dir)) | ||
|
||
print("Run:") | ||
print(" * cd {}".format(package_dir)) | ||
print(" * vim debian/control # change description, dont add empty lines") | ||
print(" * debuild -us -uc # remove -us -uc if you want to sign the deb file") | ||
return args | ||
|
||
|
||
if __name__ == "__main__": | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters