Skip to content

Commit f267ae1

Browse files
authored
Merge pull request #504 from adriaanm/chaselal-update-hacker-guide
update hacker guide
2 parents a266087 + b1229dc commit f267ae1

File tree

1 file changed

+43
-86
lines changed

1 file changed

+43
-86
lines changed

Diff for: contribute/hacker-guide.md

+43-86
Original file line numberDiff line numberDiff line change
@@ -100,47 +100,25 @@ If you are new to Git and branching, read the [Branching Chapter](http://git-scm
100100

101101
The next step after cloning your fork is setting up your machine to build Scala.
102102

103-
* It is recommended to use Java `1.6` (not `1.7` or `1.8`, because they might cause occasional glitches).
104-
* The build tool is `ant`. If you are behind a HTTP proxy, include [`ANT_ARGS=-autoproxy`](https://ant.apache.org/manual/proxy.html) in your environment.
105-
* The build runs the `pull-binary-libs.sh` script to download bootstrap libs. This requires `bash` and `curl`.
106-
* The majority of our team works on Linux and OS X, so these operating systems are guaranteed to work.
107-
* Windows is supported, but it might have issues. Please report to [the issue tracker](https://issues.scala-lang.org/) if you encounter any.
103+
You need the following tools:
108104

109-
Building Scala is as easy as running `ant` in the root of your cloned repository. Be prepared to wait for a while-- a full "clean" build
110-
takes 8+ minutes depending on your machine (and up to 30 minutes on older machines with less memory). Incremental builds are usually within 30-120 seconds range (again, your mileage might vary
111-
with your hardware).
105+
* A Java SDK. The baseline version is 6 for 2.11.x and 8 for 2.12.x. It's possible to use a later SDK for local development, but the continuous integration builds will verify against the baseline version.
106+
* `sbt`, an interactive build tool commonly used in Scala projects. Acquiring sbt manually is not necessary -- the recommended approach is to download the [sbt-extras runner script](https://github.com/paulp/sbt-extras/blob/master/sbt) and use it in place of `sbt`. The script will download and run the correct version of sbt when run from the Scala repository's root directory.
107+
* `curl` -- the build uses `curl` in the `pull-binary-libs.sh` script to download bootstrap libs.
112108

113-
16:50 ~/Projects/scala (ticket/6725)$ ant
114-
Buildfile: /Users/xeno_by/Projects/scala/build.xml
109+
OS X and Linux builds should work. Windows is supported, but it might have issues. Please report to [the issue tracker](https://issues.scala-lang.org/) if you encounter any.
115110

116-
strap.clean:
111+
Building Scala is as easy as running `sbt dist/mkPack` in the root of your cloned repository. In general, it's much more efficient to enter the `sbt` shell once and run the various tasks from there, instead of running each task by launching `sbt some-task` on your command prompt.
117112

118-
pack.clean:
119-
120-
init.jars.check:
121-
122-
init.jars:
123-
[echo] Updating bootstrap libs. (To do this by hand, run ./pull-binary-libs.sh)
124-
[exec] Resolving [943cd5c8802b2a3a64a010efb86ec19bac142e40/lib/ant/ant-contrib.jar]
125-
126-
...
127-
128-
pack.bin:
129-
[mkdir] Created dir: /Users/xeno_by/Projects/scala/build/pack/bin
130-
131-
pack.done:
132-
133-
build:
134-
135-
BUILD SUCCESSFUL
136-
Total time: 9 minutes 41 seconds
113+
Be prepared to wait for a while -- a full "clean" build takes 5+ minutes depending on your machine (longer on older machines with less memory). On a recent laptop, incremental builds usually complete within 10-30 seconds.
137114

138115
### IDE
139116

140117
There's no single editor of choice for working with Scala sources, as there are trade-offs associated with each available tool.
141118

142119
Both Eclipse and IntelliJ IDEA have Scala plugins, which are known to work with our codebase.
143-
Both of those Scala plugins provide navigation, refactoring and error reporting functionality as well as integrated debugging.
120+
Both of those Scala plugins provide navigation, refactoring, error reporting functionality, and integrated debugging.
121+
See [the Scala README](https://github.com/scala/scala#ide-setup) for instructions on using Eclipse and IntelliJ IDEA with the Scala repository.
144122

145123
There also exist lighter-weight editors such as Emacs, Sublime or jEdit which are faster and much less memory/compute-intensive to run, while
146124
lacking semantic services and debugging. To address this shortcoming, they can integrate with ENSIME,
@@ -155,8 +133,8 @@ When hacking on your topic of choice, you'll be modifying Scala, compiling it an
155133
Typically you would want to first make sure that your changes work on a small example and afterwards verify that nothing break
156134
by running a comprehensive test suite.
157135

158-
We'll start by creating a `sandbox` directory (this particular name doesn't bear any special meaning), which will hold a single test file and its compilation results. First, let's make sure that
159-
[the bug](https://issues.scala-lang.org/browse/SI-6725) is indeed reproducible by putting together a simple test and compiling and running it with the Scala compiler that we built using `ant`. The Scala compiler that we just built is located in `build/pack/bin`.
136+
We'll start by creating a `sandbox` directory (`./sandbox is listed in the .gitignore of the Scala repository), which will hold a single test file and its compilation results. First, let's make sure that
137+
[the bug](https://issues.scala-lang.org/browse/SI-6725) is indeed reproducible by putting together a simple test and compiling and running it with the Scala compiler that we built using `sbt`. The Scala compiler that we just built is located in `build/pack/bin`.
160138

161139
17:25 ~/Projects/scala (ticket/6725)$ mkdir sandbox
162140
17:26 ~/Projects/scala (ticket/6725)$ cd sandbox
@@ -177,42 +155,39 @@ Now, implement your bugfix or new feature!
177155

178156
Here are also some tips & tricks that have proven useful in Scala development:
179157

180-
* If after introducing changes or updating your clone, you get `AbstractMethodError` or other linkage exceptions,
181-
try doing `ant clean build`. Due to the way how Scala compiles traits, if a trait changes, then it's sometimes not enough to recompile
182-
just that trait, but it might also be necessary to recompile its users. The `ant` tool is not smart enough to do that, which might lead to
183-
very strange errors. Full-rebuilds fix the problem. Fortunately that's rarely necessary, because full-rebuilds take a lot of time-- the same 8-30 minutes as mentioned above.
184-
* Even on solid state drives packaging Scala distribution (i.e. creating jars from class files) is a non-trivial task. To save time here,
185-
some people in our team do `ant quick.comp` instead of `ant` and then create custom scripts ([here](https://github.com/adriaanm/binfu/blob/master/scafu.sh) are some examples to get you started) to launch Scala from `build/quick/classes`.
158+
* After building your working copy with the `compile` sbt task, there's no need to leave the comfort of your sbt shell to try it out: the REPL is available as the `scala` task, and you can also run the compiler using the `scalac` task. If you prefer to run the REPL outside sbt, you can generate the scripts in `build/quick/bin` using the `dist/mkQuick` task.
159+
* The sbt workflow is also great for debugging, as you can simply create a remote debugging session in your favorite IDE, and then activate the JVM options for the next time you run the `scala` or `scalac` tasks using:
160+
161+
```
162+
> set javaOptions in compiler := List("-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8002")
163+
> scalac test.scala
164+
[info] Running scala.tools.nsc.Main -usejavacp test.scala
165+
Listening for transport dt_socket at address: 8002
166+
```
167+
168+
* Also see [the Scala README](https://github.com/scala/scala#incremental-compilation) for tips on speeding up compile times.
169+
* If after introducing changes or updating your clone, you get `AbstractMethodError` or other linkage exceptions, try the `clean` task and building again.
186170
* Don't underestimate the power of `print`. When starting with Scala, I spent a lot of time in the debugger trying to figure out how
187171
things work. However later I found out that print-based debugging is often more effective than jumping around. While it might be obvious
188172
to some, I'd like to explicitly mention that it's also useful to print stack traces to understand the flow of execution. When working with `Trees`, you might want to use `showRaw` to get the `AST` representation.
189-
* You can publish your newly-built scala version locally to use it from sbt. Here's how:
190-
191-
$ ant publish-local-opt -Dmaven.version.suffix="-test"
192-
$ sbt
193-
[info] Set current project to test (in build file:/Users/georgii/workspace/test/)
194-
> set resolvers += Resolver.mavenLocal
195-
[info] Defining *:resolvers
196-
[info] The new value will be used by *:externalResolvers
197-
[info] Reapplying settings...
198-
[info] Set current project to test (in build file:/Users/georgii/workspace/test/)
199-
> ++2.12.0-test
200-
[info] Setting version to 2.12.0-test
201-
[info] Set current project to test (in build file:/Users/georgii/workspace/test/)
202-
> console
203-
[info] Starting scala interpreter...
204-
[info]
205-
Welcome to Scala version 2.12.0-20140623-155543-8bdacad317 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_51).
206-
Type in expressions to have them evaluated.
207-
Type :help for more information.
208-
209-
scala>
173+
* You can publish your newly-built scala version locally using the `publishLocal` task in sbt.
174+
* It's convenient to enable the following local settings to speed up your workflow (put these in `local.sbt` in your working copy):
175+
```
176+
// skip docs for local publishing
177+
publishArtifact in (Compile, packageDoc) in ThisBuild := false
178+
// set version based on current sha, so that you can easily consume this build from another sbt project
179+
baseVersionSuffix := s"local-${Process("tools/get-scala-commit-sha").lines.head.substring(0, 7)}"
180+
// show more logging during a partest run
181+
testOptions in IntegrationTest in LocalProject("test") ++= Seq(Tests.Argument("--show-log"), Tests.Argument("--show-diff"))
182+
// if incremental compilation is compiling too much (should be fine under sbt 0.13.13)
183+
// antStyle := true
184+
```
210185

211186
* Adding a macro to the `Predef` object is a pretty involved task. Due to bootstrapping, you cannot just throw a macro into it. For this reason, the process is more involved. You might want to follow the way `StringContext.f` itself is added. In short, you need to define your macro under `src/compiler/scala/tools/reflect/` and provide no implementation in `Predef` (`def fn = macro ???`). Now you have to set up the wiring. Add the name of your macro to `src/reflect/scala/reflect/internal/StdNames.scala`, add the needed links to it to `src/reflect/scala/reflect/internal/Definitions.scala`, and finally specify the bindings in `src/compiler/scala/tools/reflect/FastTrack.scala`. [Here's](https://github.com/folone/scala/commit/59536ea833ca16c985339727baed5d70e577b0fe) an example of adding a macro.
212187

213188
### Documentation
214189

215-
There are several areas that one could contribute to-- there is the Scala library, the Scala compiler, and other tools such as Scaladoc. Each area has varying amounts of documentation.
190+
There are several areas that one could contribute to -- there is the Scala library, the Scala compiler, and other tools such as Scaladoc. Each area has varying amounts of documentation.
216191

217192
##### The Scala Library
218193

@@ -263,22 +238,12 @@ but not tokens like `%n`. Looks like an easy fix.
263238
start = idx + 1
264239
}
265240

266-
After applying the fix and running `ant`, our simple test case in `sandbox/Test.scala` started working!
241+
After applying the fix and running `sbt compile`, our simple test case in `sandbox/Test.scala` started working!
267242

268243
18:51 ~/Projects/scala/sandbox (ticket/6725)$ cd ..
269-
18:51 ~/Projects/scala (ticket/6725)$ ant
270-
Buildfile: /Users/xeno_by/Projects/scala/build.xml
271-
272-
...
273-
274-
quick.comp:
275-
[scalacfork] Compiling 1 file to /Users/xeno_by/Projects/scala/build/quick/classes/compiler
276-
[propertyfile] Updating property file: /Users/xeno_by/Projects/scala/build/quick/classes/compiler/compiler.properties
277-
[stopwatch] [quick.comp.timer: 6.588 sec]
278-
244+
18:51 ~/Projects/scala (ticket/6725)$ sbt compile
279245
...
280-
281-
BUILD SUCCESSFUL
246+
[success] Total time: 18 s, completed Jun 6, 2016 9:03:02 PM
282247
Total time: 18 seconds
283248

284249
18:51 ~/Projects/scala (ticket/6725)$ cd sandbox
@@ -332,24 +297,16 @@ Here are some more testing tips:
332297
[mima] }
333298
[mima]
334299

335-
BUILD FAILED
336-
/localhome/jenkins/c/workspace/pr-scala-test/scala/build.xml:1530: The following error occurred while executing this line:
337-
/localhome/jenkins/c/workspace/pr-scala-test/scala/build-ant-macros.xml:791: The following error occurred while executing this line:
338-
/localhome/jenkins/c/workspace/pr-scala-test/scala/build-ant-macros.xml:773: Java returned: 2
339-
340-
Total time: 6 minutes 46 seconds
341-
Build step 'Execute shell' marked build as failure
342-
Archiving artifacts
343-
Notifying upstream projects of job completion
300+
...
344301
Finished: FAILURE
345302

346303
This means your change is backward or forward binary incompatible with the specified version (the check is performed by the [migration manager](https://github.com/typesafehub/migration-manager)). The error message is actually saying what you need to add to `bincompat-backward.whitelist.conf` or `bincompat-forward.whitelist.conf` to make the error go away. If you are getting this on an internal/experimental api, it should be safe to add suggested sections to the config. Otherwise, you might want to target a newer version of scala for this change.
347304

348305
### Verify
349306

350-
Now to make sure that my fix doesn't break anything I need to run the test suite using the `partest` tool we wrote to test Scala.
351-
Read up [the partest guide](partest-guide.html) to learn the details about partest, but in a nutshell you can either
352-
run `ant test` to go through the entire test suite (30+ minutes) or use wildcards to limit the tests to something manageable:
307+
Now to make sure that my fix doesn't break anything I need to run the test suite. The Scala test suite uses [JUnit](http://junit.org/junit4/) and [partest](partest-guide.html), a tool we wrote for testing Scala.
308+
Run `sbt test` and `sbt partest` to run all of the JUnit and partest tests, respectively.
309+
`partest` (not `sbt partest`) also allows you to run a subset of the tests using wildcards:
353310

354311
18:52 ~/Projects/scala/sandbox (ticket/6725)$ cd ../test
355312
18:56 ~/Projects/scala/test (ticket/6725)$ partest files/run/*interpol*

0 commit comments

Comments
 (0)