Skip to content

Commit

Permalink
feat: 0.2.10 Add feature for anvilPy, update init subcommand (#126)
Browse files Browse the repository at this point in the history
- Puts AnvilKern::AnvilPy usage behind the anvilPy feature.
- Updates init subcommand to use the basename of passed directory for
target name (before, it was "hello_world")
- This may be handled strictly if needed, but for now we're just gonna
break in this little aspect from amboso <=2.0.5.
  • Loading branch information
jgabaut authored Apr 13, 2024
1 parent 762401d commit e3b7914
Show file tree
Hide file tree
Showing 8 changed files with 108 additions and 21 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Changelog

## [0.2.10] - 2024-04-13

### Changed

- Moved anvilPy code behind a feature
- Updated init subcommand to use the passed directory basename for the target

## [0.2.9] - 2024-03-26

### Changed
Expand Down
6 changes: 3 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 8 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "invil"
description = "A port of amboso to Rust"
version = "0.2.9"
version = "0.2.10"
edition = "2021"
license = "GPL-3.0-only"
homepage = "https://github.com/jgabaut/invil"
Expand All @@ -17,16 +17,19 @@ exclude = [
"kazoj",
]

[features]

anvilPy = ["flate2", "tar", "url"]
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
clap = { version = "4.5.4", features = ["derive"] }
flate2 = "1.0.28"
flate2 = { version = "1.0.28", optional = true }
git2 = "0.18.3"
is_executable = "1.0.1"
log = "0.4.21"
regex = "1.10.3"
regex = "1.10.4"
simplelog = "0.12.2"
tar = "0.4.40"
tar = { version = "0.4.40", optional = true }
toml = "0.8.12"
url = "2.5.0"
url = { version = "2.5.0", optional = true }
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@
- [x] When in `make` build mode, call `make rebuild` by default
- [x] `--no-rebuild` to disable make rebuild and run just `make`
- [x] `--logged` to output full log to file
- Outputs to `./invil.log`. Not backwards compatible with repos not ignoring the file explicitly.
- Outputs to `./anvil.log`. Not backwards compatible with repos not ignoring the file explicitly.
- [x] `-G` flag also includes:
- a string for build OS (from `env::consts::OS`)
- HEAD commit message
Expand All @@ -128,6 +128,9 @@

## Experimental 2.1 version

These features are experimental and subject to change.
To enable them, add `--features="anvilPy"` to your build/install command.

- [x] Use "anvilPy" kern to support python projects
- Expects a suitable `pyproject.toml` is present alongside `stego.lock`
- Experimental support for almost all flags
Expand Down
13 changes: 13 additions & 0 deletions src/anvil_py.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
// SPDX-License-Identifier: GPL-3.0-only
/* Build tool with support for git tags, wrapping make.
* Copyright (C) 2023-2024 jgabaut
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3 of the License.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
use url::{Url};

use std::fs::{self, File};
Expand Down
62 changes: 52 additions & 10 deletions src/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@ use std::collections::BTreeMap;
use std::time::Instant;
use std::env;
use crate::ops::{do_build, do_run, do_delete, do_query, gen_c_header};
use crate::anvil_py::parse_pyproject_toml;

#[cfg(feature = "anvilPy")]
use crate::anvil_py::{parse_pyproject_toml, AnvilPyEnv};

use crate::exit;
use std::cmp::Ordering;
use std::fs::{self, File};
Expand All @@ -31,7 +34,6 @@ use crate::utils::{
};
use regex::Regex;
use std::fmt;
use crate::anvil_py::AnvilPyEnv;

pub const INVIL_NAME: &str = env!("CARGO_PKG_NAME");
pub const INVIL_VERSION: &str = env!("CARGO_PKG_VERSION");
Expand Down Expand Up @@ -342,6 +344,7 @@ pub struct AmbosoEnv {
pub anvil_kern: AnvilKern,

/// Optional AnvilPyEnv, only used when anvil_kern is AnvilPy
#[cfg(feature = "anvilPy")]
pub anvilpy_env: Option<AnvilPyEnv>,
}

Expand Down Expand Up @@ -996,6 +999,7 @@ fn parse_stego_tomlvalue(stego_str: &str, builds_path: &PathBuf, stego_dir: Path
anvil_version: EXPECTED_AMBOSO_API_LEVEL.to_string(),
enable_extensions: true,
anvil_kern: AnvilKern::AmbosoC,
#[cfg(feature = "anvilPy")]
anvilpy_env: None,
};
//trace!("Toml value: {{{}}}", y);
Expand Down Expand Up @@ -1225,7 +1229,31 @@ pub fn handle_init_subcommand(init_dir: Option<PathBuf>) -> ExitCode {
let init_res = Repository::init_opts(target.clone(),RepositoryInitOptions::new().no_reinit(true));
match init_res {
Ok(repo) => {
info!("Created git repo at {{{}}}", repo.workdir().expect("Repo should not be bare").display());
let repo_workdir = repo.workdir().expect("Repo should not be bare");
info!("Created git repo at {{{}}}", repo_workdir.display());

let dir_basename_osstr;
match repo_workdir.file_name() {
Some(d) => {
dir_basename_osstr = d;
}
None => {
error!("Failed to get base name for {{{}}}", repo_workdir.display());
return ExitCode::FAILURE;
}
}

let dir_basename;
match dir_basename_osstr.to_str() {
Some(s) => {
dir_basename = s;
}
None => {
error!("Failed converting {{{}}} to string. May contain invalid Unicode.", repo_workdir.display());
return ExitCode::FAILURE;
}
}
let caps_dir_basename = dir_basename.to_uppercase();
let mut src = target.clone();
src.push("src");
let mut bin = target.clone();
Expand Down Expand Up @@ -1298,15 +1326,15 @@ pub fn handle_init_subcommand(init_dir: Option<PathBuf>) -> ExitCode {
let output = File::create(stego_path.clone());
let stego_string = format!("[build]\n
source = \"main.c\"\n
bin = \"hello_world\"\n
bin = \"{}\"\n
makevers = \"0.1.0\"\n
automakevers = \"0.1.0\"\n
tests = \"tests\"\n
[tests]\n
testsdir = \"ok\"\n
errortestsdir = \"errors\"\n
[versions]\n
\"0.1.0\" = \"hello_world\"\n");
\"0.1.0\" = \"{}\"\n", dir_basename, dir_basename);
match output {
Ok(mut f) => {
let res = write!(f, "{}", stego_string);
Expand All @@ -1315,13 +1343,13 @@ errortestsdir = \"errors\"\n
debug!("Done generating stego.lock file");
}
Err(e) => {
error!("Failed writing stego.lock file at {{{stego_path}}}. Err: {e}");
error!("Failed writing stego.lock file at {{{}}}. Err: {e}", stego_path);
return ExitCode::FAILURE;
}
}
}
Err(e) => {
error!("Failed opening stego.lock file at {{{stego_path}}}. Err: {e}");
error!("Failed opening stego.lock file at {{{}}}. Err: {e}", stego_path);
return ExitCode::FAILURE;
}
}
Expand Down Expand Up @@ -1350,7 +1378,7 @@ errortestsdir = \"errors\"\n
let gitignore_path = format!("{}/.gitignore", target.display());
trace!("Generating .gitignore Target path: {{{}}}", gitignore_path);
let output = File::create(gitignore_path);
let gitignore_string = format!("# ignore object files\n*.o\n# also explicitly ignore our executable for good measure\nhello_world\n# also explicitly ignore our windows executable for good measure\nhello_world.exe\n# also explicitly ignore our debug executable for good measure\nhello_world_debug\n#We also want to ignore the dotfile dump if we ever use anvil with -c flag\namboso_cfg.dot\n#We want to ignore anvil log file\nanvil.log\n#We want to ignore default anvil build dir\nbin\n# MacOS DS_Store ignoring\n.DS_Store\n# ignore debug log file\ndebug_log.txt\n# ignore files generated by Autotools\nautom4te.cache/\ncompile\nconfig.guess\nconfig.log\nconfig.status\nconfig.sub\nconfigure\ninstall-sh\nmissing\naclocal.m4\nconfigure~\nMakefile\nMakefile.in\n");
let gitignore_string = format!("# ignore object files\n*.o\n# also explicitly ignore our executable for good measure\n{}\n# also explicitly ignore our windows executable for good measure\n{}.exe\n# also explicitly ignore our debug executable for good measure\n{}_debug\n#We also want to ignore the dotfile dump if we ever use anvil with -c flag\namboso_cfg.dot\n#We want to ignore anvil log file\nanvil.log\n#We want to ignore default anvil build dir\nbin\n# MacOS DS_Store ignoring\n.DS_Store\n# ignore debug log file\ndebug_log.txt\n# ignore files generated by Autotools\nautom4te.cache/\ncompile\nconfig.guess\nconfig.log\nconfig.status\nconfig.sub\nconfigure\ninstall-sh\nmissing\naclocal.m4\nconfigure~\nMakefile\nMakefile.in\n", dir_basename, dir_basename, dir_basename);
match output {
Ok(mut f) => {
let res = write!(f, "{}", gitignore_string);
Expand All @@ -1372,7 +1400,7 @@ errortestsdir = \"errors\"\n
let makefileam_path = format!("{}/Makefile.am", target.display());
trace!("Generating Makefile.am - Target path: {{{}}}", makefileam_path);
let output = File::create(makefileam_path);
let makefileam_string = format!("AUTOMAKE_OPTIONS = foreign\nCFLAGS = @CFLAGS@\nSHELL := /bin/bash\n.ONESHELL:\nMACHINE := $$(uname -m)\nPACK_NAME = $(TARGET)-$(VERSION)-$(OS)-$(MACHINE)\nhello_world_SOURCES = src/main.c\nLDADD = $(HW_LDFLAGS)\nAM_LDFLAGS = -O2\nAM_CFLAGS = $(HW_CFLAGS) -O2 -Werror -Wpedantic -Wall\nif DEBUG_BUILD\nAM_LDFLAGS += -ggdb -O0\nAM_CFLAGS += \nelse\nAM_LDFLAGS += -s\nendif\n%.o: %.c\n $(CCOMP) -c $(CFLAGS) $(AM_CFLAGS) $< -o $@\n$(TARGET): $(hello_world_SOURCES:.c=.o)\n @echo -e \" AM_CFLAGS: [ $(AM_CFLAGS) ]\"\n @echo -e \" LDADD: [ $(LDADD) ]\"\n $(CCOMP) $(CFLAGS) $(AM_CFLAGS) $(hello_world_SOURCES:.c=.o) -o $@ $(LDADD) $(AM_LDFLAGS)\nclean:\n @echo -en \"Cleaning build artifacts: \"\n -rm $(TARGET)\n -rm src/*.o\n -rm static/*.o\n @echo -e \"Done.\"\ncleanob:\n @echo -en \"Cleaning object build artifacts: \"\n -rm src/*.o\n -rm static/*.o\n @echo -e \"Done.\"\nanviltest:\n @echo -en \"Running anvil tests.\"\n ./anvil -tX\n @echo -e \"Done.\"\nall: $(TARGET)\nrebuild: clean all\n.DEFAULT_GOAL := all\n");
let makefileam_string = format!("AUTOMAKE_OPTIONS = foreign\nCFLAGS = @CFLAGS@\nSHELL := /bin/bash\n.ONESHELL:\nMACHINE := $$(uname -m)\nPACK_NAME = $(TARGET)-$(VERSION)-$(OS)-$(MACHINE)\n{}_SOURCES = src/main.c\nLDADD = $({caps_dir_basename}_LDFLAGS)\nAM_LDFLAGS = -O2\nAM_CFLAGS = $({caps_dir_basename}_CFLAGS) -O2 -Werror -Wpedantic -Wall\nif DEBUG_BUILD\nAM_LDFLAGS += -ggdb -O0\nAM_CFLAGS += \nelse\nAM_LDFLAGS += -s\nendif\n%.o: %.c\n $(CCOMP) -c $(CFLAGS) $(AM_CFLAGS) $< -o $@\n$(TARGET): $({}_SOURCES:.c=.o)\n @echo -e \" AM_CFLAGS: [ $(AM_CFLAGS) ]\"\n @echo -e \" LDADD: [ $(LDADD) ]\"\n $(CCOMP) $(CFLAGS) $(AM_CFLAGS) $({}_SOURCES:.c=.o) -o $@ $(LDADD) $(AM_LDFLAGS)\nclean:\n @echo -en \"Cleaning build artifacts: \"\n -rm $(TARGET)\n -rm src/*.o\n -rm static/*.o\n @echo -e \"Done.\"\ncleanob:\n @echo -en \"Cleaning object build artifacts: \"\n -rm src/*.o\n -rm static/*.o\n @echo -e \"Done.\"\nanviltest:\n @echo -en \"Running anvil tests.\"\n ./anvil -tX\n @echo -e \"Done.\"\nall: $(TARGET)\nrebuild: clean all\n.DEFAULT_GOAL := all\n", dir_basename, dir_basename, dir_basename);
match output {
Ok(mut f) => {
let res = write!(f, "{}", makefileam_string);
Expand All @@ -1394,7 +1422,7 @@ errortestsdir = \"errors\"\n
let configureac_path = format!("{}/configure.ac", target.display());
trace!("Generating configure.ac - Target path: {{{}}}", configureac_path);
let output = File::create(configureac_path);
let configureac_string = format!("# Generated by invil v{INVIL_VERSION}\nAC_INIT([hello_world], [0.1.0], [email@example.com])\nAM_INIT_AUTOMAKE([foreign -Wall])\nAC_CANONICAL_HOST\nbuild_linux=no\nbuild_windows=no\nbuild_mac=no\necho \"Host os: $host_os\"\n\nAC_ARG_ENABLE([debug], [AS_HELP_STRING([--enable-debug], [Enable debug build])], [enable_debug=$enableval], [enable_debug=no])\nAM_CONDITIONAL([DEBUG_BUILD], [test \"$enable_debug\" = \"yes\"])\ncase \"${{host_os}}\" in\n\tmingw*)\n\t\techo \"Building for mingw32: [$host_cpu-$host_vendor-$host_os]\"\n\t\tbuild_windows=yes\n\t\tAC_SUBST([HW_CFLAGS], [\"-I/usr/x86_64-w64-mingw32/include -static -fstack-protector\"])\n\t\tAC_SUBST([HW_LDFLAGS], [\"-L/usr/x86_64-w64-mingw32/lib\"])\n\t\tAC_SUBST([CCOMP], [\"/usr/bin/x86_64-w64-mingw32-gcc\"])\n\t\tAC_SUBST([OS], [\"w64-mingw32\"])\n\t\tAC_SUBST([TARGET], [\"hello_world.exe\"])\n\t;;\n\tdarwin*)\n\t\tbuild_mac=yes\n\t\techo \"Building for macos: [$host_cpu-$host_vendor-$host_os]\"\n\t\tAC_SUBST([HW_CFLAGS], [\"-I/opt/homebrew/opt/ncurses/include\"])\n\t\tAC_SUBST([HW_LDFLAGS], [\"-L/opt/homebrew/opt/ncurses/lib\"])\n\t\tAC_SUBST([OS], [\"darwin\"])\n\t\tAC_SUBST([TARGET], [\"hello_world\"])\n\t;;\n\tlinux*)\n\t\techo \"Building for Linux: [$host_cpu-$host_vendor-$host_os]\"\n\t\tbuild_linux=yes\n\t\tAC_SUBST([HW_CFLAGS], [\"\"])\n\t\tAC_SUBST([HW_LDFLAGS], [\"\"])\n\t\tAC_SUBST([OS], [\"Linux\"])\n\t\tAC_SUBST([TARGET], [\"hello_world\"])\n\t;;\nesac\n\nAM_CONDITIONAL([DARWIN_BUILD], [test \"$build_mac\" = \"yes\"])\nAM_CONDITIONAL([WINDOWS_BUILD], [test \"$build_windows\" = \"yes\"])\nAM_CONDITIONAL([LINUX_BUILD], [test \"$build_linux\" = \"yes\"])\n\nAC_ARG_VAR([VERSION], [Version number])\nif test -z \"$VERSION\"; then\n VERSION=\"0.1.0\"\nfi\nAC_DEFINE_UNQUOTED([VERSION], [\"$VERSION\"], [Version number])\nAC_CHECK_PROGS([CCOMP], [gcc clang])\nAC_CHECK_HEADERS([stdio.h])\nAC_CHECK_FUNCS([malloc calloc])\nAC_CONFIG_FILES([Makefile])\nAC_OUTPUT\n");
let configureac_string = format!("# Generated by invil v{INVIL_VERSION}\nAC_INIT([{}], [0.1.0], [email@example.com])\nAM_INIT_AUTOMAKE([foreign -Wall])\nAC_CANONICAL_HOST\nbuild_linux=no\nbuild_windows=no\nbuild_mac=no\necho \"Host os: $host_os\"\n\nAC_ARG_ENABLE([debug], [AS_HELP_STRING([--enable-debug], [Enable debug build])], [enable_debug=$enableval], [enable_debug=no])\nAM_CONDITIONAL([DEBUG_BUILD], [test \"$enable_debug\" = \"yes\"])\ncase \"${{host_os}}\" in\n\tmingw*)\n\t\techo \"Building for mingw32: [$host_cpu-$host_vendor-$host_os]\"\n\t\tbuild_windows=yes\n\t\tAC_SUBST([{caps_dir_basename}_CFLAGS], [\"-I/usr/x86_64-w64-mingw32/include -static -fstack-protector\"])\n\t\tAC_SUBST([{caps_dir_basename}_LDFLAGS], [\"-L/usr/x86_64-w64-mingw32/lib\"])\n\t\tAC_SUBST([CCOMP], [\"/usr/bin/x86_64-w64-mingw32-gcc\"])\n\t\tAC_SUBST([OS], [\"w64-mingw32\"])\n\t\tAC_SUBST([TARGET], [\"{}.exe\"])\n\t;;\n\tdarwin*)\n\t\tbuild_mac=yes\n\t\techo \"Building for macos: [$host_cpu-$host_vendor-$host_os]\"\n\t\tAC_SUBST([{caps_dir_basename}_CFLAGS], [\"-I/opt/homebrew/opt/ncurses/include\"])\n\t\tAC_SUBST([{caps_dir_basename}_LDFLAGS], [\"-L/opt/homebrew/opt/ncurses/lib\"])\n\t\tAC_SUBST([OS], [\"darwin\"])\n\t\tAC_SUBST([TARGET], [\"{}\"])\n\t;;\n\tlinux*)\n\t\techo \"Building for Linux: [$host_cpu-$host_vendor-$host_os]\"\n\t\tbuild_linux=yes\n\t\tAC_SUBST([{caps_dir_basename}_CFLAGS], [\"\"])\n\t\tAC_SUBST([{caps_dir_basename}_LDFLAGS], [\"\"])\n\t\tAC_SUBST([OS], [\"Linux\"])\n\t\tAC_SUBST([TARGET], [\"{}\"])\n\t;;\nesac\n\nAM_CONDITIONAL([DARWIN_BUILD], [test \"$build_mac\" = \"yes\"])\nAM_CONDITIONAL([WINDOWS_BUILD], [test \"$build_windows\" = \"yes\"])\nAM_CONDITIONAL([LINUX_BUILD], [test \"$build_linux\" = \"yes\"])\n\nAC_ARG_VAR([VERSION], [Version number])\nif test -z \"$VERSION\"; then\n VERSION=\"0.1.0\"\nfi\nAC_DEFINE_UNQUOTED([VERSION], [\"$VERSION\"], [Version number])\nAC_CHECK_PROGS([CCOMP], [gcc clang])\nAC_CHECK_HEADERS([stdio.h])\nAC_CHECK_FUNCS([malloc calloc])\nAC_CONFIG_FILES([Makefile])\nAC_OUTPUT\n", dir_basename, dir_basename, dir_basename, dir_basename);
match output {
Ok(mut f) => {
let res = write!(f, "{}", configureac_string);
Expand Down Expand Up @@ -1545,6 +1573,7 @@ pub fn check_passed_args(args: &mut Args) -> Result<AmbosoEnv,String> {
anvil_version: EXPECTED_AMBOSO_API_LEVEL.to_string(),
enable_extensions: true,
anvil_kern: AnvilKern::AmbosoC,
#[cfg(feature = "anvilPy")]
anvilpy_env: None,
};

Expand Down Expand Up @@ -1698,6 +1727,7 @@ pub fn check_passed_args(args: &mut Args) -> Result<AmbosoEnv,String> {
}

match anvil_env.anvil_kern {
#[cfg(feature = "anvilPy")]
AnvilKern::AnvilPy => {
let mut skip_pyparse = false;
match args.strict {
Expand Down Expand Up @@ -1730,6 +1760,17 @@ pub fn check_passed_args(args: &mut Args) -> Result<AmbosoEnv,String> {
}
}
AnvilKern::AmbosoC => {}
#[cfg(not(feature = "anvilPy"))]
_ => {
if let AnvilKern::AnvilPy = anvil_env.anvil_kern {
// Handle AnvilPy case when the feature is not enabled
error!("AnvilPy kern feature is not enabled");
return Err("AnvilPy kern feauture is not enabled".to_string());
} else {
error!("Unexpected anvil kern");
return Err("Unexpected anvil kern".to_string());
}
}
}

match args.gen_c_header {
Expand Down Expand Up @@ -2217,6 +2258,7 @@ pub fn parse_legacy_stego(stego_path: &PathBuf) -> Result<AmbosoEnv,String> {
anvil_version: EXPECTED_AMBOSO_API_LEVEL.to_string(),
enable_extensions: true,
anvil_kern: AnvilKern::AmbosoC,
#[cfg(feature = "anvilPy")]
anvilpy_env: None,
};

Expand Down
6 changes: 6 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
mod core;
mod ops;
mod utils;
#[cfg(feature = "anvilPy")]
mod anvil_py;

#[macro_use] extern crate log;
Expand Down Expand Up @@ -52,6 +53,11 @@ fn main() -> ExitCode {
if args.version {
if args.verbose > 3 {
println!("invil, v{} (Compat: v{})",INVIL_VERSION, args.anvil_version.expect("Failed initialising anvil_version"));
if cfg!(feature = "anvilPy") {
println!("Experimental anvilPy support is enabled.");
} else {
println!("Experimental anvilPy support is NOT enabled.");
}
} else {
println!("{}",INVIL_VERSION);
}
Expand Down
Loading

0 comments on commit e3b7914

Please sign in to comment.