Jump to content
Ikarus_

[RELEASE] Mini Tool - Server Source Manager

Recommended Posts

I wrote this small tool in python to manage easly the server source in a unique script to run.
The tool is written in Python 2.7 but it should works fine with next version.

Basically, the tool can help you to build/touch/strip without navigate in the differents paths.

The tool can perform:


-Build:
build game/db
build game/db with clean
build game&db  (consecutively)
build game&db with clean


-Touch (which dont' create new file when is used with a wrong name):
perform  Touch of one or more files in game/src (by inserting the names separated with a space)
perform  Touch of one or more files in db/src (by inserting the names separated with a space)

-Strip:
Strip game (by copying it)
Strip db (--same)

Additional features:
- the tool find if a file is edited $val seconds in the future (eg. if you have set a wrong date in your compiler) and it will touch the file automatically.
- the tool is written in procedural python (no OOP) so you should read easly it even if you are not an expert with python.
- You can run more than one commands in sequence by separating them with one of these character : ("&&","&","|"," ",'\t',"-",',') (es. : 1&9 -> build game and strip game)
- the tool can get command-line arguments to perform what you need  (you could take a look under to know the command you can pass)


to-know:
- To run a script in python in the compiler you need to have installed Python  (i recommend python27 which i can guarantee it will works). If you haven't installed python you can do it by using pkg manager (pkg install pyhon27) or ports (cd /usr/ports/lang/python27 && make config-recursive && make install clean)
- If you get some problem with the script you can post a comment in this thread to know the solution, anyway it should works perfectly with martysama source (most commonly used).
- To run the script you should give 7XX octal permission.
- To run the script you need to go at the same path where is the script and to use "./scriptname.py" to run it.
- If you are creating the scriptfile using notepad++ (or some external editor) is possible to have a problem about the EOL character (you have to set it on "Unix EOL").
- You have way to enable/disable the question "exit?" when the build fail

- To run the script you should put it on "Server" folder, when you can find game, db, common, etc.

For any kind of problems i recommend you to write a comment in this thread (instead of pm) because another user could get same problem and find here the solution.
i hope it would be usefull.

byebye

 

COMMANDLINE ARGUMENTS

Spoiler

--build-game
--build-db
--build-game-clean
--build-db-clean
--build-all
--build-all-clean
--touch-file-gamesrc
--touch-file-dbsrc
--strip-game
--strip-db
--strip-all

 

 

SCRIPT

Spoiler

#!/usr/local/bin/python2.7
import os
import time
import sys

ENABLE_ASK_BEFORE_EXIT = False
ENABLE_AUTOTOUCH = True

def get_revision_filename(file):
	if os.path.isfile("__REVISION__"):
		line = open("__REVISION__","r").readline()
		return file + "_r" + line.strip()

	else:
		return file



def check_last_edit(path):
	def check_last_edit_single_file(file):
		nowtime = time.time()
		lastedit = os.path.getmtime(file)
		if nowtime < lastedit:
			if ENABLE_AUTOTOUCH:
				touch_file("" , file)
				return
			ans = ""
			while ans == "":
				print("file [%s] has modified %s seconds in future. do you want to touch it or to change date?\nchoose:(touch/date/n)"%(file , int(lastedit-nowtime)))
				ans = raw_input().strip()
		 
				if ans == 'n':
					break
		 
				if ans == 'touch':
					touch_file("" , file)
		 
				elif ans == 'date':
					print("enter date (YYYYMMDDHHMM):")
					mydate = raw_input().strip()
			 
					res = os.system("date %s"%mydate)
			 
					if not res in (0,512):
						print("cannot set datetime. try another option.")
						ans = ""
						continue
			 
					nowtime = time.time()
		 
				else:
					print("unknown answer [%s]"%ans)
					ans = ""

	#end of single file
	if path[-4:] != '/src' and path[-4:] != '\\src':
		path += "/src"

	common = "common"

	files = [path+"/"+file for file in os.listdir(path) if os.path.isfile(path+"/"+file)]
	files += [common+"/"+file for file in os.listdir(common) if os.path.isfile(common+"/"+file)]



	for file in files:
		check_last_edit_single_file(file)


def ask_if_exit():
	if not ENABLE_ASK_BEFORE_EXIT:
		print("exit!")
		sys.exit()


	print("do you want to stop the script operations?y/n\n")

	ans = ""
	while ans == "":
		ans = raw_input().strip()
		if ans == 'y':
			sys.exit()
			return
 
		elif ans == 'n':
			return
 
		else:
			print("unknow answer [%s] , try again"%(ans))
			print("do you want to stop the script operations?y/n\n(press just 'y' or 'n')\n")
			ans = ""


def close():
	print("bye bye")
	sys.exit()

def run_os_command(cmd):
	try:
		res = os.system(cmd)
		if res:
			print("cannot run os command [%s] error %s"%(cmd,str(res)))
			ask_if_exit()
			return False
	except Exception ,e:
		print("an exception during run os command [%s] exception[%s]"%(cmd,str(e)))
		ask_if_exit()
		return False

	return True

def strip_file(file):
	stripfile = file+"_s"
	sourcefile= get_revision_filename(file)

	if not os.path.isfile(file+"/"+sourcefile):
		print("cannot find source file [%s]"%(file+"/"+sourcefile))
		ans=""
 
		while ans == "":
			print("do you want to build it?y/n")
			ans = raw_input().strip()
			if ans == 'y':
				build_file(file)
				strip_file(file)
				return
	 
			if ans == 'n':
				return
	 
			else:
				print("unknown answer [%s] try again."%ans)
				ans = ""
		return

	if os.path.isfile("%s/%s"%(file,stripfile)):
		os.remove("%s/%s"%(file,stripfile))

	if not run_os_command("cp %s/%s %s/%s"%(file,sourcefile, file , stripfile)):
		return

	run_os_command("strip -s %s/%s"%(file,stripfile))

def strip_db():
	strip_file("db")

def strip_game():
	strip_file("game")

def strip_all():
	strip_db()
	strip_game()

def touch_file(dir , files = ""):
	if len(dir)>0 and dir[-1] != '\\' and dir[-1] != '/':
		dir += "/"

	if files != "":
		files = files.split(" ")
		for file in files:
			if not os.path.isfile(dir+file):
				print("cannot find the file required [%s]."%file)
				continue
	 
			else:
				if not run_os_command("touch %s"%(dir + file)):
					print("cannot find the file required [%s]."%file)
					continue
		 
				else:
					print("touched %s"%file)
	else:
		print("the path [%s] will automatically added to the file path\nyou can use a space to separate the names to touch more one file"%(dir))
		ans = ""
		while ans == "":
			print("enter the names of the files (exit to exit):")
			ans = raw_input().strip()
	 
			if ans == 'exit':
				print("You didn't touch any file.")
				ask_if_exit()
				return
	 
			files = ans.split(' ')
	 
			for file in files:
				if not os.path.isfile(dir+file):
					print("cannot find the file required [%s]."%file)
					if len(files) == 1:
						ans = ""
					continue
		 
				else:
					if not run_os_command("touch %s"%(dir + file)):
						print("cannot find the file required [%s]."%file)
						if len(files) == 1:
							ans = ""
						continue
			 
					else:
						print("touched %s"%file)


def touch_in_db_src():
	touch_file("db/src")

def touch_in_game_src():
	touch_file("game/src")



def build_all():
	build_game()
	build_db()

def build_all_clean():
	build_game_clean()
	build_db_clean()


def build_file(file):
	check_last_edit(file)
	cmd = "cd %s/src && gmake && cd ../../"%file
	if not run_os_command(cmd):
		return

	output=get_revision_filename("%s/%s"%(file,file))
	if os.path.isfile(output):
		print("build %s successful."%output)

	else:
		print("cannot build file %s."%output)
		ask_if_exit()


def build_game():
	build_file("game")

def build_db():
	build_file("db")


def clean_build(file):
	return run_os_command("cd %s/src && gmake clean && cd ../../"%file) == True


def build_clean(file):
	if not clean_build(file):
		ask_if_exit()

	else:
		print("%s cleaned"%file)

	build_file(file)


def build_db_clean():
	build_clean("db")


def build_game_clean():
	build_clean("game")



EVENTS = {
	1: {
		"name" : "BUILD GAME",
		"event": build_game,
		"cmd" : "--build-game",
	},

	2: {
		"name" : "BUILD DB",
		"event": build_db,
		"cmd" : "--build-db",
	},

	3: {
		"name" : "BUILD GAME CLEAN",
		"event": build_game_clean,
		"cmd" : "--build-game-clean",
	},

	4: {
		"name" : "BUILD DB CLEAN",
		"event": build_db_clean,
		"cmd" : "--build-db-clean",
	},

	5:{
		"name" : "BUILD ALL",
		"event": build_all,
		"cmd" : "--build-all",
	},

	6: {
		"name" : "BUILD ALL CLEAN",
		"event": build_all_clean,
		"cmd" : "--build-all-clean",
	},

	7: {
		"name" : "TOUCH FILE IN game/src",
		"event": touch_in_game_src,
		"cmd" : "--touch-file-gamesrc",
	},

	8: {
		"name" : "TOUCH FILE db/src",
		"event": touch_in_db_src,
		"cmd" : "--touch-file-dbsrc",
	},

	9:{
		"name" : "STRIP GAME",
		"event": strip_game,
		"cmd" : "--strip-game",
	},

	10:{
		"name" : "STRIP DB",
		"event": strip_db,
		"cmd" : "--strip-db",
	},

	11:{
		"name" : "STRIP ALL",
		"event": strip_all,
		"cmd" : "--strip-all",
	},

	0:{
		"name" : "CLOSE",
		"event": close,
		"cmd" : "--close",
	},
}



def print_commandlist():
	print("What do you want to do?\n")
	toprint = [ (EVENTS[key]["name"],str(key)) for key in EVENTS]

	for thing in toprint: print("%s.\t%s"%(thing[1],thing[0]))


def do_cmd(cmd):
	key = int(cmd)
	if not key in EVENTS:
		print("Unknown command [%d] (ignored)\n")
		return

	print("executing [%s]..."%(EVENTS[key]["name"]))
	event = EVENTS[key]["event"]
	event()


def is_right_ans(ans):
	andchar = ("&&","&","|"," ",'\t',"-",',')
	return len([char for char in ans if not char in andchar and not char.isdigit()]) == 0



def do_commands(cmdstr):
	andchar = ("&&","&","|"," ",'\t',"-",',')
	cmdlist = [cmdstr]
	tmp = []

	for char in andchar:
		for cmd in cmdlist:
			tmp = list(cmdlist)
			cmdlist = []
	 
			for part in tmp:
				cmdlist+= part.split(char)

	wrong = [cmd for cmd in cmdlist if not cmd.isdigit()]
	if len(wrong) != 0:
		print("found wrong command/commands [%s] (ignored)."%str(wrong))

	for cmd in cmdlist:
		if cmd in wrong:
			continue
 
		do_cmd(cmd)

def main():
	if len(sys.argv) > 1:
		cmdargs = [ (EVENTS[key]["cmd"] , key) for key in EVENTS]
	 
		listofargs = [value["cmd"] for value in EVENTS.values()]
		wrongargs = [arg for arg in sys.argv if not arg in listofargs and arg != sys.argv[0]]
	 
		if len(wrongargs) != 0:
			print("wrong args [%s] ignored."%(str(wrongargs)))
	 
	 
		for cmdarg in cmdargs:
			if cmdarg[0] in sys.argv and not cmdarg[0] in wrongargs:
				do_cmd(cmdarg[1])
	 
		return
 
 
 
	print_commandlist()

	ans = ""
	while ans == "":
		ans = raw_input().strip()
		if not is_right_ans(ans):
			print("wrong input command.")
			print_commandlist()
			ans = ""
 
	do_commands(ans)





if __name__ == "__main__":
	main()

 

 

  • Love 13

Share this post


Link to post

Sometimes i reply, not because i want to be unpleasent, but because i see too much wasted time on things that shouldnt have time spent on.

 

Add this to your makefile before all the makes to touch the files:

 

@find . -type f | xargs -n 5 touch

imagem.png

 

 

 

To make commands to build / strip etc without going to folder or even running your python script, just add commands to your sbin.

 

For example a sbin command "rebuild"  with the content of:

cd /your/location && gmake rebuild -j

 

So that everytime you run your "rebuild" command at ANY location, it will do the action above.

 

In my opinion the time you spent making such a tool is not worth the outcome.

Sometimes is better just to use the default tools and dont complicate.

 

Dont take this as a trolling or insult, is just to give you my advise to spend time on other stuff that deserve it, after all time is finite and should be well spent.

Edited by tierrilopes (see edit history)
  • Love 2

Share this post


Link to post

I don't know if you have a service or if you often work on other people's computers, however believe me, they are all always doing gmake all which is a waste of time.
I simply use this panel because I just have to copy it to the machine and I'm done, and having to do it to all the customers I have (which is a nice amount fortunately) I save a lot of time with a simple copy paste.
I published it just because it is noob proof and anyone copying by pasting the file in its server folder has everything ready.
The version that I use has many other tools that are useful to me that I have many other libraries and folders to compile .. What I published is the piece that affects the common command to use in the common files.

 

I also specify that my "build all" command does not compile everything, only game and db, same as build all clean which compiles only game and db giving clean. it is rather rare to modify the other libraries and therefore to recompile them every time does not make much sense.

Anyway thanks for your opinion and your suggestions.

Edited by Ikarus_ (see edit history)

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...

Important Information

Terms of Use / Privacy Policy / Guidelines / We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.