Shell like application using sbt console - scala

I would like to deploy some scala code, to be used very similar to sbt console
(command line interface, history, etc)
and would like to
customize it
and made it simple to deploy.
Can sbt console be used with these changes:
Removed startup info messages
Removed scala welcome message
Customized command prompt instead of "scala>" to be "myApp>"
No access to local nor global ivy/maven repositories (all jars
available, including sbt jars and dependencies)
Anybody passed this path ?
I have tried
Using sbt to build command line application
but with no much progress so far
(I guessed it was intented to very similar situation)
Are there ready made plugin available ?
Any other tool related or unrelated to sbt ?
Thank you

Actully, no need for sbt. To have it tweaked, scala code should be changed.

For the sbt "Customized command prompt" part, you have a good example with "sbt: Customize the Shell prompt in sbt" from Patrick Bailey (patmandenver).
create the ~/.sbt/0.13/global.sbt file:
vi ~/.sbt/0.13/global.sbt
And place the following in it.
shellPrompt := { state =>
def textColor(color: Int) = { s"\033[38;5;${color}m" }
def backgroundColor(color:Int) = { s"\033[48;5;${color}m" }
def reset = { s"\033[0m" }
def formatText(str: String)(txtColor: Int, backColor: Int) = {
s"${textColor(txtColor)}${backgroundColor(backColor)}${str}${reset}"
}
val red = 1
val green = 2
val yellow = 11
val white = 15
val black = 16
val orange = 166
formatText(s"[${name.value}]")(white, orange) +
"\n " +
formatText("\u276f")(green, black) +
formatText("\u276f")(yellow, black) +
formatText("\u276f ")(red, black)
}
Run reload in sbt and….
That can be amended/enhanced/completed to add other information you would need in your case.

Related

Integrate µTest (micro test) for Scala into a Gradle project

I'm using Gradle for my Scala projects and a bit frustrated about documentation of scalatest. So I searched for a alternative test framework. The only one I found was µTest (micro test). But so far I could not found a way to integrate µTest into Gradle.
After time of investigation I found a solution. If I have a sample test:
import utest._
object SampleTests extends TestSuite {
val tests:Tests = Tests {
var x = 0
'outer1 - {
x += 1
'inner1 - {
x += 2
assert(x == 3) // 0 + 1 + 2
x
}
'inner2 - {
x += 3
assert(x == 4) // 0 + 1 + 3
x
}
}
'outer2 - {
x += 4
'inner3 - {
x += 5
assert(x == 9) // 0 + 4 + 5
x
}
}
}
def main(args: Array[String]): Unit = {
val results = TestRunner.runAndPrint(SampleTests.tests, "SampleTests")
}
}
Importent is that there is a main funtion which calls a method of the TestRunner with a parameter of type Tests. This parameter can be a value or a method defined with def.
Furthermore the test code should be inside test source location (test instead of main).
For triggering this code you need to modify the build.gradle file. There you can insert a user defined task like this:
task microTest(type: JavaExec) {
main = 'package.SampleTests'
classpath = sourceSets.test.runtimeClasspath
}
Of course you need to declare the dependency inside build.gradle to the test framework:
testImplementation "com.lihaoyi:utest_2.a:x.y.z"
Fazit:
There is a way to trigger the tests with
./gradlew microTest
or click with the mouse inside your IDE at the listed gradle task. The output of the test framework micro test will be printed to the console in the expected way. But when you call this task indirectly by defining the following line inside build.gradle:
test.finalizedBy microTest
with click at the test task in the IDE (Intellij), then the colored output is replaced by special characters.
When not clicking (entering the command line: ./gradlew test) all output is printed correctly.

How can I print all the settings in Test configuration for a project build using SBT?

I have a scala-js project, adding a particular library dependency, is affecting the way project test cases are running. Without the library dependency everything's fine, the moment I add them, tests doesn't execute. I want to check all sbt settings, if those are getting affected. Is there any way I can print all settings and check?
BuildStructure.data seems to give access to all the settings by scope. We could access it by defining a custom command printAllTestSettings like so:
def printAllTestSettings = Command.command("printAllTestSettings") { state =>
val structure = Project.extract(state).structure
val testScope =
Scope(
Select(ProjectRef(new File("/home/mario/sandbox/hello-world-scala/"), "root")),
Select(ConfigKey("test")),
Zero,
Zero
)
structure
.data
.keys(testScope)
.foreach(key => println(s"${key.label} = ${structure.data.get(testScope, key).get}"))
state
}
commands ++= Seq(printAllTestSettings)
Here is output snippet:
...
managedSourceDirectories = List(/home/mario/sandbox/hello-world-scala/target/scala-2.12/src_managed/test)
managedResourceDirectories = List(/home/mario/sandbox/hello-world-scala/target/scala-2.12/resource_managed/test)
testLoader = Task((taskDefinitionKey: ScopedKey(Scope(Select(ProjectRef(file:/home/mario/sandbox/hello-world-scala/,root)), Select(ConfigKey(test)), Zero, Zero),testLoader)))
packageBin = Task((taskDefinitionKey: ScopedKey(Scope(Select(ProjectRef(file:/home/mario/sandbox/hello-world-scala/,root)), Select(ConfigKey(test)), Zero, Zero),packageBin)))
...

Remove or Exclude WatchSource in sbt 1.0.x

Overview
After looking around the internet for a while, I have not found a good way to omit certain folders from being watched by sbt 1.0.x in a Play Framework application.
Solutions posted for older versions of sbt:
How to exclude a folder from compilation
How to not watch a file for changes in Play Framework
There are a few more, but all more or less the same.
And the release notes for 1.0.2 show that the += and ++= behavior was maintained, but everything else was dropped.
https://www.scala-sbt.org/1.x/docs/sbt-1.0-Release-Notes.html
Source code verifies: https://www.scala-sbt.org/1.0.4/api/sbt/Watched$.html
Would love to see if anyone using sbt 1.0.x has found a solution or workaround to this issue. Thanks!
Taking the approach of how SBT excludes managedSources from watchSources I was able to omit a custom folder from being watched like so:
watchSources := {
val directoryToExclude = "/Users/mgalic/sandbox/scala/scala-seed-project/src/main/scala/dirToExclude"
val filesToExclude = (new File(directoryToExclude) ** "*.scala").get.toSet
val customSourcesFilter = new FileFilter {
override def accept(pathname: File): Boolean = filesToExclude.contains(pathname)
override def toString = s"CustomSourcesFilter($filesToExclude)"
}
watchSources.value.map { source =>
new Source(
source.base,
source.includeFilter,
source.excludeFilter || customSourcesFilter,
source.recursive
)
}
},
Here we use PathFinder to get all the *.scala sources from directoryToExclude:
val filesToExclude = (new File(directoryToExclude) ** "*.scala").get.toSet
Then we create customSourcesFilter using filesToExclude, which we then add to every current WatchSource:
watchSources.value.map { source =>
new Source(
...
source.excludeFilter || customSourcesFilter,
...
)
}
Note the above solution is just something that worked for me, that is, I do not know what is the recommend approach of solving this problem.

Strange issue with SBT, println, and scala console application

When I run my scala code (I'm using SBT), the prompt is displayed after I enter some text as shown here:
C:\... > sbt run
[info] Loading project definition [...]
[info] Set current project to [...]
Running com[...]
test
>>
exit
>> >> >> >> >> >> [success] Total time[...]
It seems like it's stacking up the print() statements and only displaying them when it runs a different command.
If I use println() it works as it should (except that I don't want a newline)
The code:
...
def main(args:Array[String]) {
var endSession:Boolean = false
var cmd = ""
def acceptInput:Any = {
print(">> ")
cmd = Console.readLine
if (cmd != "exit") {
if (cmd != "") runCommand(cmd)
acceptInput
}
}
acceptInput
}
...
What's going on here?
Output from print (and println) can be buffered. Scala sends output through java.io.PrintStream, which suggests that it will only auto-flush on newline, and then only if you ask. It might be OS dependent, though, since my print appears immediately.
If you add Console.out.flush after each print, you'll empty out the buffer to the screen (on any OS).

Jython Build has no Output

Hey, I've been playing around with Jython a bit and I wrote the following test program:
from javax.swing import *
from java.awt import *
from java.awt.event import ActionListener
class JythonTest(JFrame):
_windowTitle = ""
def __init__(self):
self.initVars()
self.initLookAndFeel()
self.initComponents()
self.initGui()
def initVars(self):
self._windowTitle = "Jython Test"
JFrame.__init__(self, self._windowTitle)
def initLookAndFeel(self):
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName())
def initComponents(self):
label = JLabel("Hello World!", JLabel.CENTER)
label.setFont(Font("Arial", Font.BOLD, 30))
tabs = JTabbedPane()
tabs.addTab("Test", label)
tabs.addTab("Calculator", self.CalculatorPane())
self.add(tabs)
def initGui(self):
self.setSize(400,200)
self.setDefaultCloseOperation(self.EXIT_ON_CLOSE)
self.setVisible(1)
class CalculatorPane(JPanel, ActionListener):
_txt1 = 0
_txt2 = 0
_box = 0
def __init__(self):
self.initVars()
self.initComponents()
def initVars(self):
pass
def initComponents(self):
self._txt1 = JTextField(5)
self._box = JComboBox(["+", "-", "*", "/"])
self._txt2 = JTextField(5)
btn = JButton("Go")
btn.addActionListener(self)
self.add(self._txt1)
self.add(self._box)
self.add(self._txt2)
self.add(btn)
def actionPerformed(self, ev):
val1 = self._txt1.getText()
val2 = self._txt2.getText()
operation = self._box.getSelectedItem()
val1 = int(val1)
val2 = int(val2)
if operation == "+":
answer = val1+val2
elif operation == "-":
answer = val1-val2
elif operation == "*":
answer = val1*val2
elif operation == "/":
answer = val1/val2
JOptionPane.showMessageDialog(self, "The answer is: " + str(answer))
if __name__ == "__main__":
win = JythonTest()
Here's my system info:
Operating System: Ubuntun 10.10
Netbeans Version: 6.9
My problem is that I can't compile the above code. It runs just fine when I click the run button, however, when I hit build or clean & build then I don't get any results. The build process runs in the bottom right corner for about half a second and then finishes. The output box opens up but it's entirely empty, even after the process ends. When I look at my project folder, nothing changes. Only two folders exist, nbproject and src. There probably should be a dist folder with a jar inside of it. Here's what's in the file structure:
user#computer: ~/NetBeansProjects/pythontest$ ls
nbproject src
user#computer: ~/NetBeansProjects/pythontest$ ls nbproject
private project.properties project.xml
user#computer: ~/NetBeansProjects/pythontest$ ls nbproject/private
private.xml
user#computer: ~/NetBeansProjects/pythontest$ ls src
pythontest.py setup.py
All I did to set up was install netbeans from the debian package (quite a while ago) and set up python/jython through the NetBeans python plugin. Any idea what's wrong?
The short answer is that it doesn't really work like that; I'm not aware of any IDE or tool support for packaging jython programs.
Usually what I do is just make a shell script that says:
java -cp "the/classpath/;" org.python.util.jython myscript.py
I've found that is the most foolproof way to run a jython program, and has saved me many headaches from not-working .jar files during development.
That said, there are methods of packaging jython programs in standalone .jar files, if that's what you want.
The best resource that I've found is the Distributing Jython Scripts page in the Jython FAQ, which describes a few different techniques for distributing jython scripts.
I usually only use the methods described there when "publishing" a program.