Sublime Forum

[TEMPLATE] Multi-Command Builds with Input (PowerShell Script)

#1

#INTRO:

 
I’ve seen a few threads about capturing input in builds recently, so I decided to put together an easy way to manage builds from a central location.

The script requires a Windows PC with PowerShell.
( tested with: PowerShell: v5.0, build 10586, rev 122 )

 
Benefits of PowerShell & This Script:

  • chain multiple commands
  • run parallel builds
  • SublimeBuild for output only and/or debugging
  • PowerShell for input
  • both builds are independent & can receive different commands
  • define all of your build commands in one file
  • sublime-build files follow a simple template
  • strong system integration
  • customizable visual style
  • select & copy text
  • syntax is easier to work with than batch files

Script @ GitHub

 



#DEMO:

@ Java

@ Python

 



#INFO:

 
There are 3 main sections in the script:

  • USER SETTINGS
  • FUNCTIONS
  • SCRIPT

 
USER SETTINGS is the only part of the script that needs to be modified.

It has 2 sub-sections:

Variables

  • default PowerShell & SublimeBuild states
  • header options ( file | fileName | fileBase | filePath | projectName )

Build Settings

  • first build to run ( PowerShell or SublimeBuild )
  • commands to be run @ PowerShell
  • commands to be run @ SublimeBuild
  • [optional] disable PowerShell or SublimeBuild
  • [optional] disable headers
     


#EXAMPLES:

@ SublimeText_Builds.ps1/BuildSettings

ElseIf ( $MODE -ieq "Java_Input" )
	{
		$firstBuild = $SUBLIME_BUILD
		$sublimeBuild_Commands += `
			"If ( Test-Path " + $sQuote + $filePathSlash + $fileBase + ".class" + $sQuote + " )" + `
			"{ Remove-Item "  + $sQuote + $filePathSlash + $fileBase + ".class" + $sQuote + " }"
		$sublimeBuild_Commands += "cd " + $sQuote + $filePath + $sQuote
		$sublimeBuild_Commands += "javac -encoding UTF-8 " + $sQuote + $fileName + $sQuote
		$powerShell_Commands += "cd " + $pQuote + $filePath + $pQuote
		$powerShell_Commands += "java " + $fileBase
	}
ElseIf ( $MODE -ieq "Java_NoInput" )
	{
		$firstBuild = $SUBLIME_BUILD
		$sublimeBuild_Commands += `
			"If ( Test-Path " + $sQuote + $filePathSlash + $fileBase + ".class" + $sQuote + " )" + `
			"{ Remove-Item "  + $sQuote + $filePathSlash + $fileBase + ".class" + $sQuote + " }"
		$sublimeBuild_Commands += "cd " + $sQuote + $filePath + $sQuote
		$sublimeBuild_Commands += "javac -encoding UTF-8 " + $sQuote + $fileName + $sQuote
		$sublimeBuild_Commands += "java " + $fileBase
		$powerShell_Enabled   = $FALSE
		$bottomHeader_Enabled = $FALSE
	}

@ JavaC.sublime-build

{
	"selector":   "source.java",
	"cmd":        [ "PowerShell", "SublimeText_Builds.ps1", "Java_NoInput", "\"$file\"", "\"$file_name\"", "\"$file_base_name\"", "\"$file_path\"", "\"$project_base_name\"" ],
	"file_regex": "^(...*?):([0-9]*):?([0-9]*)",

	"variants":
		[
			{
				"name": "Input",
				"cmd":  [ "PowerShell", "SublimeText_Builds.ps1", "Java_Input", "\"$file\"", "\"$file_name\"", "\"$file_base_name\"", "\"$file_path\"", "\"$project_base_name\"" ],
			},
		]
}

The sublime-build template only requires 3 updates when creating a new build:

  • selector
  • file_regex
  • the 3rd argument of each "cmd"
  • ( must match @ SublimeText_Builds.ps1/BuildSettings )
2 Likes

Sublime Java
Running Python on sublime console
Sublime user input into console (using scanner class with java and running programs in sublime)
Configuring a build system for python3 (run files as modules)
My first simple python program
[FORUM REQUEST] Resource Category / Pinned Thread Alternative
#2

@fico, what is your gif generation process, out of interest? On Windows, I currently record with Icecream Screen Recorder, and then use a free website http://ezgif.com/video-to-gif to convert it, which is far from ideal…

0 Likes

#3

For a while, I was using ScreenToGIF for GIFs and Icecream Screen Recorder for screencasts.

I just started using ActivePresenter in the last few weeks and… it is BEASTLY.

It is the most efficient editor I’ve used for this type of thing, out of ANYTHING ( including Premiere, After Effects, etc. ).

The best part of it is the slide functionality.   You can record a full screencast, and then break it up very easily into sections.   It also has the best annotation features I’ve seen in this genre of software. ( Check out the last GIF on this thread )

The paid versions also have some pretty crazy features.
( I’m on the free version for now, but it still has huge amounts of functionality )

The only things it’s lacking right now are GIF output & individual slide output.
My workaround is to export video, and run it through the ScreenToGIF editor.
 



 
If I need to export multiple slides, I have two ways of doing it.   Both are kind of a pain in the ass.

  • A GIF splitting script I wrote for Processing with the gifAnimation library.   It’s super slow & requires manual split points to be entered.
  • Save the ActivePresenter file for as many slides as there are, delete all slides leaving a single unique slide in each file, export each file to a video, and run each video through SplitToGIF.

Neither is ideal, but it still beats anything else that’s available.   Plus it’s still super quick if you’re just working with one GIF at a time.

I’m going to write a blog post demoing their software, targeted towards developers.   The subject will be how to create useful, informative posts on forums & communities like SO.   Hopefully I can sway them to add the missing features I mentioned earlier, considering that the online dev community is pretty huge & their software is pretty much the best way for devs to communicate graphically.

2 Likes

#4

Wow, that is neat! Thanks for the comprehensive info!

I look forward to the aforementioned blog post, and hope it will indeed sway the devs to add GIF output and individual slide output :thumbsup:

1 Like

#5

FYI, for the aspect of input, I think Console Exec is more ideal than your script.

  • easier to use (add "target": "console_exec" to an existing build setting and that’s all)
  • cross-platform (Win/Linux, not for Mac)

Although, the screenshot in the readme of Console Exec looks pretty lame and it does not mention it resolves the input problem which most people care about.

0 Likes

#6

 
Thanks for the tip, I had actually checked out Console Exec before putting this together.   Your solution is great for basic input & much more user friendly, but I was also looking for a few extra features in my build process.

 

I shared it in case anyone else happens to get use from it, but the main reasons I created it for my personal use are:

  • To manage a single workspace for all of my builds

  • To bypass the limitations of inline JSON definitions, giving me the ability to include variables and functions for more complex build solutions & future extensibility

  • Powershell has more powerful system integration than cmd.   It’s also a lot easier on the eyes since it can be styled, and it allows you to select specific text from the results.

1 Like

#7

could u add support for c? (using clang) so it opens and puts the output in a cygwin terminal :d

0 Likes

#8

 

##See:
##[TEMPLATE] Dynamic Builds with External CLI (Python Script)

 
That method is way cleaner & way easier to use, so you can probably just swap out a few lines to make it work for you.

0 Likes

#9

{
“shell_cmd” : “clang-3.8.exe -o “$file_base_name” “${file_name}” && “./${file_base_name}””,
“selector” : “source.c”,
“path” : “C:\cygwin64\bin;$path”,
“working_dir” : “$file_path”
}

I genuinely have no idea… thats what im currently using

0 Likes

#10

 
Idk man, haven’t worked with C or Clang.

You basically just need to figure out the command/argument formats that cygwin and clang use, and then manipulate the strings passed from SublimeText into those formats.

 

For PowerShell, I had to figure out a way to allow quoted commands in case the filepath contained spaces. The solution was to prefix the initial command with & followed by a space. For your system, it might work right away, or you can figure out the proper syntax, or you can just ditch the quotes if your cygwin path doesn’t contain spaces.

I also had to pass the -NoExit arg to keep the PowerShell window open, so you might need to figure out something similar for cygwin.

 

Here’s my best attempt not having really worked with your toolset, you might need to play around with what’s quoted and what’s not and maybe some other formatting.

@ Packages/BuildSystems/Clang_BuildSystem.py

import sublime, sublime_plugin
import subprocess

class clang_build_system_command(sublime_plugin.WindowCommand):
	def run(self, cmd=[], file_regex=""):

		filePath, fileName, fileBase, fileDirectory, projectName = cmd
		quoted_FilePath = quote(filePath)

		cygwin_EXE = quote("C:\\PATH\\TO\\cygwin.exe")
		__ = ";" # Cygwin Command Separator

		command__SetWorkingDirectory = "cd " + quote(filePath)
		
		clang_EXE  = quote("C:\\PATH\\TO\\clang-3.8.exe")
		arg__Output = "-o "
		command__BuildWithClang = clang_EXE + " " + arg__Output + quote(fileBase) + " " + quote(fileName) + " && " + quote("./$" + fileBase)

		commands = [
			cygwin_EXE,
			__, command__SetWorkingDirectory,
			__, command__BuildWithClang,
		]

		subprocess.Popen(commands)


def quote(text):
	text = '"' + text + '"'
	return(text)

 

@ Packages/BuildSystems/Clang.sublime-build

{
	"selector":   "source.c, source.c++",
	"target":     "clang_build_system",
	"file_regex": "^(..[^:]*):([0-9]+):?([0-9]+)?:? (.*)$",
	"cmd":        ["$file", "$file_name", "$file_base_name", "$file_path", "$project_base_name"],
}
0 Likes

#11

I mean, even if you did it in PowerShell I wouldn’t mind as long as it worked… but I tried the above and ctrl b had no effect whatsoever.

Also I believe both fields should be in the C file not BuildSystems. Since they didn’t appear as Builds until I moved them to the @Packages/C

0 Likes