├── .gitignore
├── README.md
├── build.sbt
└── src
└── main
├── resources
├── build.xml
└── nbproject
│ ├── build-impl.xml
│ ├── genfiles.properties
│ ├── private
│ ├── config.properties
│ ├── private.properties
│ └── private.xml
│ ├── project.properties
│ └── project.xml
└── scala
└── netbeans
├── NetbeansCommands.scala
├── NetbeansPlugin.scala
├── NetbeansTasks.scala
└── project
├── AntScript.scala
├── NetbeansConfigFile.scala
├── ProjectConfiguration.scala
├── ProjectContext.scala
└── ProjectProperties.scala
/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 | /build.xml
3 | /lib
4 | /manifest.mf
5 | /nbproject
6 | /project
7 | /target
8 |
9 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | **sbt-netbeans-plugin** is a plugin for simple-build-tool that allows working with SBT projects in Netbeans IDE.
2 |
3 | ### Installing the plugin
4 |
5 | You can either add sources of the plugin to `~/.sbt/plugins` or add a managed dependency to the plugin artifact (in the both cases, plugin will be globally available):
6 |
7 | $ cd ~/.sbt/plugins/
8 | $ xsbt
9 | > set resolvers += ScalaToolsSnapshots
10 | > set resolvers += "remeniuk repo" at "http://remeniuk.github.com/maven"
11 | > set libraryDependencies += "org.netbeans" %% "sbt-netbeans-plugin" % "0.1.4"
12 | > update
13 | > session save
14 | > exit
15 |
16 | Version `0.1.4` is compatible with `Scala 2.9.1` and `SBT 0.11.1`.
17 |
18 | ### Older versions of the plugin
19 |
20 | Older versions of the plugin are available here: http://remeniuk.github.com/maven/org/netbeans/
21 |
22 | ### Building from source
23 |
24 | Clone **sbt-netbeans-plugin**:
25 |
26 | $ git clone -n git://github.com/remeniuk/sbt-netbeans-plugin.git
27 | $ cd sbt-netbeans-plugin
28 |
29 | Publish to the local ivy repository:
30 |
31 | $ xsbt publish-local
32 |
33 | ### Using the plugin
34 |
35 | By default, any command is applied only to the current project. If you want to apply it to all the projects it depends on or aggregates, `transitive` command should be added (e.g., `netbeans create transitive` applied to the root project will create Netbeans files not only for the root, but also for all the dependencies, etc.).
36 |
37 | Create Netbeans files:
38 |
39 | > netbeans create
40 |
41 | ,or simply:
42 |
43 | > netbeans
44 |
45 | *Along with the Netbeans project files, `netbeans-update-dependencies` task is added to the project settings. This task is automatically triggered every time `update` is called, and checks, if Netbeans project classpath matches SBT classpath. If classpaths differ, `project.properties` is updated. Therefore, when you add a dependency (either managed or unmanaged), and call `update`, those dependencies are immediately plugged to the project and reflected in the IDE*
46 |
47 | **Now, you can open SBT project in Netbeans!**
48 |
49 | Create an empty source/resource folders:
50 |
51 | > netbeans create source-directories
52 |
53 | Update Netbeans files with SBT project settings:
54 |
55 | > netbeans update all
56 |
57 | ,or:
58 |
59 | > netbeans update
60 |
61 | If you don't want to add `netbeans-update-dependencies` to the project settings, you will have to trigger update of the Netbeans project properties manually. In order to update only those files that contain project classpaths, use the following command:
62 |
63 | > netbeans update dependencies
64 |
65 | Remove Netbeans files:
66 |
67 | > netbeans remove
68 |
69 | ### Settings
70 |
71 | `sbtExecutable (sbt-executable)` - holds the name of SBT executable in your local environment (could be `sbt` on Linux, or `sbt.bat` on Windows). Default value is `sbt`. The setting can be modified through SBT console:
72 |
73 | set sbtExecutable := "xsbt"
74 | sesion save
75 |
76 | ## Credits
77 |
78 | Special thanks for contributed ideas and help with testing to:
79 |
80 | * Andrew Gaydenko
81 | * Ali Mukadam
82 |
--------------------------------------------------------------------------------
/build.sbt:
--------------------------------------------------------------------------------
1 | organization := "org.netbeans"
2 |
3 | name := "sbt-netbeans-plugin"
4 |
5 | version := "0.1.5"
6 |
7 | sbtPlugin := true
8 |
9 | resolvers ++= Seq(ScalaToolsSnapshots, "Typesafe Repo" at "http://repo.typesafe.com/typesafe")
10 |
11 | libraryDependencies += "org.scalaz" %% "scalaz-core" % "6.0.4"
12 |
13 | publishArtifact in (Compile, packageDoc) := false
14 |
15 | publishMavenStyle := true
16 |
17 | projectID <<= (organization,moduleName,version,artifacts,crossPaths){ (org,module,version,as,crossEnabled) =>
18 | ModuleID(org, module, version).cross(crossEnabled).artifacts(as : _*)
19 | }
20 |
21 | publishTo := Some(Resolver.file("ghrepo", new File("/home/remeniuv/projects/remeniuk.github.com/maven"))(Patterns(true, Resolver.mavenStyleBasePattern)))
22 |
--------------------------------------------------------------------------------
/src/main/resources/build.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Builds, tests, and runs the project sbt-netbeans-plugin.
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 | You must set the main class for the main 'run' task. Change Compile to Test to set it for 'test:run':
41 | mainClass in (Compile, run) := Some({main.class})
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 | Add -Xrunjdwp:transport=dt_socket,address={jpda.address} as an argument
51 | to the SBT (specifying desired `jpda.address`), attach debugger and run the file.
52 |
53 |
54 |
55 |
56 |
57 | Add -Xrunjdwp:transport=dt_socket,address={jpda.address} as an argument
58 | to the SBT (specifying desired `jpda.address`), attach debugger and run the project.
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
--------------------------------------------------------------------------------
/src/main/resources/nbproject/build-impl.xml:
--------------------------------------------------------------------------------
1 |
2 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 | Must set src.dir
148 | Must set test.src.dir
149 | Must set build.dir
150 | Must set dist.dir
151 | Must set build.classes.dir
152 | Must set dist.javadoc.dir
153 | Must set build.test.classes.dir
154 | Must set build.test.results.dir
155 | Must set build.classes.excludes
156 | Must set dist.jar
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 | Must set javac.includes
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 | Must set javac.includes
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 |
263 |
264 |
265 |
266 |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 |
279 |
280 |
281 |
282 |
283 |
284 |
285 |
286 |
287 |
288 |
289 |
290 |
291 |
292 |
293 |
294 |
295 |
296 |
297 |
298 |
299 |
300 |
301 |
302 |
303 |
304 |
305 |
306 |
307 |
308 |
309 |
310 |
311 |
312 |
313 |
314 |
315 |
316 |
317 |
318 |
319 |
320 |
321 |
322 |
323 |
324 |
325 |
326 |
327 |
328 |
329 |
330 |
331 |
332 |
333 |
334 |
335 |
336 |
337 |
338 |
339 |
340 |
341 |
342 |
343 |
344 |
345 |
346 |
347 |
348 |
349 |
350 |
351 |
352 |
353 |
354 |
355 |
356 |
357 |
358 |
359 |
360 |
361 |
362 |
363 |
364 |
365 |
366 |
367 |
368 |
369 |
370 |
371 |
372 |
373 |
374 |
375 |
376 |
377 |
378 |
379 |
380 |
381 |
382 |
383 |
384 |
385 |
386 |
391 |
392 |
393 |
394 |
395 |
396 |
397 |
398 |
399 |
400 |
401 |
402 |
403 |
404 |
405 |
406 |
407 |
408 |
409 |
410 |
411 |
412 |
413 |
414 |
415 |
416 |
417 |
418 |
419 |
420 |
421 | Must select some files in the IDE or set javac.includes
422 |
423 |
424 |
425 |
426 |
427 |
428 |
429 |
430 |
435 |
436 |
437 |
438 |
439 |
440 |
441 |
442 |
443 |
444 |
445 |
446 |
447 |
448 |
449 |
450 |
451 |
452 |
453 |
454 |
455 | To run this application from the command line without Ant, try:
456 |
457 |
458 |
459 |
460 |
461 |
462 | java -cp "${run.classpath.with.dist.jar}" ${main.class}
463 |
464 |
465 |
466 |
467 |
468 |
469 |
470 |
471 |
472 |
473 |
474 |
475 |
476 |
477 |
478 |
479 |
480 |
481 |
482 |
483 |
484 |
485 |
486 | To run this application from the command line without Ant, try:
487 |
488 | java -jar "${dist.jar.resolved}"
489 |
490 |
491 |
492 |
493 |
494 |
495 |
496 |
501 |
502 |
503 |
504 |
505 |
506 |
507 |
508 |
509 |
510 |
511 |
512 | Must select one file in the IDE or set run.class
513 |
514 |
515 |
520 |
521 |
522 |
523 |
524 |
525 |
526 |
527 |
528 |
529 |
530 |
531 |
532 |
533 |
534 |
535 |
536 | Must select one file in the IDE or set debug.class
537 |
538 |
539 |
540 |
541 | Must set fix.includes
542 |
543 |
544 |
545 |
546 |
547 |
548 |
553 |
554 |
555 |
556 |
557 |
558 |
559 |
560 |
561 |
562 |
563 |
564 |
565 |
566 |
567 |
568 |
573 |
574 |
575 |
576 |
577 |
578 |
579 |
580 |
581 |
582 |
583 |
584 |
585 |
586 |
587 |
588 |
589 |
590 |
591 |
592 |
593 |
594 |
595 |
596 |
597 |
598 |
599 | Must select some files in the IDE or set javac.includes
600 |
601 |
602 |
603 |
604 |
605 |
606 |
607 |
608 |
609 |
610 |
611 |
616 |
617 |
618 |
619 |
620 |
621 |
622 |
623 | Some tests failed; see details above.
624 |
625 |
626 |
627 |
628 |
629 |
630 |
631 |
632 | Must select some files in the IDE or set test.includes
633 |
634 |
635 |
636 | Some tests failed; see details above.
637 |
638 |
639 |
644 |
645 | Must select one file in the IDE or set test.class
646 |
647 |
648 |
649 |
650 |
651 |
652 |
653 |
654 |
655 |
656 |
657 |
658 |
659 |
660 |
661 |
662 |
663 |
664 |
665 |
666 |
667 |
668 |
669 |
670 |
675 |
676 | Must select one file in the IDE or set applet.url
677 |
678 |
679 |
680 |
681 |
682 |
683 |
688 |
689 | Must select one file in the IDE or set applet.url
690 |
691 |
692 |
693 |
694 |
695 |
696 |
697 |
702 |
703 |
704 |
705 |
706 |
707 |
708 |
709 |
710 |
711 |
712 |
713 |
714 |
--------------------------------------------------------------------------------
/src/main/resources/nbproject/genfiles.properties:
--------------------------------------------------------------------------------
1 | build.xml.data.CRC32=f84bcc79
2 | build.xml.script.CRC32=bb95f086
3 | build.xml.stylesheet.CRC32=ca9d572e@1.4
4 | # This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
5 | # Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
6 | nbproject/build-impl.xml.data.CRC32=f84bcc79
7 | nbproject/build-impl.xml.script.CRC32=c4e21bf1
8 | nbproject/build-impl.xml.stylesheet.CRC32=5220179f@1.4
9 |
--------------------------------------------------------------------------------
/src/main/resources/nbproject/private/config.properties:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/remeniuk/sbt-netbeans-plugin/582e75817cfea8f49dec3e3d8d06e0592794f3e4/src/main/resources/nbproject/private/config.properties
--------------------------------------------------------------------------------
/src/main/resources/nbproject/private/private.properties:
--------------------------------------------------------------------------------
1 | compile.on.save=false
2 | do.depend=false
3 | do.jar=true
4 | javac.debug=true
5 | javadoc.preview=true
6 |
--------------------------------------------------------------------------------
/src/main/resources/nbproject/private/private.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/src/main/resources/nbproject/project.properties:
--------------------------------------------------------------------------------
1 | application.title=sbt-netbeans-plugin
2 | file.reference.main-scala=
3 | file.reference.test-scala=
4 | dist.dir=target
5 | dist.jar=${dist.dir}\\scala_2.8.1\\sbt-netbeans-plugin_2.8.1-0.1.jar
6 | build.classes.dir=${build.dir}/classes
7 | build.classes.excludes=**/*.java,**/*.form,**/*.scala
8 | # This directory is removed when the project is cleaned:
9 | build.dir=target
10 | build.generated.dir=${build.dir}/generated
11 | # Only compile against the classpath explicitly listed here:
12 | build.sysclasspath=ignore
13 | build.test.classes.dir=${build.dir}/test/classes
14 | build.test.results.dir=${build.dir}/test/results
15 | debug.classpath=\
16 | ${run.classpath}
17 | debug.test.classpath=\
18 | ${run.test.classpath}
19 | # This directory is removed when the project is cleaned:
20 | dist.javadoc.dir=${dist.dir}/scaladoc
21 | includes=**
22 | excludes=**/boot/scala-*/ , **/src_managed/, **/lib_managed/, **/*.lock, **/*.log, **/*.jar, **/*.pom, **/target/, boot/, plugins/project/ , plugins/target/
23 | jar.compress=false
24 | java.platform.active=java_default_platform
25 | # Space-separated list of extra javac options
26 | javac.compilerargs=
27 | javac.deprecation=false
28 | javac.source=1.5
29 | javac.target=1.5
30 | javadoc.additionalparam=
31 | javadoc.author=false
32 | javadoc.encoding=${source.encoding}
33 | javadoc.noindex=false
34 | javadoc.nonavbar=false
35 | javadoc.notree=false
36 | javadoc.private=false
37 | javadoc.splitindex=true
38 | javadoc.use=true
39 | javadoc.version=false
40 | javadoc.windowtitle=
41 | main.class=
42 | manifest.file=manifest.mf
43 | meta.inf.dir=${src.dir}/META-INF
44 | platform.active=default_platform
45 | run.classpath=\
46 | ${javac.classpath}:\
47 | ${build.classes.dir}
48 | # Space-separated list of JVM arguments used when running the project
49 | # (you may also define separate properties like run-sys-prop.name=value instead of -Dname=value
50 | # or test-sys-prop.name=value to set system properties for unit tests):
51 | run.jvmargs=
52 | run.test.classpath=\
53 | ${javac.test.classpath}:\
54 | ${build.test.classes.dir}
55 | # Space-separated list of extra scalac options
56 | scalac.compilerargs=
57 | scalac.deprecation=no
58 | scalac.unchecked=no
59 | source.encoding=UTF-8
60 | src.dir=${file.reference.main-scala}
61 | src.java.dir=${file.reference.main-java}
62 | test.src.dir=${file.reference.test-scala}
63 | resources.dir=
64 | test.resources.dir=
65 | sources.sbt.project=project
--------------------------------------------------------------------------------
/src/main/resources/nbproject/project.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | org.netbeans.modules.scala.project
4 |
5 |
6 | ${application.title}
7 | 1.6.5
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/src/main/scala/netbeans/NetbeansCommands.scala:
--------------------------------------------------------------------------------
1 | /*
2 | * To change this template, choose Tools | Templates
3 | * and open the template in the editor.
4 | */
5 |
6 | package netbeans
7 |
8 | import sbt._
9 | import sbt.complete.DefaultParsers._
10 |
11 | object NetbeansCommands {
12 |
13 | import NetbeansPlugin._
14 | import scalaz._
15 | import Scalaz._
16 |
17 | val create = for{c <- createNetbeansFiles(_);
18 | u <- updateAll(_)} yield c andThen u
19 |
20 | val createSourceDirs = for{c <- createSourceDirectories(_);
21 | u <- updateProjectConfig(_)} yield c andThen u
22 |
23 | /** If `transitive` is used, command is applied to all projects used by
24 | * current project */
25 | val transitive = token(Space ~> ("transitive" ^^^ true)) ?? false
26 |
27 | val createOptions = "create" ~> (token(Space ~> ("source-directories" ^^^ createSourceDirs)) ?? create)
28 |
29 | val updateOptions = "update" ~> (token(Space ~> ("all" ^^^ updateAll _ |
30 | "dependencies" ^^^ updateProjectProperties _)) ?? updateAll _)
31 |
32 | val removeOptions = "remove" ^^^ removeNetbeansFiles _
33 |
34 | val netbeansConsole = Space ~>
35 | (((createOptions | updateOptions | removeOptions) ~ transitive) map {
36 | case (command, transitive) => (command, transitive)
37 | }) ?? (create, true)
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/src/main/scala/netbeans/NetbeansPlugin.scala:
--------------------------------------------------------------------------------
1 | package netbeans
2 |
3 | import sbt._
4 | import Keys._
5 | import project._
6 | import CommandSupport._
7 |
8 | object NetbeansPlugin extends Plugin {
9 |
10 | val sbtExecutable = SettingKey[String]("sbt-executable")
11 |
12 | /** build.xml template under ./sbt/plugins (overrides the template in plugin jar) */
13 | private val buildXmlTemplateLocation = (state: State) => BuildPaths.getGlobalPluginsDirectory(state, BuildPaths.defaultGlobalBase) / "src" / "main" / "resources" / "build.xml"
14 | /** project.properties template under ./sbt/plugins (overrides the template in plugin jar) */
15 | private val projectFilesTemplateLocation = (state: State) => BuildPaths.getGlobalPluginsDirectory(state, BuildPaths.defaultGlobalBase) / "src" / "main" / "resources" / "nbproject"
16 |
17 | /** Extracts Netbeans project files templates from the plugin jar */
18 | private def copyNetbeansFiles(basePath: File)(pluginJarPath: File) =
19 | IO.unzip(pluginJarPath, basePath, "*.xml" | "*.properties")
20 |
21 | /** Copies packed Netbeans project files templates to the project folder */
22 | private def copyPackedTemplates(libClasspath: Seq[File], dest: File) =
23 | libClasspath.filter(_.getName.contains("sbt-netbeans-plugin"))
24 | .headOption.map(copyNetbeansFiles(dest))
25 |
26 | /** Copies Netbeans project files templates from ./sbt/plugins */
27 | private def copyUnpackedTemplates(dest: File, state: State) = {
28 | buildXmlTemplateLocation(state).get.map { template =>
29 | IO.copy(Seq(template.asFile -> (dest / "build.xml").asFile), false)
30 | }
31 | projectFilesTemplateLocation(state).get.map { template =>
32 | IO.copyDirectory(template.asFile, (dest / "nbproject").asFile, false)
33 | }
34 | }
35 |
36 | /** Adds sbt-netbeans commands globally */
37 | override lazy val settings = Seq(commands += netbeansCommands)
38 |
39 | /** Updates Netbeans project files with SBT project settings */
40 | private[netbeans] def updateNetbeansFiles(projectRef: ProjectRef,
41 | s: State,
42 | projectFiles: Seq[ProjectContext => NetbeansConfigFile]): State = {
43 |
44 | import scalaz.Scalaz._
45 |
46 | s.log.info("Updating Netbeans files for project `%s`..." format(projectRef.project))
47 |
48 | ProjectContext.netbeansContext(projectRef, s).map{context =>
49 | projectFiles.map(_(context)).foreach{ projectFile =>
50 | projectFile.validate.fold ({ errors =>
51 | s.log.error("%s: failed to update %s"
52 | .format(projectRef.project, projectFile.description))
53 | }, { _ =>
54 | projectFile.store()
55 | s.log.info("%s: successfully updated %s"
56 | .format(projectRef.project, projectFile.description))
57 | }
58 | )
59 | }
60 | }
61 |
62 | s
63 | }
64 |
65 | /** Updates all Netbeans project files */
66 | private[netbeans] def updateAll(projectRef: ProjectRef)(s: State): State =
67 | updateNetbeansFiles(projectRef, s,
68 | Seq((context => AntScript(context.baseDirectory / "build.xml")(context)),
69 | (context => ProjectConfiguration(context.baseDirectory / "nbproject" /"project.xml")(context)),
70 | (context => ProjectProperties(context.baseDirectory / "nbproject" / "project.properties")(context)))
71 | )
72 |
73 | /** Updates project.properties */
74 | private[netbeans] def updateProjectProperties(projectRef: ProjectRef)(s: State): State =
75 | updateNetbeansFiles(projectRef, s, Seq((context => ProjectProperties(context.baseDirectory / "nbproject" /"project.properties")(context))))
76 |
77 | /** Updates project.xml */
78 | private[netbeans] def updateProjectConfig(projectRef: ProjectRef)(s: State): State =
79 | updateNetbeansFiles(projectRef, s, Seq((context => ProjectConfiguration(context.baseDirectory / "nbproject" /"project.xml")(context))))
80 |
81 | /** Creates empty source/resource directories */
82 | private[netbeans] def createSourceDirectories(projectRef: ProjectRef)(s: State): State = {
83 | ProjectContext.netbeansContext(projectRef, s).map{context =>
84 | s.log.info("Creating empty source directories for project `%s`..." format(projectRef.project))
85 |
86 | IO.createDirectories(Seq(
87 | context.baseDirectory / "src" / "main" / "scala",
88 | context.baseDirectory / "src" / "test" / "scala",
89 | context.baseDirectory / "src" / "main" / "resources",
90 | context.baseDirectory / "src" / "test" / "resources"
91 | ))
92 | }
93 | s
94 | }
95 |
96 | /** Adds Netbeans project files to the SBT project */
97 | private[netbeans] def createNetbeansFiles(projectRef: ProjectRef)(s: State): State = {
98 | val extracted = Project extract s
99 | import extracted._
100 |
101 | s.log.info("Creating Netbeans files for project `%s`" format(projectRef.project))
102 | for{base <- baseDirectory in (projectRef, Compile) get structure.data}{
103 | copyPackedTemplates(currentUnit.unit.plugins.classpath,
104 | base)
105 | copyUnpackedTemplates(base, s)
106 | }
107 |
108 | if(session.original.filter(_.key.key.label == NetbeansTasks.updateDepTaskKey).isEmpty){
109 | s.log.info("Writing plugin settings for project `%s`" format(projectRef.project))
110 | NetbeansTasks.writePluginSettings(projectRef, structure)
111 | s.reload
112 | } else s
113 | }
114 |
115 | /** Removes Netbeans project files from the SBT project */
116 | private[netbeans] def removeNetbeansFiles(projectRef: ProjectRef)(s: State): State = {
117 | val extracted = Project extract s
118 | import extracted._
119 |
120 | s.log.info("Removing Netbeans files from project `%s`" format(projectRef.project))
121 | (baseDirectory in (projectRef, Compile) get structure.data) map { base =>
122 | IO.delete((base / "build.xml" +++ base / "nbproject").get)
123 | }
124 |
125 | s
126 | }
127 |
128 | type NetbeansCommand = ProjectRef => State => State
129 |
130 | lazy val netbeansCommands =
131 | Command("netbeans")(_ => NetbeansCommands.netbeansConsole) { (state: State, output: Any) =>
132 | output match {
133 | case (cmd: NetbeansCommand, transitive: Boolean) =>
134 | val extracted = Project extract state
135 | val s = cmd(extracted.currentRef)(state)
136 | if(transitive){
137 | state.log.info("Executing command transitively...")
138 | (s /: extracted.currentProject.uses) {(_s, _ref) => cmd(_ref)(_s)}
139 | } else s
140 | case other =>
141 | state.log.error("Failed to process command line: " + other)
142 | state.fail
143 | }
144 | }
145 |
146 | }
147 |
--------------------------------------------------------------------------------
/src/main/scala/netbeans/NetbeansTasks.scala:
--------------------------------------------------------------------------------
1 | /*
2 | * To change this template, choose Tools | Templates
3 | * and open the template in the editor.
4 | */
5 |
6 | package netbeans
7 |
8 | import sbt._
9 | import Keys._
10 | import java.nio.charset.Charset
11 | import project._
12 | import CommandSupport._
13 | import NetbeansPlugin._
14 |
15 | object NetbeansTasks {
16 |
17 | val exportedSettings = Seq("seq(netbeans.NetbeansTasks.netbeansSettings:_*)")
18 |
19 | val updateDepTaskKey = "netbeans-update-dependencies"
20 |
21 | val netbeansUpdateDependencies = TaskKey[Any](updateDepTaskKey)
22 |
23 | val netbeansSettings = Seq(
24 | sbtExecutable := "sbt",
25 | netbeansUpdateDependencies <<= updateProjectPropertiesTask triggeredBy(update)
26 | )
27 |
28 | /** Updates project properties, if project classpath has changed */
29 | def updateProjectPropertiesTask = (baseDirectory, fullClasspath in Compile, thisProjectRef, state) map { (base, classpath, projectRef, s) =>
30 | val pluginCachePath = base / "nbproject" / "netbeans.cache"
31 |
32 | s.log.info("Triggered update dependencies task for proect %s" format(projectRef))
33 |
34 | val cachedClasspath = (pluginCachePath.get.map{ path =>
35 | val classpathCache = IO.readLines(path, Charset.defaultCharset).mkString(":")
36 | s.log.info("Cache file exists: %s" format(classpathCache))
37 | classpathCache
38 | }).headOption.getOrElse("")
39 |
40 | val currentClasspath = classpath.files.mkString(":")
41 |
42 | if(currentClasspath != cachedClasspath){
43 | s.log.info("Updating classpath: %s" format(currentClasspath))
44 | IO.write(pluginCachePath, currentClasspath.getBytes)
45 | updateProjectProperties(projectRef)(s)
46 | }
47 | }
48 |
49 | /** Persists plugin settings in SBT project config */
50 | def writePluginSettings(pref: ProjectRef, structure: sbt.Load.BuildStructure) = {
51 | val project = Project.getProject(pref, structure).getOrElse(sys.error("Invalid project reference " + pref))
52 | val appendTo: File = BuildPaths.configurationSources(project.base).headOption.getOrElse(new File(project.base, "build.sbt"))
53 | val baseAppend = exportedSettings.flatMap("" :: _ :: Nil)
54 | val adjustedLines = if(appendTo.isFile && !SessionSettings.needsTrailingBlank(IO readLines appendTo) ) baseAppend else "" +: baseAppend
55 | IO.writeLines(appendTo, adjustedLines, append = true)
56 | }
57 |
58 | }
59 |
--------------------------------------------------------------------------------
/src/main/scala/netbeans/project/AntScript.scala:
--------------------------------------------------------------------------------
1 | package netbeans.project
2 |
3 | import netbeans.NetbeansPlugin
4 | import netbeans.NetbeansTasks
5 | import sbt._
6 | import java.io.File
7 | import scala.xml.{Node, XML}
8 | import scala.xml.transform.{RuleTransformer, RewriteRule}
9 |
10 | case class AntScript(originalFilePath: File)(implicit context: ProjectContext) extends NetbeansConfigFile{
11 |
12 | val description = "Ant-script (build.xml)"
13 |
14 | lazy val operatingSystem = System.getProperty("os.name")
15 |
16 | private val scriptRewriter = new RuleTransformer(new RewriteRule {
17 |
18 | import context._
19 |
20 | val extracted = Project.extract(currentState)
21 |
22 | val sbtExecutableName = (NetbeansPlugin.sbtExecutable in
23 | extracted.currentRef get
24 | extracted.structure.data).getOrElse("sbt")
25 |
26 | override def transform(n: Node): Seq[Node] = n match {
27 | case {children @ _*} =>
28 | {
29 | children
30 | }
31 |
32 | case {args @ _*} =>
33 | {args}
36 |
37 | case arg @ =>
38 |
44 |
45 | case other => other
46 | }
47 |
48 | })
49 |
50 | def store(outputFile: File): Unit = {
51 | val script = scriptRewriter(XML.loadFile(originalFilePath.asFile))
52 | IO.write(outputFile.asFile, script.toString.getBytes)
53 | }
54 |
55 | }
--------------------------------------------------------------------------------
/src/main/scala/netbeans/project/NetbeansConfigFile.scala:
--------------------------------------------------------------------------------
1 | /*
2 | * To change this template, choose Tools | Templates
3 | * and open the template in the editor.
4 | */
5 |
6 | package netbeans.project
7 |
8 | import java.io.File
9 | import scalaz._
10 | import Scalaz._
11 | import sbt._
12 |
13 | trait NetbeansConfigFile {
14 |
15 | val originalFilePath: File
16 |
17 | def description: String
18 |
19 | def validate = (originalFilePath.get.toList match {
20 | case Nil => originalFilePath.fail
21 | case head :: tail => this.success
22 | }).liftFailNel
23 |
24 | def store(outputFile: File = originalFilePath): Unit
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/src/main/scala/netbeans/project/ProjectConfiguration.scala:
--------------------------------------------------------------------------------
1 | package netbeans.project
2 |
3 | import scala.xml.{XML, Node, NodeSeq, Elem, UnprefixedAttribute, Null}
4 | import scala.xml.transform.{RewriteRule, RuleTransformer}
5 | import sbt._
6 | import ProjectContext._
7 | import java.io.File
8 |
9 | case class ProjectConfiguration(originalFilePath: File)(implicit context: ProjectContext) extends NetbeansConfigFile{
10 |
11 | val description = "project configuration (nbproject/project.xml)"
12 |
13 | private val sourceRoots = {
14 | import context._
15 | import src._
16 | import res._
17 |
18 | Map(
19 | ("src.dir", "Scala Source") -> scalaSource.isEmpty,
20 | ("src.java.dir", "Java Source") -> javaSource.isEmpty,
21 | ("resources.dir", "Resources") -> resources.isEmpty,
22 | ("sources.sbt.project", "Configuration") -> false
23 | ).filter(_._2 == false).keys
24 | }
25 |
26 | private val testRoots = {
27 | import context._
28 | import src._
29 | import res._
30 |
31 | Map(
32 | ("test.src.dir", "Scala Test Sources") -> scalaTestSource.isEmpty,
33 | ("file.reference.test-java", "Java Test Sources") -> javaTestSource.isEmpty,
34 | ("test.resources.dir", "Test Resources") -> testResources.isEmpty
35 | ).filter(_._2 == false).keys
36 | }
37 |
38 | private val projectConfig = XML.loadFile(originalFilePath.asFile)
39 |
40 | private val projectConfigRuleTransformer =
41 | new RuleTransformer(new RewriteRule {
42 | val references = context.project.uses.flatMap(subProject =>
43 |
44 | {subProject.project}
45 | jar
46 |
47 | jar
48 | clean
49 | jar
50 |
51 | ).toSeq
52 |
53 | override def transform(n: Node): Seq[Node] =
54 | n match {
55 | case {_} =>
56 | {context.name}
57 |
58 | case Elem(prefix, "references", attribs, scope) =>
59 | Elem(prefix, "references", attribs, scope, references:_ *)
60 |
61 | case {_*} =>
62 | {
63 | sourceRoots.flatMap{case (id, name) => }
64 | }
65 |
66 | case {_*} =>
67 | {
68 | testRoots.flatMap{case (id, name) => }
69 | }
70 |
71 | case other => other
72 | }
73 |
74 |
75 | })
76 |
77 | def store(outputFile: File): Unit =
78 | IO.write(outputFile.asFile, projectConfigRuleTransformer(projectConfig).toString.getBytes)
79 |
80 | }
81 |
--------------------------------------------------------------------------------
/src/main/scala/netbeans/project/ProjectContext.scala:
--------------------------------------------------------------------------------
1 | /*
2 | * To change this template, choose Tools | Templates
3 | * and open the template in the editor.
4 | */
5 |
6 | package netbeans.project
7 |
8 | import java.io.File
9 | import sbt._
10 |
11 | object ProjectContext{
12 |
13 | import Keys._
14 | import scalaz.Scalaz._
15 |
16 | class EmptyPath(path: File){
17 | def isEmpty = path.get.headOption.isEmpty
18 | }
19 |
20 | def toOption[T](res: Result[T]) = res match {
21 | case Value(r) => Some(r)
22 | case _ => None
23 | }
24 |
25 | implicit def fileToEmptyPath(file: File) = new EmptyPath(file)
26 |
27 | def projectSources(currentProjectRef: ProjectRef, s: State) = {
28 | val extracted = Project extract s
29 | import extracted._
30 |
31 | val _mainClass = Project.evaluateTask(mainClass in (currentProjectRef, Compile, run), s)
32 | .flatMap(toOption).flatMap(x => x)
33 |
34 | (scalaSource in (currentProjectRef, Compile) get structure.data) |@|
35 | (scalaSource in (currentProjectRef, Test) get structure.data) |@|
36 | (javaSource in (currentProjectRef, Compile) get structure.data) |@|
37 | (javaSource in (currentProjectRef, Test) get structure.data) |@|
38 | Some(_mainClass) apply ProjectSources.apply
39 | }
40 |
41 | def projectResources(currentProjectRef: ProjectRef, s: State) = {
42 | val extracted = Project extract s
43 | import extracted._
44 |
45 | (resourceDirectory in (currentProjectRef, Compile) get structure.data) |@|
46 | (resourceDirectory in (currentProjectRef, Test) get structure.data) apply ProjectResources.apply
47 | }
48 |
49 | def projectClasspaths(currentProjectRef: ProjectRef, s: State) = {
50 | val extracted = Project extract s
51 | import extracted._
52 |
53 | ((Project.evaluateTask(externalDependencyClasspath in (currentProjectRef, Compile), s) |@|
54 | Project.evaluateTask(externalDependencyClasspath in (currentProjectRef, Test), s)) apply { (compCp, testCp) =>
55 | (toOption(compCp) |@| toOption(testCp)) apply ProjectClasspaths.apply
56 | }).flatten.headOption
57 | }
58 |
59 | def netbeansContext(currentProjectRef: ProjectRef, s: State) = {
60 | val extracted = Project extract s
61 | import extracted._
62 |
63 | Option(s) |@|
64 | (thisProject in (currentProjectRef, Compile) get structure.data) |@|
65 | (name in (currentProjectRef, Compile) get structure.data) |@|
66 | (baseDirectory in (currentProjectRef, Compile) get structure.data) |@|
67 | projectSources(currentProjectRef, s) |@|
68 | projectResources(currentProjectRef, s) |@|
69 | projectClasspaths(currentProjectRef, s) |@|
70 | Project.evaluateTask(scalaInstance in (currentProjectRef, Compile), s).flatMap(toOption) apply ProjectContext.apply
71 | }
72 |
73 | }
74 |
75 | case class ProjectSources(scalaSource: File, scalaTestSource: File,
76 | javaSource: File, javaTestSource: File, mainClass: Option[String])
77 | case class ProjectResources(resources: File, testResources: File)
78 | case class ProjectClasspaths(compileClasspath: Keys.Classpath, testClasspath: Keys.Classpath)
79 |
80 | case class ProjectContext(currentState: State, project: ResolvedProject, name: String,
81 | baseDirectory: File, src: ProjectSources, res: ProjectResources,
82 | classpaths: ProjectClasspaths, scalaInstance: ScalaInstance){
83 |
84 | protected def subprojectClasspath =
85 | project.uses
86 | .map(subProject => "${reference.%s.jar}".format(subProject.project))
87 |
88 | val sbtJars = (baseDirectory \ "project" ** "sbt" ** "*.jar").get.map(_.absolutePath).toList
89 | val scalaJars = scalaInstance.jars
90 |
91 | val compileClasspathString = (subprojectClasspath ++ classpaths.compileClasspath.files ++
92 | scalaJars ++ sbtJars).mkString(":")
93 | val testClasspathString = (classpaths.testClasspath.files ++ scalaJars).mkString(":")
94 |
95 | }
96 |
--------------------------------------------------------------------------------
/src/main/scala/netbeans/project/ProjectProperties.scala:
--------------------------------------------------------------------------------
1 | package netbeans.project
2 |
3 | import java.nio.charset.Charset
4 | import java.util.Properties
5 | import sbt._
6 | import java.io.File
7 |
8 | case class ProjectProperties(originalFilePath: File)
9 | (implicit context: ProjectContext)
10 | extends Properties with NetbeansConfigFile{
11 |
12 | import context._
13 | import src._
14 | import res._
15 |
16 | val description = "project properties (nbproject/project.properties)"
17 |
18 | val extracted = Project.extract(currentState)
19 |
20 | IO.reader(originalFilePath, Charset.defaultCharset)(load)
21 |
22 | protected def destPath(projectRef: ProjectRef) =
23 | (Keys.artifactPath in (projectRef, Keys.makePom) get extracted.structure.data)
24 | .map(_.absolutePath.replaceAll("\\.pom", ".jar"))
25 |
26 | private def subprojectProperties = {
27 | import scalaz.Scalaz._
28 |
29 | project.uses.flatMap{subProject =>
30 | ((Keys.artifactPath in (subProject, Keys.makePom) get extracted.structure.data) |@|
31 | (Keys.baseDirectory in subProject get extracted.structure.data)) { (_dest, _baseDirectory) =>
32 | "reference." + subProject.project + ".jar" -> _dest.absolutePath.replaceAll("\\.pom", ".jar") ::
33 | "project." + subProject.project -> _baseDirectory ::
34 | Nil
35 | } getOrElse Nil
36 | }
37 | }
38 |
39 | def properties = Map(
40 | "application.title" -> name,
41 | "file.reference.main-scala" -> scalaSource,
42 | "file.reference.test-scala" -> scalaTestSource,
43 | "file.reference.main-java" -> javaSource,
44 | "file.reference.test-java" -> javaTestSource,
45 | "test.resources.dir" -> testResources,
46 | "resources.dir" -> resources,
47 | "javac.classpath" -> compileClasspathString,
48 | "javac.test.classpath" -> testClasspathString,
49 | "main.class" -> mainClass.getOrElse(""),
50 | "dist.jar" -> destPath(extracted.currentRef).getOrElse("")
51 | ) ++ subprojectProperties
52 |
53 | def store(outputFile: File): Unit =
54 | IO.writer(outputFile.asFile, "", Charset.defaultCharset, false) { content =>
55 | properties.foreach(prop => setProperty(prop._1, prop._2.toString))
56 | store(content, "Generated with sbt-netbeans-plugin")
57 | }
58 | }
59 |
--------------------------------------------------------------------------------