Repository: DragonBuild/dragon (language: python)

Issue:
Project specific variables affect global namespace in DragonMake
If I have a DragonMake containing a `type: tweak` module followed by a `type: cli` module, the cli executable is wrongly built as a shared library. The reason seems to be that the type definition for `tweak` in defaults.yml sets `lopts: '-dynamiclib ...'`, and the definition for `cli` has no `lopts` at all. Instead of causing an empty `lopts`, this makes it keep the old value from when it processed the tweak, so it passes -dynamiclib when building the cli executable too.

Putting the `cli` module first and the `tweak` module second fixes the problem. Setting `lopts: ''` in the definition of `cli` in defaults.yml also works.

Similarly, the cli module gets wrongly linked to Foundation and CydiaSubstrate if it's defined _after_ the tweak in the DragonMake, but not if it's defined first.


Discussion / hints:
Pushed a hotfix for this but I'm leaving it open as I really need to take a look at why those settings are carrying over.

Someone wrote some "optimized" logic for loading in the config files; I'm wondering whether these 'defaults' are getting pointed to when they should be copied instead. 
There's a problem somewhere in DragonMake logic that causes the variables to behave as globals instead of properly adhering to their namespace. 

I am entirely unsure how that's possible given the current control flow of the DragonGen code. This can be solved by redefining the variable causing issues for each project. Having to do so is not intended behavior, and this is an important issue that reduces QOL when writing build scripts. 

now that pip migration is complete i'm going to look into this again.

Fix patch:
diff --git a/branding/dragon.png b/.github/branding/dragon.png
similarity index 100%
rename from branding/dragon.png
rename to .github/branding/dragon.png
diff --git a/branding/dragon.svg b/.github/branding/dragon.svg
similarity index 100%
rename from branding/dragon.svg
rename to .github/branding/dragon.svg
diff --git a/DragonGen/README.md b/DragonGen/README.md
deleted file mode 100644
index 135363f09..000000000
--- a/DragonGen/README.md
+++ /dev/null
@@ -1,5 +0,0 @@
-# DragonBuild/DragonGen
-
-This folder contains the generation script that builds build.ninja files. 
-
-It uses the ninja_syntax python script that comes packaged with ninja, although we have our own copy, in case we need to modify it later.
\ No newline at end of file
diff --git a/DragonGen/rules.yml b/DragonGen/rules.yml
deleted file mode 100644
index 5adca5cd7..000000000
--- a/DragonGen/rules.yml
+++ /dev/null
@@ -1,239 +0,0 @@
----
-logos:
-  name: Logos Preprocessor
-  desc: Preprocessing $in using Logos
-  cmd: $logos $in > $out
-prefs:
-  name: DragonPrefs
-  desc: Building DragonPrefs
-  cmd: python3 $$DRAGONBUILD/DragonGen/dragonprefs.py $in $out
-swiftarmv6:
-  name: Swift armv6
-  cmd: SwiftFiles=$$(echo '$swiftfiles $in' | tr ' ' '\\n' | sort | uniq -u); $swift -frontend -c $internalswiftflags $bridgeheader -target armv6-apple-ios -emit-module-path $out.swiftmodule -primary-file $in $$SwiftFiles -o $out
-swiftarmv7:
-  name: Swift armv7
-  cmd: SwiftFiles=$$(echo '$swiftfiles $in' | tr ' ' '\\n' | sort | uniq -u); $swift -frontend -c $internalswiftflags $bridgeheader -target armv7-apple-ios -emit-module-path $out.swiftmodule -primary-file $in $$SwiftFiles -o $out
-swiftarmv7s:
-  name: Swift armv7s
-  cmd: SwiftFiles=$$(echo '$swiftfiles $in' | tr ' ' '\\n' | sort | uniq -u); $swift -frontend -c $internalswiftflags $bridgeheader -target armv7s-apple-ios -emit-module-path $out.swiftmodule -primary-file $in $$SwiftFiles -o $out
-swiftarm64:
-  name: Swift arm64
-  cmd: SwiftFiles=$$(echo '$swiftfiles $in' | tr ' ' '\\n' | sort | uniq -u); $swift -frontend -c $internalswiftflags $bridgeheader -target arm64-apple-ios -emit-module-path $out.swiftmodule -primary-file $in $$SwiftFiles -o $out
-swiftarm64e:
-  name: Swift arm64e
-  cmd: SwiftFiles=$$(echo '$swiftfiles $in' | tr ' ' '\\n' | sort | uniq -u); $swift -frontend -c $internalswiftflags $bridgeheader -target arm64e-apple-ios -emit-module-path $out.swiftmodule -primary-file $in $$SwiftFiles -o $out
-swiftmoduleheader:
-  name: Swift Module Header
-  cmd: $swift -frontend -c $internalswiftflags $bridgeheader -target arm64-apple-ios7.0 -emit-module -merge-modules $in -emit-objc-header-path $out -o /dev/null
-
-
-cargoarmv6:
-  name: cargo armv6
-  desc: Compiling $in with $cc [armv6]
-  cmd: $cargo-nightly --target=i386-apple-darwin10 $internalcflags -c $in -o $out
-cargoarmv7:
-  name: cargo armv7
-  desc: Compiling $in with $cc [armv7]
-  cmd: $cc -arch armv7 $internalcflags -c $in -o $out
-cargoarmv7s:
-  name: cargo armv7s
-  desc: Compiling $in with $cc [armv7s]
-  cmd: $cc -arch armv7s $internalcflags -c $in -o $out
-cargoarm64:
-  name: cargo arm64
-  desc: Compiling $in with $cc [arm64]
-  cmd: $cc -arch arm64 $internalcflags -c $in -o $out
-cargoarm64e:
-  name: cargo arm64e
-  desc: Compiling $in with $cc [arm64e]
-  cmd: $cc -arch arm64e $internalcflags -c $in -o $out
-cargox86_64:
-  name: cargo x86_64
-  desc: Compiling $in with $cc [x86_64]
-  cmd: $cc -arch x86_64 $internalcflags -c $in -o $out
-cargoi386:
-  name: cargo i386
-  desc: Compiling $in with $cc [i386]
-  cmd: $cc -arch i386 $internalcflags -c $in -o $out
-
-carmv6:
-  name: clang armv6
-  desc: Compiling $in with $cc [armv6]
-  cmd: $cc -arch armv6 $internalcflags -c $in -o $out
-carmv7:
-  name: clang armv7
-  desc: Compiling $in with $cc [armv7]
-  cmd: $cc -arch armv7 $internalcflags -c $in -o $out
-carmv7s:
-  name: clang armv7s
-  desc: Compiling $in with $cc [armv7s]
-  cmd: $cc -arch armv7s $internalcflags -c $in -o $out
-carm64:
-  name: clang arm64
-  desc: Compiling $in with $cc [arm64]
-  cmd: $cc -arch arm64 $internalcflags -c $in -o $out
-carm64e:
-  name: clang arm64e
-  desc: Compiling $in with $cc [arm64e]
-  cmd: $cc -arch arm64e $internalcflags -c $in -o $out
-cx86_64:
-  name: clang x86_64
-  desc: Compiling $in with $cc [x86_64]
-  cmd: $cc -arch x86_64 $internalcflags -c $in -o $out
-ci386:
-  name: clang i386
-  desc: Compiling $in with $cc [i386]
-  cmd: $cc -arch i386 $internalcflags -c $in -o $out
-
-cxxarmv6:
-  name: clang++ armv6
-  desc: Compiling $in with $cxx [armv6]
-  cmd: $cxx -arch armv6 $internalcflags -c $in -o $out
-cxxarmv7:
-  name: clang++ armv7
-  desc: Compiling $in with $cxx [armv7]
-  cmd: $cxx -arch armv7 $internalcflags -c $in -o $out
-cxxarmv7s:
-  name: clang++ armv7s
-  desc: Compiling $in with $cxx [armv7s]
-  cmd: $cxx -arch armv7s $internalcflags -c $in -o $out
-cxxarm64:
-  name: clang++ arm64
-  desc: Compiling $in with $cxx [arm64]
-  cmd: $cxx -arch arm64 $internalcflags -c $in -o $out
-cxxarm64e:
-  name: clang++ arm64e
-  desc: Compiling $in with $cxx [arm64e]
-  cmd: $cxx -arch arm64e $internalcflags -c $in -o $out
-cxxx86_64:
-  name: clang++ x86_64
-  desc: Compiling $in with $cxx [x86_64]
-  cmd: $cxx -arch x86_64 $internalcflags -c $in -o $out
-cxxi386:
-  name: clang++ i386
-  desc: Compiling $in with $cxx [i386]
-  cmd: $cxx -arch i386 $internalcflags -c $in -o $out
-
-objcarmv6:
-  name: clang++ armv6
-  desc: Compiling $in with $cc [armv6]
-  cmd: $cc -arch armv6 $internalcflags -c $in -o $out
-objcarmv7:
-  name: clang++ armv7
-  desc: Compiling $in with $cc [armv7]
-  cmd: $cc -arch armv7 $internalcflags -c $in -o $out
-objcarmv7s:
-  name: clang++ armv7s
-  desc: Compiling $in with $cc [armv7s]
-  cmd: $cc -arch armv7s $internalcflags -c $in -o $out
-objcarm64:
-  name: clang++ arm64
-  desc: Compiling $in with $cc [arm64]
-  cmd: $cc -arch arm64 $internalcflags -c $in -o $out
-objcarm64e:
-  name: clang++ arm64e
-  desc: Compiling $in with $cc [arm64e]
-  cmd: $cc -arch arm64e $internalcflags -c $in -o $out
-objcx86_64:
-  name: clang++ x86_64
-  desc: Compiling $in with $cc [x86_64]
-  cmd: $cc -arch x86_64 $internalcflags -c $in -o $out
-objci386:
-  name: clang++ i386
-  desc: Compiling $in with $cc [i386]
-  cmd: $cc -arch i386 $internalcflags -c $in -o $out
-
-objcxxarmv6:
-  name: clang++ armv6
-  desc: Compiling $in with $cxx [armv6]
-  cmd: $cxx -arch armv6 $internalcflags -c $in -o $out
-objcxxarmv7:
-  name: clang++ armv7
-  desc: Compiling $in with $cxx [armv7]
-  cmd: $cxx -arch armv7 $internalcflags -c $in -o $out
-objcxxarmv7s:
-  name: clang++ armv7s
-  desc: Compiling $in with $cxx [armv7s]
-  cmd: $cxx -arch armv7s $internalcflags -c $in -o $out
-objcxxarm64:
-  name: clang++ arm64
-  desc: Compiling $in with $cxx [arm64]
-  cmd: $cxx -arch arm64 $internalcflags -c $in -o $out
-objcxxarm64e:
-  name: clang++ arm64e
-  desc: Compiling $in with $cxx [arm64e]
-  cmd: $cxx -arch arm64e $internalcflags -c $in -o $out
-objcxxx86_64:
-  name: clang++ x86_64
-  desc: Compiling $in with $cxx [x86_64]
-  cmd: $cxx -arch x86_64 $internalcflags -c $in -o $out
-objcxxi386:
-  name: clang++ i386
-  desc: Compiling $in with $cxx [i386]
-  cmd: $cxx -arch i386 $internalcflags -c $in -o $out
-
-
-linkarmv6:
-  name: armv6 Linker
-  desc: Linking $in with $ld [armv6]
-  cmd: $ld -arch armv6 $internallflags $internalldflags -o $out $in
-linkarmv7:
-  name: armv7 Linker
-  desc: Linking $in with $ld [armv7]
-  cmd: $ld -arch armv7 $internallflags $internalldflags -o $out $in
-linkarmv7s:
-  name: armv7s Linker
-  desc: Linking $in with $ld [armv7s]
-  cmd: $ld -arch armv7s $internallflags $internalldflags -o $out $in
-linkarm64:
-  name: arm64 Linker
-  desc: Linking $in with $ld [arm64]
-  cmd: $ld -arch arm64 $internallflags $internalldflags -o $out $in
-linkarm64e:
-  name: arm64e Linker
-  desc: Linking $in with $ld [arm64e]
-  cmd: $ld -arch arm64e $internallflags $internalldflags -o $out $in
-linkx86_64:
-  name: x86_64 Linker
-  desc: Linking $in with $ld [x86_64]
-  cmd: $ld -arch x86_64 $internallflags $internalldflags -o $out $in
-linki386:
-  name: i386 Linker
-  desc: Linking $in with $ld [i386]
-  cmd: $ld -arch i386 $internallflags $internalldflags -o $out $in
-archive:
-  name: Creating Archive
-  desc: Creating Static Archive with $ar from $in
-  cmd: ar cr $out $in
-dummy:
-  name: Copying Files
-  desc: Copying Files
-  cmd: cp $in $out
-copy:
-  name: Copying Files
-  desc: Copying Files
-  cmd: cp $in $out
-lipo:
-  name: Lipo Utility
-  desc: Merging architechtures
-  cmd: $lipo -create $in -output $out
-bundle:
-  name: Bundle Resources
-  desc: Copying Bundle Resources
-  cmd: mkdir -p "$proj_build_dir/_$location/" && cp -R "$resource_dir/" "$proj_build_dir/_$location"
-plist:
-  name: plutil compilation
-  desc: Compiling $in
-  cmd: $plutil -convert binary1 $in -o $out
-debug:
-  name: DsymUtil
-  desc: Generating Debug Symbols for $name
-  cmd: $dsym \"$in\" 2&> /dev/null; cp $in $out
-sign:
-  name: $codesign
-  desc: Signing $name
-  cmd: $codesign $entflag$entfile $in && cp $in $out
-stage:
-  name: Staging Commands
-  desc: Running Stage for $name
-  cmd: $stage && $stage2
\ No newline at end of file
diff --git a/README.md b/README.md
index 9927a5a9e..6155ae215 100644
--- a/README.md
+++ b/README.md
@@ -1,10 +1,13 @@
 <p align="center" >
-<img src="branding/dragon.svg" alt="Logo" width=200px> 
+<img src=".github/branding/dragon.svg" alt="Logo" width=200px> 
 </p>
 <p align="center">
   <strong>
   dragon is an expansible build system built for speed and ease of use.
   </strong>
+  <a href="https://github.com/dragonbuild/dragon/actions/workflows/tests.yml">
+    <image src="https://github.com/dragonbuild/dragon/actions/workflows/tests.yml/badge.svg">
+  </a>
 </p>
 
 # Development on this project is currently on a hiatus.
diff --git a/development_install.sh b/development_install.sh
new file mode 100755
index 000000000..4c6ecb2b9
--- /dev/null
+++ b/development_install.sh
@@ -0,0 +1,11 @@
+#!/usr/bin/env bash
+
+#
+# Quick Uninstall/Install script for use when working on the project
+#
+
+rm -rf ~/.dragon
+
+python3 -m pip uninstall dragon
+python3 -m pip install .
+
diff --git a/dragon b/dragon
index 8f4dd1c1f..79b3145c5 100644
--- a/dragon
+++ b/dragon
@@ -1,5 +1,5 @@
 #!/usr/bin/env bash
-export DRAGONVERS="1.4"
+export DRAGONVERS="1.5"
 
 # Defauld dragondir is ~/.dragon
 if [ -z $DRAGONDIR ]; then export DRAGONDIR=$HOME/.dragon; fi
@@ -7,6 +7,7 @@ if [ -z $DRAGONDIR ]; then export DRAGONDIR=$HOME/.dragon; fi
 # Run setup wizard if dragondir is empty or nonexistant
 if [ -z "$(ls -A $DRAGONDIR 2> /dev/null)" ]; then
     python3 -m dragontools.wizard
+    exit 0
 fi
 
 
@@ -55,7 +56,7 @@ while [ "$1" != "" ]; do
                                 ;;
         g | gen | generate)     gen=1
                                 ;;
-        n | nic | new)          python3 $DRAGONBUILD/bin/nic.py
+        n | nic | new)          python3 $DRAGONDIR/bin/nic.py
                                 drexit
                                 ;;
         exp | export)           gen=1
@@ -102,14 +103,14 @@ while [ "$1" != "" ]; do
         u | update )            update
                                 drexit
                                 ;;
-        rs | respring )         python3 $DRAGONBUILD/internal/tools/device.py run killall -9 SpringBoard
+        rs | respring )         python3 -m dragontools.device run killall -9 SpringBoard
                                 drexit
                                 ;;
         dr | devicerun )        shift
-                                python3 $DRAGONBUILD/internal/tools/device.py run $*
+                                python3 -m dragontools.device run $*
                                 drexit
                                 ;;
-        s | device)             python3 $DRAGONBUILD/internal/tools/device.py setup
+        s | device)             python3 -m dragontools.device setup
                                 ;;
         sr | rconf )            setupRemote
                                 ;;
@@ -123,7 +124,7 @@ while [ "$1" != "" ]; do
                                 drexit
                                 ;;
         r | remote )            shift
-                                bash $DRAGONBUILD/internal/tools/remote $*
+                                bash $DRAGONDIR/internal/tools/remote $*
                                 drexit
                                 ;;
         relink )                rm .dragon/sign
@@ -137,7 +138,7 @@ while [ "$1" != "" ]; do
         time )                  N=`date +%s%N`; export PS4='+[$(((`date +%s%N`-$N)/1000000))ms][${BASH_SOURCE}:${LINENO}]: ${FUNCNAME[0]:+${FUNCNAME[0]}(): }';
                                 set -x
                                 ;;
-        v | -v )                cat $DRAGONBUILD/internal/branding/banner.txt
+        v | -v )                cat $DRAGONDIR/internal/banner.txt
                                 ;;
         * )                     usage
                                 drexit 1
@@ -155,8 +156,8 @@ cwd=$(basename $PWD)
 
 if [ $gen == 1 ]; then
     rm -rf .dragon/ninja/build.ninja
-    mkdir -p .dragon/ninja > /dev/null
-    mkdir -p .dragon/modules > /dev/null
+    mkdir -p .dragon/ninja 2>/dev/null
+    mkdir -p .dragon/modules 2>/dev/null
 
     generate
 
@@ -181,10 +182,19 @@ if [ $build == 1 ]; then
     subsb=($(python3 -c "print('${project_dirs}' if ('${project_dirs}'.count('.')<2) else '${project_names}')"))
     set +f
 
+    mkdir -p .dragon 
+    cp DragonMake .dragon/DragonMake
+
     for i in ${subsb[@]}; do
+        # Copy the DragonMake into the subproject's build directory
+        # Primarily for bundle filter gen, right now.
+        [[ -d $i ]] && mkdir -p $i/.dragon/ && cp DragonMake $i/.dragon/DragonMake
+
         build $i
     done
 
+    find . -name '.clean' -type f -delete
+
     if [ $DRAGON_DPKG == 1 ]; then
         create_package
     fi
@@ -209,14 +219,14 @@ if [ $install == 1 ] && [ $DRAGON_DPKG == 1 ]; then
 
     INSTALL_CMD=$(yaml DragonMake "['icmd']" || echo "sbreload")
 
-    python3 $DRAGONBUILD/internal/tools/device.py run ${INSTALL_CMD} || drexit
+    python3 -m dragontools.device run ${INSTALL_CMD} || drexit
 fi
 
 # --------
 # On-device debugging
 # --------
 if [ $debug == 1 ] ; then
-    eval $(python3 $DRAGONBUILD/internal/tools/device.py get)
+    eval $(python3 $DRAGONDIR/internal/tools/device.py get)
     echo -e "${PrefixColor}[Dragon]${BoldColor} Starting on device debugger and targeting '$debugproc' ${NC}"
     ssh -p $DRBPORT root@$DRBIP "command -v lldb || apt-get install lldb" || drexit
     ssh -p $DRBPORT root@$DRBIP "lldb -n $debugproc" || ssh -p $DRBPORT root@$DRBIP "killall lldb"
diff --git a/dragontools/deployable/defaults.yml b/dragontools/deployable/defaults.yml
deleted file mode 100644
index ab1116e22..000000000
--- a/dragontools/deployable/defaults.yml
+++ /dev/null
@@ -1,256 +0,0 @@
----
-# Special thanks to uroboro for suggesting this
-# Configurations here should provide enough default variables to create the specified module;
-# Please reach out to _kritanta if you need advice on extending these
-Defaults:
-  proj_build_dir: .dragon
-  builddir: $proj_build_dir/build
-  objdir: $proj_build_dir/obj
-  signdir: $proj_build_dir/sign
-  bridging-header: $name-Bridging-Header.h
-  dragondir: $$DRAGONBUILD
-  toolchain-prefix: arm64-apple-darwin14-
-  tool-prefix: ''
-  cc: clang
-  cxx: clang++
-  ld: clang++
-  nopack: No
-  codesign: ldid
-  dsym: dsymutil
-  plutil: plutil
-  swift: swift
-  lipo: lipo
-  logos: $dragondir/src/logos/bin/logos.pl
-  cargo: cargo
-  cargo-nightly: 'cargo +nightly'
-  optool: $dragondir/bin/optool
-  stage:
-    - 'true'
-  wild_recurse: No
-  warnings: -Wall
-  optim: "0"
-  debug: -fcolor-diagnostics
-  idflag: ''
-  entflag: '-S'
-  entfile: ''
-  resource_dir: 'Resources'
-  fw_dirs:
-    - $dragondir/sdks/iPhoneOS.sdk/System/Library/PrivateFrameworks/
-    - $dragondir/frameworks
-  lib_dirs:
-    - $dragondir/lib
-    - '.'
-  additional_lib_dirs:
-  additional_fw_dirs:
-  cinclude: '-I$dragondir/include -I$dragondir/vendor/include -I$dragondir/include/_fallback -I$DRAGONBUILD/headers/ -I$pwd'
-  stagedir: '_'
-  modulesinternal: '-fmodules -fcxx-modules -fmodule-name=$name -fbuild-session-file=$proj_build_dir/modules/ -fmodules-validate-once-per-build-session -fmodules-prune-after=345600 -fmodules-prune-interval=86400'
-
-# Touching these without a firm grasp of what you're doing is likely to break things
-# They serve to abstract how we slap together all of the clang args
-InternalDefaults:
-  internalcflags: '$cinclude $debug $fwSearch $cflags $btarg -O$optim  $targetprefix$targetvers $sysroot $header_includes $arc $triple $theosshim $macros $warnings $modulesinternal'
-  internalswiftflags: '-color-diagnostics -enable-objc-interop -sdk /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk -L/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/iphoneos -g -L/usr/lib/swift -swift-version 5 -module-name $name'
-  internalfflags: '$internalcflags $typeldflags $frameworks $libs $libflags $lopts $libSearch $ldflags $libs'
-  internalldflags: '$internalcflags $typeldflags $frameworks $libs $libflags $lopts $libSearch $ldflags $libs'
-  internalsigntarget: '$signdir/$build_target_file.unsigned'
-  internalsymtarget: '$signdir/$build_target_file.unsym'
-  internallibflags: '-lobjc -lc++'
-  pwd: '.'
-Targets:
-  sim:
-    all:
-      targetos: iphonesimulator
-      triple: MACHINE
-      arc: yes
-      sysroot: /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk
-      archs:
-        - MACHINE
-  ios:
-    all:
-      targetos: iphoneos
-      targetvers: 10.0
-      triple: arm64-apple-ios$targetvers
-      targetprefix: -miphoneos-version-min=
-      arc: yes
-      sysroot: $dragondir/sdks/iPhoneOS.sdk
-      archs:
-        - armv7
-        - arm64
-        - arm64e
-  watchos:
-    all:
-      targetos: watchos
-      targetvers: 5.0
-      arc: yes
-      sysroot: $dragondir/sdks/WatchOS.sdk
-      archs: arm64_32
-  host:
-    all:
-      triple: MACHINE
-      archs:
-        - MACHINE
-Types:
-  comprehensive:
-  app:
-    required_states:
-      - has_build_files
-    variables:
-      install_location: '/Applications/'
-      target: '$proj_build_dir/$stagedir/$location/$name.app/$name'
-  application:
-    required_states:
-      - has_build_files
-    variables:
-      install_location: '/Applications/'
-      target: '$proj_build_dir/$stagedir/$location/$name.app/$name'
-  tweak-jailed:
-    required_states:
-      - has_build_files
-    variables:
-      install_location: '/Applications/'
-      target: '$proj_build_dir/$stagedir/$location/$name.app/$name'
-      loader: DragonLoad
-      embed-libs:
-        - CydiaSubstrate
-  tweak:
-    required_states:
-      - has_build_files
-    production:
-      deb:
-        - 'build-files'
-        - 'copy-to-target'
-    production_allow:
-      - deb
-    variables:
-      install_location: '/Library/MobileSubstrate/DynamicLibraries/'
-      build_target_file: '$proj_build_dir/$stagedir/$location$name.dylib'
-      hooker-priority: libhooker
-      lang: logos
-      lopts: '-dynamiclib -ggdb -Xlinker -segalign -Xlinker 4000 -framework CydiaSubstrate'
-      frameworks:
-        - UIKit
-        - Foundation
-      stage2:
-        - 'cp $name.plist $proj_build_dir/_/Library/MobileSubstrate/DynamicLibraries/$name.plist'
-  prefs:
-    required_states:
-      - has_build_files
-    production_allow:
-      - deb
-    variables:
-      install_location: '/Library/PreferenceBundles/$name.bundle'
-      build_target_file: '$proj_build_dir/$stagedir$location/$name'
-      libs:
-        - 'substrate'
-      lopts: '-dynamiclib -ggdb -Xlinker -segalign -Xlinker 4000 -framework Preferences'
-      frameworks:
-        - UIKit
-        - Foundation
-      stage2:
-        - 'mkdir -p .dragon/_/Library/PreferenceLoader/Preferences/'
-        - 'cp entry.plist .dragon/_/Library/PreferenceLoader/Preferences/$name.plist'
-        - 'cp -R Resources/ $proj_build_dir/$stagedir/$location'
-  bundle:
-    required_states:
-      - has_build_files
-    production_allow:
-      - deb
-    variables:
-      install_location: '/Library/$name/'
-      build_target_file: '$proj_build_dir/$stagedir/$location/$name.bundle/$name'
-      lopts: '-dynamiclib -ggdb -Xlinker -segalign -Xlinker 4000'
-      frameworks:
-        - UIKit
-        - Foundation
-      stage2:
-        - 'cp -R Resources/ $proj_build_dir/$stagedir/$location/$name.bundle/'
-
-  framework:
-    required_states:
-      - has_build_files
-    production_allow:
-      - deb
-    variables:
-      install_location: '/Library/Frameworks/$name.framework'
-      build_target_file: '$proj_build_dir/$stagedir/$location/$name'
-      lopts: '-dynamiclib -ggdb -Xlinker -segalign -Xlinker 4000'
-      frameworks:
-        - Foundation
-      stage2:
-        - 'cp -R Resources/ $proj_build_dir/$stagedir/$location'
-        - 'cp -R $proj_build_dir/$stagedir$location $$DRAGONBUILD/frameworks/$name.framework'
-        - 'if [ ! -z "$public_headers" ]; then
-           mkdir -p $proj_build_dir/$stagedir/$location/Headers;
-           cp $public_headers $proj_build_dir/$stagedir/$location/Headers;
-           fi'
-  resource-bundle:
-    required_states:
-    production_allow:
-      - deb
-    variables:
-      install_location: '/Library/$name/$name.bundle/'
-      build_target_file: 'build.ninja'
-      libs:
-        - 'substrate'
-      lopts: '-dynamiclib -ggdb -Xlinker -segalign -Xlinker 4000'
-      frameworks:
-        - UIKit
-        - Foundation
-      stage2:
-        - 'true;'
-  stage:
-    variables:
-      build_target_file: 'build.ninja'
-      stage2:
-        - 'true;'
-  library:
-    required_states:
-      - has_build_files
-    production_allow:
-      - deb
-      - raw
-    variables:
-      install_location: 'usr/lib'
-      build_target_file: '$proj_build_dir/$stagedir/$location/$name.dylib'
-      ldflags: '-install_name $location$name.dylib'
-      lopts: '-dynamiclib -ggdb -Xlinker -segalign -Xlinker 4000'
-      stage2:
-        - 'true;'
-  cli:
-    required_states:
-      - has_build_files
-    production_allow:
-      - deb
-      - raw
-    variables:
-      install_location: '/usr/bin'
-      lopts: ''
-      build_target_file: '$proj_build_dir/$stagedir/$location/$name'
-      stage2:
-        - 'true;'
-  tool:
-    required_states:
-      - has_build_files
-    production_allow:
-      - deb
-      - raw
-    variables:
-      install_location: '/usr/bin'
-      lopts: ''
-      build_target_file: '$proj_build_dir/$stagedir/$location/$name'
-      stage2:
-        - 'true;'
-  static:
-    required_states:
-      - has_build_files
-    production_allow:
-      - deb
-      - raw
-    variables:
-      install_location: '/usr/lib'
-      lopts: ''
-      build_target_file: '$proj_build_dir/$stagedir/$location/$name.a'
-      stage2:
-        - 'true;'
-  raw:
diff --git a/dragontools/deployable/environment b/dragontools/deployable/environment
deleted file mode 100644
index 33c9f52cb..000000000
--- a/dragontools/deployable/environment
+++ /dev/null
@@ -1,5 +0,0 @@
-#!/bin/bash
-
-export PATH="$PATH:/usr/local/bin/:$DRAGONBUILD/bin/"
-
-export DRAGONVERS="1.3"
diff --git a/setup.py b/setup.py
index 2f1564f58..cab649c23 100644
--- a/setup.py
+++ b/setup.py
@@ -1,17 +1,17 @@
 from setuptools import setup
 
-setup(name='Dragon',
-      version='1.4',
+setup(name='dragon',
+      version='1.5',
       description='A powerful toolkit targeting Apple development research, '
       'and packaging.',
       author='kritanta',
       url='https://github.com/DragonBuild/dragon',
       requires=['pyyaml'],
-      packages=['dragongen', 'dragongen.buildgen', 'dragontools'],
+      packages=['dragongen', 'buildgen', 'dragontools'],
       package_dir={
-          'dragongen': 'DragonGen/dragongen',
-          'dragontools': 'dragontools',
-          'dragongen.buildgen': 'DragonGen/dragongen/buildgen',
+          'dragongen': 'src/dragongen',
+          'dragontools': 'src/dragontools',
+          'buildgen': 'src/buildgen',
       },
       package_data={
           'dragontools': ['shscripts/*', 'deployable/*'],
diff --git a/src/README.md b/src/README.md
deleted file mode 100644
index 32b5f3349..000000000
--- a/src/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# DragonBuild/src
-
-This folder contains tools we need to build from source.
\ No newline at end of file
diff --git a/DragonGen/dragongen/__init__.py b/src/buildgen/__init__.py
similarity index 100%
rename from DragonGen/dragongen/__init__.py
rename to src/buildgen/__init__.py
diff --git a/DragonGen/dragongen/buildgen/generator.py b/src/buildgen/generator.py
similarity index 97%
rename from DragonGen/dragongen/buildgen/generator.py
rename to src/buildgen/generator.py
index 93ba9d945..d59b27635 100644
--- a/DragonGen/dragongen/buildgen/generator.py
+++ b/src/buildgen/generator.py
@@ -4,8 +4,8 @@
 with standard syntax.
 """
 from enum import Enum
-from buildgen.makefile_generator import MakefileWriter
-from buildgen.ninja_generator import NinjaWriter
+from .makefile_generator import MakefileWriter
+from .ninja_generator import NinjaWriter
 
 
 class BuildSystem(Enum):
diff --git a/DragonGen/dragongen/buildgen/makefile_generator.py b/src/buildgen/makefile_generator.py
similarity index 98%
rename from DragonGen/dragongen/buildgen/makefile_generator.py
rename to src/buildgen/makefile_generator.py
index b629cc873..52c0200ff 100644
--- a/DragonGen/dragongen/buildgen/makefile_generator.py
+++ b/src/buildgen/makefile_generator.py
@@ -1,7 +1,7 @@
 import re
 import textwrap
 
-from buildgen.writer import Writer
+from .writer import Writer
 
 
 class MakefileWriter(Writer):
diff --git a/DragonGen/dragongen/buildgen/ninja_generator.py b/src/buildgen/ninja_generator.py
similarity index 99%
rename from DragonGen/dragongen/buildgen/ninja_generator.py
rename to src/buildgen/ninja_generator.py
index f9624f225..7b2740564 100644
--- a/DragonGen/dragongen/buildgen/ninja_generator.py
+++ b/src/buildgen/ninja_generator.py
@@ -12,7 +12,7 @@
 
 import re
 import textwrap
-from buildgen.writer import Writer
+from .writer import Writer
 
 
 def escape_path(word):
diff --git a/DragonGen/dragongen/buildgen/writer.py b/src/buildgen/writer.py
similarity index 100%
rename from DragonGen/dragongen/buildgen/writer.py
rename to src/buildgen/writer.py
diff --git a/DragonGen/dragongen/buildgen/__init__.py b/src/dragongen/__init__.py
similarity index 100%
rename from DragonGen/dragongen/buildgen/__init__.py
rename to src/dragongen/__init__.py
diff --git a/DragonGen/dragongen/generation.py b/src/dragongen/generation.py
similarity index 98%
rename from DragonGen/dragongen/generation.py
rename to src/dragongen/generation.py
index 03c8a1d46..3fce60d07 100644
--- a/DragonGen/dragongen/generation.py
+++ b/src/dragongen/generation.py
@@ -25,19 +25,15 @@
 
 '''
 
-import os
-from pprint import pprint
-import sys
-import termios
 import traceback
-import tty
 import platform
 from collections import namedtuple
 from datetime import datetime
 from typing import TextIO
+import yaml
 
-from variable_types import ProjectVars
-from util import *
+from .variable_types import ProjectVars
+from .util import *
 from buildgen.generator import BuildFileGenerator
 
 
@@ -497,9 +493,8 @@ def get_default_section_dict(*key_path: str) -> dict:
     '''
 
     global _LAZY_DEFAULTS_DOT_YML
-    if _LAZY_DEFAULTS_DOT_YML is None:
-        with open(f'{os.environ["DRAGONDIR"]}/internal/defaults.yml') as f:
-            _LAZY_DEFAULTS_DOT_YML = yaml.safe_load(f)
+    with open(f'{os.environ["DRAGONDIR"]}/internal/defaults.yml') as f:
+        _LAZY_DEFAULTS_DOT_YML = yaml.safe_load(f)
 
     key_path = list(key_path)
     ret = _LAZY_DEFAULTS_DOT_YML.copy()
@@ -542,6 +537,9 @@ def main():
         'icmd': 'install_command',
         'ip': 'DRBIP',
         'postinst': None,
+        'preinst': None,
+        'postrm': None,
+        'prerm': None,
         'port': 'DRBPORT',
         'id': None,
         'mtn': None,
diff --git a/DragonGen/dragongen/util.py b/src/dragongen/util.py
similarity index 99%
rename from DragonGen/dragongen/util.py
rename to src/dragongen/util.py
index ac3be639a..da60016f8 100644
--- a/DragonGen/dragongen/util.py
+++ b/src/dragongen/util.py
@@ -3,7 +3,7 @@
 from pprint import pprint
 import termios
 import tty 
-from variable_types import ArgList
+from .variable_types import ArgList
 
 colors = [["\033[0;31m","\033[0;32m","\033[0;33m","\033[0;34m","\033[0;36m",
 "\033[0;37m","\033[0m"],["\033[1;31m","\033[1;32m","\033[1;33m","\033[1;34m",
diff --git a/DragonGen/dragongen/variable_types.py b/src/dragongen/variable_types.py
similarity index 100%
rename from DragonGen/dragongen/variable_types.py
rename to src/dragongen/variable_types.py
diff --git a/dragontools/__init__.py b/src/dragontools/__init__.py
similarity index 100%
rename from dragontools/__init__.py
rename to src/dragontools/__init__.py
diff --git a/src/dragontools/bfilter.py b/src/dragontools/bfilter.py
new file mode 100644
index 000000000..533c3b088
--- /dev/null
+++ b/src/dragontools/bfilter.py
@@ -0,0 +1,39 @@
+import yaml, os, sys
+
+colors = [["\033[0;31m","\033[0;32m","\033[0;33m","\033[0;34m","\033[0;36m",
+"\033[0;37m","\033[0m"],["\033[1;31m","\033[1;32m","\033[1;33m","\033[1;34m",
+"\033[1;36m","\033[1;37m","\033[0m"]]
+
+def dprintline(col: int, tool: str, textcol: int, bold: int, pusher: int, msg: str):
+    print("%s[%s]%s %s%s%s" % (
+        colors[1][col], tool, colors[bold][textcol], ">>> " if pusher else "", msg, colors[0][6]))
+
+dbstate = lambda msg: dprintline(1, "Packager", 5, 1, 0, msg)
+dbwarn = lambda msg: dprintline(2, "Packager", 5, 0, 0, msg)
+dberror = lambda msg: dprintline(0, "Packager", 5, 1, 0, msg)
+
+# This script will get called w/ 
+# argc=3  argv[0]                          argv[1]     argv[2]    
+# python3 $DRAGONDIR/internal/bfilter.py DragonMake  projectName
+
+def main():
+    if os.path.exists(sys.argv[1]):
+        with open(sys.argv[1]) as f:
+            config = yaml.safe_load(f)
+
+    # dbstate("Creating Filter for " + sys.argv[2])
+
+    filter_dict = config[sys.argv[2]]['filter']
+    print(filter_serialize(filter_dict))
+
+    
+def filter_serialize(filter_dict):
+    # {'executables':['SpringBoard']}
+    # out: { Filter = { Executables = ( "SpringBoard" ); }; }
+    ind = "{ Filter = { "
+    for i in filter_dict:
+        ind += i.capitalize() + ' = ( ' + ", ".join(["\"" + j + "\"" for j in filter_dict[i]]) + ' );'
+    ind += ' }; }'
+    return ind
+
+main()
\ No newline at end of file
diff --git a/dragontools/control.py b/src/dragontools/control.py
similarity index 97%
rename from dragontools/control.py
rename to src/dragontools/control.py
index e20f67f0e..1ce6fdafc 100644
--- a/dragontools/control.py
+++ b/src/dragontools/control.py
@@ -14,7 +14,7 @@ def dprintline(col: int, tool: str, textcol: int, bold: int, pusher: int, msg: s
 
 # This script will get called w/ 
 # argc=3  argv[0]                          argv[1]    argv[2]
-# python3 $DRAGONBUILD/internal/control.py DragonMake ./.dragon/_/DEBIAN/control
+# python3 $DRAGONDIR/internal/control.py DragonMake ./.dragon/_/DEBIAN/control
 def main():
     dbstate("Pulling 'control' values from DragonMake")
 
diff --git a/branding/banner.txt b/src/dragontools/deployable/banner.txt
similarity index 90%
rename from branding/banner.txt
rename to src/dragontools/deployable/banner.txt
index 31b835463..fa4b74c47 100644
--- a/branding/banner.txt
+++ b/src/dragontools/deployable/banner.txt
@@ -10,8 +10,8 @@
 ████      ▀█¬      ▐███████    ▐███▌       ▐██   ▐██  ▐██    ██▀└-▐██  ██▄   ██▌ ▐██   ▐██  ██⌐  j██
 ▀███,           ;.┌████████─▌  ████         ▀████▀██  ▐██    ▀████▀██  .▀███▀██▌  ▀█████▀.  ██⌐  j██
  ████         ▄▀╓██████████ ╫▌▄███▌                                    ¥▓▄▄.▄██─  
- └████,   ╓▄██└▄█████████▌▌ █████▀                                      └╙▀▀▀-         version 1.3.0
+ └████,   ╓▄██└▄█████████▌▌ █████▀                                      └╙▀▀▀-         version 1.5.0
    ████████▀┌▄███████████═ ▄████▀                                                         ~ kritanta
     ╙█████▄▓█████████████▓████▀
-      └▀████████████████████▀
-          ╙▀▀██████████▀▀└
+      └▀████████████████████▀               this project was made possible by l0renzo pane.
+          ╙▀▀██████████▀▀└                  thank you.
diff --git a/DragonGen/defaults.yml b/src/dragontools/deployable/defaults.yml
similarity index 95%
rename from DragonGen/defaults.yml
rename to src/dragontools/deployable/defaults.yml
index ab1116e22..7cf9de40a 100644
--- a/DragonGen/defaults.yml
+++ b/src/dragontools/deployable/defaults.yml
@@ -8,7 +8,7 @@ Defaults:
   objdir: $proj_build_dir/obj
   signdir: $proj_build_dir/sign
   bridging-header: $name-Bridging-Header.h
-  dragondir: $$DRAGONBUILD
+  dragondir: $$DRAGONDIR
   toolchain-prefix: arm64-apple-darwin14-
   tool-prefix: ''
   cc: clang
@@ -42,7 +42,7 @@ Defaults:
     - '.'
   additional_lib_dirs:
   additional_fw_dirs:
-  cinclude: '-I$dragondir/include -I$dragondir/vendor/include -I$dragondir/include/_fallback -I$DRAGONBUILD/headers/ -I$pwd'
+  cinclude: '-I$dragondir/include -I$dragondir/vendor/include -I$dragondir/include/_fallback -I$DRAGONDIR/headers/ -I$pwd'
   stagedir: '_'
   modulesinternal: '-fmodules -fcxx-modules -fmodule-name=$name -fbuild-session-file=$proj_build_dir/modules/ -fmodules-validate-once-per-build-session -fmodules-prune-after=345600 -fmodules-prune-interval=86400'
 
@@ -128,11 +128,11 @@ Types:
       hooker-priority: libhooker
       lang: logos
       lopts: '-dynamiclib -ggdb -Xlinker -segalign -Xlinker 4000 -framework CydiaSubstrate'
-      frameworks:
+      frameworks:  
         - UIKit
         - Foundation
       stage2:
-        - 'cp $name.plist $proj_build_dir/_/Library/MobileSubstrate/DynamicLibraries/$name.plist'
+        - 'cp $name.plist $proj_build_dir/_/Library/MobileSubstrate/DynamicLibraries/$name.plist 2>/dev/null  || python3 -m dragontools.bfilter $proj_build_dir/DragonMake $name > $proj_build_dir/_/Library/MobileSubstrate/DynamicLibraries/$name.plist'
   prefs:
     required_states:
       - has_build_files
@@ -179,7 +179,7 @@ Types:
         - Foundation
       stage2:
         - 'cp -R Resources/ $proj_build_dir/$stagedir/$location'
-        - 'cp -R $proj_build_dir/$stagedir$location $$DRAGONBUILD/frameworks/$name.framework'
+        - 'cp -R $proj_build_dir/$stagedir$location $$DRAGONDIR/frameworks/$name.framework'
         - 'if [ ! -z "$public_headers" ]; then
            mkdir -p $proj_build_dir/$stagedir/$location/Headers;
            cp $public_headers $proj_build_dir/$stagedir/$location/Headers;
@@ -225,7 +225,6 @@ Types:
       - raw
     variables:
       install_location: '/usr/bin'
-      lopts: ''
       build_target_file: '$proj_build_dir/$stagedir/$location/$name'
       stage2:
         - 'true;'
diff --git a/src/dragontools/deployable/environment b/src/dragontools/deployable/environment
new file mode 100644
index 000000000..946f6cae8
--- /dev/null
+++ b/src/dragontools/deployable/environment
@@ -0,0 +1,5 @@
+#!/bin/bash
+
+export PATH="$PATH:/usr/local/bin/:$DRAGONDIR/bin/"
+
+export DRAGONVERS="1.3"
diff --git a/dragontools/deployable/rules.yml b/src/dragontools/deployable/rules.yml
similarity index 99%
rename from dragontools/deployable/rules.yml
rename to src/dragontools/deployable/rules.yml
index 5adca5cd7..f468c9566 100644
--- a/dragontools/deployable/rules.yml
+++ b/src/dragontools/deployable/rules.yml
@@ -6,7 +6,7 @@ logos:
 prefs:
   name: DragonPrefs
   desc: Building DragonPrefs
-  cmd: python3 $$DRAGONBUILD/DragonGen/dragonprefs.py $in $out
+  cmd: python3 $$DRAGONDIR/DragonGen/dragonprefs.py $in $out
 swiftarmv6:
   name: Swift armv6
   cmd: SwiftFiles=$$(echo '$swiftfiles $in' | tr ' ' '\\n' | sort | uniq -u); $swift -frontend -c $internalswiftflags $bridgeheader -target armv6-apple-ios -emit-module-path $out.swiftmodule -primary-file $in $$SwiftFiles -o $out
diff --git a/dragontools/deployable/state.yml b/src/dragontools/deployable/state.yml
similarity index 100%
rename from dragontools/deployable/state.yml
rename to src/dragontools/deployable/state.yml
diff --git a/dragontools/device.py b/src/dragontools/device.py
similarity index 97%
rename from dragontools/device.py
rename to src/dragontools/device.py
index 4914066c1..2eac29059 100644
--- a/dragontools/device.py
+++ b/src/dragontools/device.py
@@ -95,7 +95,7 @@ def setup_key_auth(self):
 class DeviceManager(object):
 
     def __init__(self):
-        with open(f'{os.environ["DRAGONBUILD"]}/internal/data/state.yml') as state:
+        with open(f'{os.environ["DRAGONBUILD"]}/internal/state.yml') as state:
             dragon_state = yaml.safe_load(state)
 
         self.dragon_state = dragon_state
@@ -107,7 +107,7 @@ def __init__(self):
         self.current = self.devices[dragon_state['device']['current']]
 
     def savestate(self):
-        with open(f'{os.environ["DRAGONBUILD"]}/internal/data/state.yml', 'w') as state:
+        with open(f'{os.environ["DRAGONBUILD"]}/internal/state.yml', 'w') as state:
             yaml.dump(self.dragon_state, state)
     
     def add_device(self, device: Device):
diff --git a/dragontools/shscripts/building b/src/dragontools/shscripts/building
similarity index 77%
rename from dragontools/shscripts/building
rename to src/dragontools/shscripts/building
index 4927be1bd..45eddb343 100644
--- a/dragontools/shscripts/building
+++ b/src/dragontools/shscripts/building
@@ -4,7 +4,11 @@ clean_dir()
 {
     echo -e "${PrefixColor}[Dragon]${BoldColor} Cleaning $1${NC}"
     # find . -name 'build.ninja' -delete
-    rm -rf .dragon/
+    [[ -f .dragon/DragonMake ]] && cp .dragon/DragonMake .DragonMake
+    rm -rf .dragon 
+    [[ -f .DragonMake ]] && mkdir .dragon && mv .DragonMake .dragon/DragonMake
+    mkdir -p .dragon 
+    touch .dragon/.clean
 }
 
 build()
@@ -21,12 +25,12 @@ build()
     fi
 
     if [ $clean == 1 ]; then 
-        clean_dir $DNAME
+        [[ -f .dragon/.clean ]] || clean_dir $DNAME
     fi
     
-    mkdir -p .dragon/_/.dragonbuilding
+    mkdir -p .dragon/_/.dragonbuilding 2>/dev/null
 
-    mkdir -p .dragon/modules
+    mkdir -p .dragon/modules 2>/dev/null
 
     echo -e "${PrefixColor}[Dragon]${BoldColor} Building ${DNAME}${NC}"
 
@@ -45,7 +49,7 @@ build()
     if [ $1 == "." ]; then 
         true;
     else
-        cp -R .dragon/_ "$projroot"/.dragon
+        cp -R .dragon/_ "$projroot"/.dragon 2>/dev/null
     fi
 
     cd "$projroot" || drexit
diff --git a/dragontools/shscripts/dragoncolors b/src/dragontools/shscripts/dragoncolors
similarity index 100%
rename from dragontools/shscripts/dragoncolors
rename to src/dragontools/shscripts/dragoncolors
diff --git a/dragontools/shscripts/generator b/src/dragontools/shscripts/generator
similarity index 88%
rename from dragontools/shscripts/generator
rename to src/dragontools/shscripts/generator
index ea524a373..ce04b5064 100644
--- a/dragontools/shscripts/generator
+++ b/src/dragontools/shscripts/generator
@@ -4,8 +4,6 @@ generate()
 {
     echo $DGEN_DEBUG | grep "1" > /dev/null && echo "DragonGen Debug Enabled"
 
-    source $DRAGONBUILD/internal/data/dragoncolors
-
     echo $simtarg | grep "1" > /dev/null && echo -e "${GenColor}[DragonGen]${BoldColor} Targeting Simulator + simject${NC}"
 
     eval $(DGEN_DEBUG=${DGEN_DEBUG} TARG_SIM=${simtarg} python3 -m dragongen.generation)
diff --git a/dragontools/shscripts/packaging b/src/dragontools/shscripts/packaging
similarity index 68%
rename from dragontools/shscripts/packaging
rename to src/dragontools/shscripts/packaging
index 033e1af6c..761dd7ac1 100644
--- a/dragontools/shscripts/packaging
+++ b/src/dragontools/shscripts/packaging
@@ -17,28 +17,29 @@ send_package()
         echo -e "${PrefixColor}[Dragon]${BoldColor} $1 not found${NC}"
         drexit
     fi
-    python3 $DRAGONBUILD/internal/tools/device.py test
+    python3 -m dragontools.device test
 
-    eval $(python3 $DRAGONBUILD/internal/tools/device.py get)
+    eval $(python3 -m dragontools.device get)
 
     if [ -z "$DRBIP" ]; then
-        python3 $DRAGONBUILD/internal/tools/device.py setup
+        python3 -m dragontools.device setup
     fi
 
     echo -e "${PrefixColor}[Dragon]${BoldColor} Copying package to device and running install commands${NC}"
-    python3 $DRAGONBUILD/internal/tools/device.py qr mkdir -p /var/mobile/dragon/packages
-    scp -P $DRBPORT ${OUTPUT} root@$DRBIP:/var/mobile/dragon/${OUTPUT} || drexit && python3 $DRAGONBUILD/internal/tools/device.py qr dpkg -i /var/mobile/dragon/${OUTPUT} || drexit && python3 $DRAGONBUILD/internal/tools/device.py qr rm -rf /var/mobile/dragon/${OUTPUT}
+    python3 -m dragontools.device qr mkdir -p /var/mobile/dragon/packages
+    scp -P $DRBPORT ${OUTPUT} root@$DRBIP:/var/mobile/dragon/${OUTPUT} || drexit && python3 -m dragontools.device qr dpkg -i /var/mobile/dragon/${OUTPUT} || drexit && python3 -m dragontools.device qr rm -rf /var/mobile/dragon/
 }
 
 create_package()
 {
     echo -e "${PackageColor}[Packager]${NC} Generating Package Structure"
     mv .dragon/_/.dragonbuilding .dragon/_/DEBIAN
-    cp control .dragon/_/DEBIAN/control 2>/dev/null || python3 $DRAGONBUILD/internal/tools/control.py DragonMake ./.dragon/_/DEBIAN/control 
+    cp control .dragon/_/DEBIAN/control 2>/dev/null || python3 -m dragontools.control DragonMake ./.dragon/_/DEBIAN/control 
     du -d 0 .dragon/_ | xargs -I '{}' echo 'Installed-Size: {}' | cut -d ' ' -f 1,2 >> .dragon/_/DEBIAN/control
     chmod -R 0755 .dragon/_/DEBIAN/*
     mkdir -p .dragon/packages
     find . -name '.DS_Store' -type f -delete
+    find . -name '.dragonbuilding' -delete
     echo -e "${PackageColor}[Packager]${BoldColor} Building Package${NC}"
     dpkg-deb --build -Zgzip -z9 .dragon/_ .dragon/packages/
     GENOUTPUT="$(ls .dragon/packages)"
diff --git a/dragontools/shscripts/remote b/src/dragontools/shscripts/remote
similarity index 85%
rename from dragontools/shscripts/remote
rename to src/dragontools/shscripts/remote
index 308087581..796a5f9f5 100644
--- a/dragontools/shscripts/remote
+++ b/src/dragontools/shscripts/remote
@@ -1,9 +1,9 @@
 #!/usr/bin/env bash
 
-source $DRAGONBUILD/internal/data/dragoncolors
+source $DRAGONDIR/internal/data/dragoncolors
 
 set -e
-source $DRAGONBUILD/state/remoteip
+source $DRAGONDIR/state/remoteip
 LDIR=$PWD
 RDIR=$(python3 -c 'import os;print("~/.dragonbuild/server/" + os.getenv("PWD")')
 RPAR="$(dirname "$RDIR")"
diff --git a/dragontools/shscripts/simulator b/src/dragontools/shscripts/simulator
similarity index 74%
rename from dragontools/shscripts/simulator
rename to src/dragontools/shscripts/simulator
index 5289d0270..4bce8a175 100644
--- a/dragontools/shscripts/simulator
+++ b/src/dragontools/shscripts/simulator
@@ -9,18 +9,18 @@ simfail()
 
 simsetup()
 {
-    mkdir -p $DRAGONBUILD/simulator/load
+    mkdir -p $DRAGONDIR/simulator/load
     hold=$PWD
-    cd $DRAGONBUILD/src/simject || simfail
+    cd $DRAGONDIR/src/simject || simfail
     dragon c b
     cd $hold || simfail
 }
 
 simstall()
 {
-    test -f $DRAGONBUILD/simulator/resim || simsetup
+    test -f $DRAGONDIR/simulator/resim || simsetup
     echo -e "${PrefixColor}[Dragon]${BoldColor} Installing files to the simulator..."
-    cp .dragon/_/Library/MobileSubstrate/DynamicLibraries/* $DRAGONBUILD/simulator/load || cleanbuildfail
+    cp .dragon/_/Library/MobileSubstrate/DynamicLibraries/* $DRAGONDIR/simulator/load || cleanbuildfail
     echo -e "${PrefixColor}[Dragon]${BoldColor} Respringing..."
     resim
 }
\ No newline at end of file
diff --git a/dragontools/shscripts/util b/src/dragontools/shscripts/util
similarity index 95%
rename from dragontools/shscripts/util
rename to src/dragontools/shscripts/util
index cee9a654d..11c7b93ff 100644
--- a/dragontools/shscripts/util
+++ b/src/dragontools/shscripts/util
@@ -37,20 +37,20 @@ setupRemote()
     # remote.py | remote.sh
     echo -e "${PrefixColor}[Dragon]${NC} Enter Server IP"
     read IPA
-    echo "export IPA=\"$IPA\"" > $DRAGONBUILD/state/remoteip
+    echo "export IPA=\"$IPA\"" > $DRAGONDIR/state/remoteip
     echo -e "${PrefixColor}[Dragon]${NC} Enter Username"
     read USERN
     if [ -z "$USERN" ]; then
         USERN="root"
     fi
-    echo "export USERN=\"$USERN\"" >> $DRAGONBUILD/state/remoteip
+    echo "export USERN=\"$USERN\"" >> $DRAGONDIR/state/remoteip
 }
 
 update()
 {
     # update.sh
     x=$PWD
-    cd $DRAGONBUILD || drexit
+    cd $DRAGONDIR || drexit
     git pull
     git submodule update --init --recursive
     cd $x || drexit
diff --git a/dragontools/shscripts/variables b/src/dragontools/shscripts/variables
similarity index 92%
rename from dragontools/shscripts/variables
rename to src/dragontools/shscripts/variables
index d1f6d7e54..9d5546039 100644
--- a/dragontools/shscripts/variables
+++ b/src/dragontools/shscripts/variables
@@ -23,7 +23,7 @@ export release=0
 
 export ToolchainPath=""
 export ToolchainPrefix=""
-command -v dsymutil >/dev/null || export ToolchainPath="${DRAGONBUILD}/toolchain/bin/"; export ToolchainPrefix="";
+command -v dsymutil >/dev/null || export ToolchainPath="${DRAGONDIR}/toolchain/bin/"; export ToolchainPrefix="";
 
 
 # This controls ninja colors.
diff --git a/dragontools/util.py b/src/dragontools/util.py
similarity index 100%
rename from dragontools/util.py
rename to src/dragontools/util.py
diff --git a/dragontools/wizard.py b/src/dragontools/wizard.py
similarity index 70%
rename from dragontools/wizard.py
rename to src/dragontools/wizard.py
index ff8a96d59..c5e53efff 100644
--- a/dragontools/wizard.py
+++ b/src/dragontools/wizard.py
@@ -27,18 +27,9 @@ def setup_wizard():
     if os.environ.get('foo'):
         exit(0)
 
-    columns = int(os.popen('stty size', 'r').read().split()[1])
-
-    log('DragonBuild setup utility'.center(columns))
-    log('========================='.center(columns), end='\n\n')
-    log('For basic users, press return for default options')
-
-    dragondir = os.path.expandvars(
-        get_input('Dragonbuild directory', '$HOME/.dragon/')
-    )
-    if dragondir != os.path.expandvars('$HOME/.dragon/'):
-        log('Be sure to set $DRAGONDIR in your shell profile!')
-
+    log('installing dragon v1.5')
+    log('=========================', end='\n\n')
+    dragondir = os.path.expandvars('$HOME/.dragon/')
     try:
         os.mkdir(os.path.expandvars(dragondir))
     except FileExistsError:
@@ -46,15 +37,21 @@ def setup_wizard():
 
     os.chdir(dragondir)
 
-    for repo in ('lib', 'include', 'frameworks', 'vendor', 'sdks'):
-        get_supporting(
-            f'https://api.github.com/repos/DragonBuild/{repo}/releases/latest',
-            repo
-        )
+    for repo in ('lib', 'include', 'frameworks', 'vendor', 'sdks', 'src'):
+        try:
+            get_supporting(
+                f'https://api.github.com/repos/DragonBuild/{repo}/releases/latest',
+                repo
+            )
+        except: 
+            log('Potentially ratelimited, attempting fallback by cloning repo (this adds some overhead)')
+            os.system(f'git clone https://github.com/dragonbuild/{repo} --depth 1')
 
     log('Deploying internal configuration')
     shutil.copytree(deployable_path(),
                     dragondir + '/internal')
+                    
+    os.mkdir(os.path.expandvars('$HOME/.dragon/toolchain'))
     log('Done!')
 
 
@@ -80,3 +77,4 @@ def get_supporting(api: str, destination: str):
 
 if __name__ == '__main__':
     setup_wizard()
+    os.system('dragon v')
diff --git a/toolchain/.keep b/toolchain/.keep
deleted file mode 100644
index e69de29bb..000000000


Test patch:
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
new file mode 100644
index 000000000..9e9ffae54
--- /dev/null
+++ b/.github/workflows/tests.yml
@@ -0,0 +1,60 @@
+# This workflow will install Python dependencies, run tests and lint with a single version of Python
+# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions
+
+name: tests
+
+on:
+  push:
+    paths-ignore:
+      - '**/*.md'
+      - '**/*.txt'
+    branches:
+      - master
+      - 'dev/**'
+  pull_request:
+    paths-ignore:
+      - '**/*.md'
+      - '**/*.txt'
+    branches:
+      - master
+      - 'dev/**'
+
+jobs:
+  tests:
+    strategy:
+      matrix:
+        project-link: 
+          - https://github.com/KritantaDev/Chapters
+          - https://github.com/KritantaDev/Docky
+          - https://github.com/KritantaDev/Shakelight
+          - https://github.com/KritantaDev/Gravitation
+          - https://github.com/KritantaDev/Signe
+          - https://github.com/KritantaDev/StatusViz
+          - https://github.com/KritantaDev/StopCrashingPls
+          - https://github.com/KritantaDev/libCozy
+    runs-on: macos-latest
+    steps:
+    - uses: actions/checkout@v2
+    - name: Set up Python
+      uses: actions/setup-python@v2
+      with:
+        python-version: 3.9.5
+    - name: Install dependencies
+      run: |
+        python -m pip install --upgrade pip
+        pip install pyyaml
+        pip install git+git://github.com/dragonbuild/dragon@dev
+        brew install ldid
+        brew install ninja
+        brew install dpkg
+        if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
+    - name: Install DragonBuild
+      run: |
+        dragon
+    - name: Cloning Project
+      run: |
+        git clone ${{ matrix.project-link }}
+    - name: Building Project
+      run: |
+        cd $(dirname $(find . -name DragonMake | xargs))
+        dragon b
diff --git a/dragontools/deployable/tests.yml b/src/dragontools/deployable/tests.yml
similarity index 100%
rename from dragontools/deployable/tests.yml
rename to src/dragontools/deployable/tests.yml
diff --git a/dragontools/test.py b/src/dragontools/test.py
similarity index 100%
rename from dragontools/test.py
rename to src/dragontools/test.py