From befc62e1e0ca09f761527e1fd60a54e56d05baae Mon Sep 17 00:00:00 2001 From: Calvin Spealman Date: Sun, 26 May 2019 10:44:28 -0400 Subject: [PATCH] Feet is now a rust program. This is for the bootloader, which unpacks the runtime. PyInstaller is no longer used. --- Cargo.lock | 136 +++++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 12 +++++ README.md | 16 ++++-- feet.rs | 90 +++++++++++++++++++++++++++++++ requirements.txt | 1 - setup.py | 30 +++++++++++ 6 files changed, 279 insertions(+), 6 deletions(-) create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 feet.rs delete mode 100644 requirements.txt create mode 100644 setup.py diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..773c138 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,136 @@ +[[package]] +name = "adler32" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "byteorder" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "bzip2" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bzip2-sys 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "bzip2-sys" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "cc" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "cfg-if" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "crc32fast" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "feet" +version = "0.1.0" +dependencies = [ + "zip 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "libc" +version = "0.2.55" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "libflate" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "adler32 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "podio" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "redox_syscall" +version = "0.1.54" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "time" +version = "0.1.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "winapi" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "zip" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bzip2 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libflate 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", + "podio 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[metadata] +"checksum adler32 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7e522997b529f05601e05166c07ed17789691f562762c7f3b987263d2dedee5c" +"checksum byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a019b10a2a7cdeb292db131fc8113e57ea2a908f6e7894b0c3c671893b65dbeb" +"checksum bzip2 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "42b7c3cbf0fa9c1b82308d57191728ca0256cb821220f4e2fd410a72ade26e3b" +"checksum bzip2-sys 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "6584aa36f5ad4c9247f5323b0a42f37802b37a836f0ad87084d7a33961abe25f" +"checksum cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)" = "39f75544d7bbaf57560d2168f28fd649ff9c76153874db88bdbdfd839b1a7e7d" +"checksum cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "b486ce3ccf7ffd79fdeb678eac06a9e6c09fc88d33836340becb8fffe87c5e33" +"checksum crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1" +"checksum libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)" = "42914d39aad277d9e176efbdad68acb1d5443ab65afe0e0e4f0d49352a950880" +"checksum libflate 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)" = "c52384aeb22d0ce82a10d8ddf35f7fb4717d1b23eac5b94cd38d2050fb53766a" +"checksum podio 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "780fb4b6698bbf9cf2444ea5d22411cef2953f0824b98f33cf454ec5615645bd" +"checksum redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)" = "12229c14a0f65c4f1cb046a3b52047cdd9da1f4b30f8a39c5063c8bae515e252" +"checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f" +"checksum winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "f10e386af2b13e47c89e7236a7a14a086791a2b88ebad6df9bf42040195cf770" +"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +"checksum zip 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c18fc320faf909036e46ac785ea827f72e485304877faf1a3a39538d3714dbc3" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..a873f17 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "feet" +version = "0.1.0" +authors = ["Calvin Spealman "] +edition = "2018" + +[dependencies] +zip = "0.5.2" + +[[bin]] +name = "feet" +path = "feet.rs" diff --git a/README.md b/README.md index 3b495a0..962131a 100644 --- a/README.md +++ b/README.md @@ -4,9 +4,8 @@ FEET is a runner for Python. What does that mean? It makes it easy to create Python scripts, programs, applications, or games and package them up to send to friends, users, players, or whomever you want -to share your work with. FEET is really just a wrapper around the excellent -PyInstaller project and it is *mostly* for Windows users, because they have -the hardest time sharing Python code. +to share your work with. FEET is currently being built for Windows, but Linux +and Mac versions will hopefully arrive in the future! FEET is just an executable, called `feet.exe`, that sits in a folder beside your script that you name `main.py`. You can zip up this folder and send it @@ -16,12 +15,19 @@ or package anything. Just send them your files and the runner. +When users run your program via `feet.exe` the first time, it will unpack a +runtime to a `feet/` sub-folder. You can remove this at any time, especially +before zipping your program to share. + Note: Feet is a prototype, but please let me know if you find it useful and file issues for any improvements that you feel would help make it less of an experiment and more of a real thing. ## BUILDING +FEET includes a bootloader written in rust. Make sure you have a recent version +of the Rust compiler and Cargo tool installed. + To build feet, install the build dependencies and then run the build script. pip install -r requirements.txt @@ -85,5 +91,5 @@ Python Feet is a prototype. It definitely has bugs and will definitely have breaking changes. However, if you find it useful, that's great! If you find problems with it or if you want to help, please file issues on the [Github page](https://github.com/ironfroggy/feet/issues) with all the details you -can include, or find me on Twitter [@ironfroggy](https://twitter.com/ironfroggy) to thank, complain to, or discuss Python -with. +can include, or find me on Twitter [@ironfroggy](https://twitter.com/ironfroggy) +to thank, complain to, or discuss Python with. diff --git a/feet.rs b/feet.rs new file mode 100644 index 0000000..9daf83e --- /dev/null +++ b/feet.rs @@ -0,0 +1,90 @@ +use std::env; +use std::process::{Command, Stdio}; +use std::io::{BufRead, BufReader, Error, ErrorKind}; +// use std::io::Error; +use std::path::Path; +use std::io; +use std::fs; + +use std::io::{Seek, Read}; +use zip::result::ZipResult; +use zip::read::{ZipFile, ZipArchive}; +// use zip::write::{FileOptions, ZipWriter}; +use std::fs::File; + +fn browse_zip_archive(buf: &mut T, browse_func: F) -> ZipResult> + where T: Read + Seek, + F: Fn(&ZipFile) -> ZipResult +{ + let mut archive = ZipArchive::new(buf)?; + (0..archive.len()) + .map(|i| archive.by_index(i).and_then(|file| browse_func(&file))) + .collect() +} + +fn main() -> Result<(), Error> { + // let mut file = File::open("example.zip").expect("Couldn't open file"); + // let files = browse_zip_archive(&mut file, |f| { + // Ok(format!("{}: {} -> {}", f.name(), f.size(), f.compressed_size())) + // }); + // println!("{:?}", files); + + if (!Path::new("./feet/").exists()) { + // let archive_path = "feetruntime.zip"; + let archive_path = "./feet.exe"; + let file = fs::File::open(&archive_path).unwrap(); + let mut archive = zip::ZipArchive::new(file).unwrap(); + + for i in 0..archive.len() { + let mut file = archive.by_index(i).unwrap(); + let outpath = file.sanitized_name(); + + { + let comment = file.comment(); + if !comment.is_empty() { + println!("File {} comment: {}", i, comment); + } + } + + if (&*file.name()).ends_with('/') { + println!("File {} extracted to \"{}\"", i, outpath.as_path().display()); + fs::create_dir_all(&outpath).unwrap(); + } else { + println!("File {} extracted to \"{}\" ({} bytes)", i, outpath.as_path().display(), file.size()); + if let Some(p) = outpath.parent() { + if !p.exists() { + fs::create_dir_all(&p).unwrap(); + } + } + let mut outfile = fs::File::create(&outpath).unwrap(); + io::copy(&mut file, &mut outfile).unwrap(); + } + + // Get and Set permissions + #[cfg(unix)] + { + use std::os::unix::fs::PermissionsExt; + + if let Some(mode) = file.unix_mode() { + fs::set_permissions(&outpath, fs::Permissions::from_mode(mode)).unwrap(); + } + } + } + } + + // Now, runtime is either extracted or already was, so run the commands + + let mut args: Vec = env::args().collect(); + args.remove(0); + + let mut child = Command::new("./feet/cpython/python") + .arg("./feet/feet.py") + .args(args) + .stderr(Stdio::inherit()) + .stdout(Stdio::inherit()) + .stdin(Stdio::inherit()) + .spawn()?; + + child.wait(); + Ok(()) +} diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index d49a41d..0000000 --- a/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -PyInstaller==3.4 \ No newline at end of file diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..6889409 --- /dev/null +++ b/setup.py @@ -0,0 +1,30 @@ +import setuptools + +with open("README.md", "r", encoding='utf8') as f: + long_description = f.read() + +setuptools.setup( + name="feet", + version="0.0.3", + author="Calvin Spealman", + author_email="ironfroggy@gmail.com", + description="Feet makes Python run", + long_description=long_description, + long_description_content_type="text/markdown", + url="https://github.com/ironfroggy/feet", + modules=['feetmaker'], + entry_points = { + 'console_scripts': [ + 'mkfeet=feetmaker:main', + ], + }, + install_requires=[ + 'requirements-parser', + # 'pip==19.1.1', + ], + classifiers=[ + "Programming Language :: Python :: 3", + "License :: OSI Approved :: MIT License", + "Operating System :: Windows", + ], +) \ No newline at end of file