Skip to content

Instantly share code, notes, and snippets.

@andy0130tw
Last active November 8, 2015 06:32
Show Gist options
  • Save andy0130tw/ac1f686285e4fa20eadc to your computer and use it in GitHub Desktop.
Save andy0130tw/ac1f686285e4fa20eadc to your computer and use it in GitHub Desktop.
BIMEHW - single-file batch compiler in Visual Studio + Template for both g++ and MSVC
#!/usr/bin/env python3
from sys import argv
from os import listdir
from os import remove
from os.path import join
from os.path import isfile
import subprocess
from subprocess import PIPE
import re
from time import time
from time import gmtime
from time import strftime
from shutil import copyfile
from shutil import move
from colorama import init as coloramaINIT
from colorama import Fore
from colorama import Style
SOLUTION_NAME = 'bime-hw'
MSBUILD_PATH = 'C:\\Program Files (x86)\\MSBuild\\12.0\\Bin\\MSBuild.exe'
MSBUILD_FLAG = ';'.join(['/p:Configuration=Release'])
TARGET_FILENAME = '{}.cpp'.format(SOLUTION_NAME)
EXECUTABLE_FILENAME = '{}.exe'.format(SOLUTION_NAME)
TARGET_PATH = join(SOLUTION_NAME, TARGET_FILENAME)
FOLDER_REPO = 'code'
FOLDER_DIST = 'dist'
coloramaINIT()
current_time = lambda: strftime("%Y-%m-%d %H:%M:%S", gmtime())
def writeOutput(f, o):
''' workaround of UnicodeDecodeError '''
# ensure all data is written to file
f.flush()
ff = open(f.name, 'ab')
ff.write(o)
ff.close()
# TODO: process each file in folder 'code'
# for each: copy it, compile it, and then copy back the code with the execuable
# into another folder called dist
# record stdout; dump it only if build fails
# check the return code
# and then create an archive
def main():
logfile = open('vs-compile.log', 'a')
print('Batch compilation started')
logfile.write('Batch compilation started at {}. -------------------\n'.format(current_time()))
for fname in listdir(FOLDER_REPO):
print('Compiling \033[94m{}\033[0m... '.format(fname), end='')
logfile.write('{}: '.format(fname))
exename = re.sub(r'(.+)\.cpp', r'\1.exe', fname)
try:
if isfile(TARGET_PATH):
# TODO: back it up and go normally
raise BaseException('Target already exists!')
ts = time()
copyfile(join(FOLDER_REPO, fname), TARGET_PATH)
log = subprocess.check_output([MSBUILD_PATH, MSBUILD_FLAG])
print('\033[92mSUCCESS! ({}ms)\033[0m'.format(time() - ts))
logfile.write('SUCCESS ({}ms)\n'.format(time() - ts))
# writeOutput(logfile, log)
move(TARGET_PATH, join(FOLDER_DIST, fname))
move(join('Release', EXECUTABLE_FILENAME), join(FOLDER_DIST, exename))
except subprocess.CalledProcessError as e:
print('\033[91mFAILURE\033[0m')
logfile.write('FAILURE\n')
writeOutput(logfile, e.output)
logfile.write('\n')
# try outputting error message
err_start = 0
while(1):
err_start = e.output.find(b' ' + TARGET_FILENAME.encode() + b'(', err_start)
err_end = e.output.find(b'\n', err_start+1)
if not e.output[err_start:err_end]:
break
print(e.output[err_start:err_end].decode('utf8'))
err_start = err_end
# clean up
remove(TARGET_PATH)
except BaseException as e:
logfile.write('ABORTED\nAborted due to an internal error: ')
logfile.write(e.__str__())
logfile.write('\n\n')
print('\033[91mABORTED\033[0m')
raise
print('Batch compilation ended')
logfile.write('Batch compilation ended at {}. -------------------\n'.format(current_time()))
if __name__ == '__main__':
if len(argv) > 1:
if argv[1] == 'clean':
print('Cleaning target...')
try:
remove(TARGET_PATH)
print('removed {}'.format(TARGET_FILENAME))
exename = join('Release', EXECUTABLE_FILENAME)
remove(exename)
print('removed {}'.format(exename))
except:
print('error... not removed')
elif argv[1] == 'distclean':
print('Cleaning dist...')
for rmname in listdir(FOLDER_DIST):
remove(join(FOLDER_DIST, rmname))
print('removed {}'.format(rmname))
else:
print('''Usage:
[without argument]: batch compilation
clean: delete current file placed in the project.
distclean: delete all sources and execuables in dist folder.
A log file is appended into vs-compile.log only in batch compilation mode.''')
else:
print('====== BIMEHW batch compilation worker by Andy Pan ======')
main()
@echo off
echo ============== INIT ===============
del vs-compile.log
python batch-compile.py clean
python batch-compile.py distclean
echo ============ [COMPILE] ============
python batch-compile.py
echo.
pause
echo =============== LOG ===============
type vs-compile.log
pause
//================================================================
// PROGRAMMER : 潘廣霖
// DATE : $<1: import datetime; return str(datetime.date.today())>
// FILENAME : $(2: echo $GEDIT_CURRENT_DOCUMENT_NAME | tr a-z A-Z)
// DESCRIPTION : ${3}
//================================================================
#ifdef _MSC_VER
#include "stdafx.h"
#endif // _MSC_VER
#include<iostream>
#include<cstdlib>
using namespace std;
#ifdef _MSC_VER
int main(int argc, _TCHAR* argv[]) {
#else
int main() {
#endif // _MSC_VER
$0
}
// edited in gedit
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment