├── .gitignore
├── README.md
├── project
├── Build.scala
├── Dependencies.scala
├── build.properties
└── plugins.sbt
├── scalariform.sbt
└── src
└── main
├── resources
└── LICENSE-2.0.txt
└── scala
└── com
└── typesafe
└── sbt
├── PreferencesProtocol.scala
├── SbtScalariform.scala
└── Scalariform.scala
/.gitignore:
--------------------------------------------------------------------------------
1 | # SBT
2 | boot/
3 | lib_managed/
4 | target/
5 | .history
6 |
7 | # Eclipse
8 | .cache
9 | .classpath
10 | .project
11 | .scala_dependencies
12 | .settings
13 | .target/
14 | eclipse.sbt
15 |
16 | # IntelliJ
17 | .idea/
18 | *.iml
19 | *.ipr
20 | *.iws
21 | out/
22 |
23 | # TextMate
24 | *.tmproj
25 |
26 | # Mac
27 | .DS_Store
28 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | sbt-scalariform
2 | ===============
3 |
4 | Welcome to sbt-scalariform, an sbt plugin adding support for source code formatting using Scalariform.
5 |
6 | Installing sbt-scalariform
7 | --------------------------
8 |
9 | As of sbt-scalariform 1.5.0, this plugin is now an auto plugin. Make sure to read the _Upgrading from 1.4.0_
10 | and _Advanced Configuration_ sections carefully when upgrading.
11 |
12 | sbt-scalariform is a plugin for sbt 0.13.5+. Please make sure that you are using an appropriate sbt release.
13 | In order to download and install sbt, please refer to [sbt Getting Started Guide / Setup](http://www.scala-sbt.org/release/docs/Getting-Started/Setup.html).
14 |
15 | As sbt-scalariform is a plugin for sbt, it is installed like any other sbt plugin, that is by mere configuration.
16 | For details about using sbt plugins, please refer to [sbt Getting Started Guide / Using Plugins](http://www.scala-sbt.org/release/docs/Getting-Started/Using-Plugins.html).
17 |
18 | If you've got a simple one project build, you can probably skip the details and just add sbt-scalariform to your local plugin definition.
19 | If you've got a more complicated build with several projects and are __upgrading from 1.4.0 or older__, see the next section below.
20 | Local plugins are defined in a `plugins.sbt` file in the `project/` folder of your project.
21 |
22 | To add sbt-scalariform to your build using sbt 0.13.5, just add the below setting, paying attention to blank lines:
23 |
24 | ```
25 | ... // Other settings
26 | resolvers += "Sonatype OSS Releases" at "https://oss.sonatype.org/service/local/staging/deploy/maven2"
27 |
28 | addSbtPlugin("org.scalariform" % "sbt-scalariform" % "1.6.0")
29 | ```
30 |
31 | This will add the task `scalariformFormat` in the scopes `compile` and `test` and additionally run this task automatically when compiling;
32 | for more control see the section *Advanced configuration* below
33 |
34 | Now you are ready to go. Either start sbt or, if it was already started, reload the current session by executing the
35 | `reload` command. If everything worked, you should have the new command `scalariformFormat` available as well automatic
36 | formatting on `compile` and `test:compile` activated.
37 |
38 |
39 | After adding the sbt-scalariform plugin like this, if you want different formatting settings from the default behavior, read
40 | the advanced configuration section.
41 |
42 | If you are using an sbt 0.13.x version older than 0.13.5, you'll want to upgrade, or stick to using sbt-scalariform 1.4.0.
43 |
44 | sbt 0.12.x and below is not supported for this fork, see `https://github.com/sbt/sbt-scalariform` for
45 | older versions.
46 |
47 | Upgrading from 1.4.0: Disabling Auto-plugin Auto Formatting behavior
48 | ---------------------------------------------
49 | Sbt-Scalariform versions 1.5.0 and greater have switched to using AutoPlugins for automatic settings in build files.
50 | By default, when including this project, all of your projects defined will now have sbt-scalariform settings mixed into
51 | each project. This means on compilation, your code will be formatted. If you'd like to keep sbt-scalariform
52 | available for manual formatting with a sbt `scalariformFormat` command, you can mix in `defaultScalariformSettings` to your project --
53 | see the advanced configuration section for details on how to do this.
54 |
55 | Autoplugins only work with sbt 0.13.5 or greater.
56 |
57 | If you'd like to disable this plugin entirely on a per project basis, you can use sbt's built in feature to disable auto plugins:
58 |
59 | ```
60 | import com.typesafe.sbt.SbtScalariform
61 |
62 | lazy val project = Project(
63 | ...
64 | ).disablePlugins(SbtScalariform)
65 | ```
66 |
67 | Using sbt-scalariform
68 | ---------------------
69 |
70 | If you added the settings for this plugin like described above, you can either format your sources manually or automatically:
71 |
72 | - Whenever you run the tasks `compile` or `test:compile`, your source files will be automatically formatted by Scalariform
73 |
74 | - If you want to start formatting your source files explicitly, just run the task `scalariformFormat` or `test:scalariformFormat`
75 |
76 | Advanced configuration
77 | ----------------------
78 | sbt-scalariform comes with various configuration options. Changing the formatting preferences and deactivating the automatic formatting on compile are probably the most important ones and described in detail.
79 |
80 | You can provide your own formatting preferences for Scalariform via the setting key `ScalariformKeys.preferences` which expects an instance of `IFormattingPreferences`. Make sure you import all necessary members from the package `scalariform.formatter.preferences`. Let's look at an example:
81 |
82 | .sbt build example
83 | ```
84 | import scalariform.formatter.preferences._
85 | import com.typesafe.sbt.SbtScalariform
86 |
87 | SbtScalariform.scalariformSettings
88 |
89 | ScalariformKeys.preferences := ScalariformKeys.preferences.value
90 | .setPreference(AlignSingleLineCaseStatements, true)
91 | .setPreference(DoubleIndentClassDeclaration, true)
92 | .setPreference(PreserveDanglingCloseParenthesis, true)
93 | ```
94 |
95 | .scala build example
96 | ```
97 | import scalariform.formatter.preferences._
98 | import com.typesafe.sbt.SbtScalariform
99 |
100 | lazy val project = Project(
101 | ...
102 | settings = SbtScalariform.scalariformSettings ++ Seq(
103 | ScalariformKeys.preferences := ScalariformKeys.preferences.value
104 | .setPreference(AlignSingleLineCaseStatements, true)
105 | .setPreference(DoubleIndentClassDeclaration, true)
106 | .setPreference(PreserveDanglingCloseParenthesis, true)
107 | )
108 | )
109 | ```
110 |
111 | If you don't want sbt to automatically format your source files when the tasks `compile` or `test:compile`, just add
112 | `defaultScalariformSettings` instead of `scalariformSettings` to your build definition.
113 |
114 | .scala build example:
115 | ```
116 | import com.typesafe.sbt.SbtScalariform
117 |
118 | lazy val project = Project(
119 | "project_name",
120 | file("."),
121 | settings = SbtScalariform.defaultScalariformSettings ++
122 | ...
123 | )
124 | ```
125 |
126 | .sbt build example:
127 |
128 | ```
129 | import com.typesafe.sbt.SbtScalariform
130 |
131 | SbtScalariform.defaultScalariformSettings
132 | ```
133 |
134 |
135 | If you want to additionally enable Scalariform for your integration tests, use `scalariformSettingsWithIt` or `defaultScalariformSettingsWithIt` instead of the above.
136 |
137 | Other useful configuration options are provided by common sbt setting keys:
138 |
139 | - `includeFilter in format`: Defaults to **.scala*
140 | - `excludeFilter in format`: Using the default of sbt
141 |
142 | Contact
143 | ------------
144 |
145 | Please contact `@daniel-trinh` on http://github.com for help
146 |
147 | License
148 | -------
149 |
150 | This code is open source software licensed under the Apache 2.0 License.
151 |
--------------------------------------------------------------------------------
/project/Build.scala:
--------------------------------------------------------------------------------
1 | import sbt._
2 | import sbt.Keys._
3 | import sbt.{ThisBuild, Project}
4 | import scala.Some
5 | import com.typesafe.sbt.SbtScalariform
6 | import com.typesafe.sbt.SbtScalariform.ScalariformKeys
7 | import scalariform.formatter.preferences._
8 |
9 | object SbtScalariformBuild extends Build {
10 |
11 | val formattingPreferences = {
12 | import scalariform.formatter.preferences._
13 | FormattingPreferences()
14 | .setPreference(AlignParameters, true)
15 | .setPreference(CompactStringConcatenation, true)
16 | .setPreference(CompactControlReadability, false)
17 | .setPreference(AlignSingleLineCaseStatements, true)
18 | .setPreference(AlignSingleLineCaseStatements.MaxArrowIndent, 40)
19 | .setPreference(SpacesWithinPatternBinders, true)
20 | .setPreference(DoubleIndentClassDeclaration, true)
21 | .setPreference(SpacesAroundMultiImports, true)
22 | }
23 |
24 | def getPublishToRepo(isSnapshot: Boolean) =
25 | if (isSnapshot)
26 | Some("snapshots" at "https://oss.sonatype.org/content/repositories/snapshots")
27 | else
28 | Some("releases" at "https://oss.sonatype.org/service/local/staging/deploy/maven2")
29 |
30 | val sbtScalariform: Project = Project(
31 | "sbt-scalariform",
32 | file("."),
33 | settings = Seq(
34 | organization := "org.scalariform",
35 | name := "sbt-scalariform",
36 | version in ThisBuild := "1.6.0",
37 | resolvers ++= Resolvers.resolvers,
38 | libraryDependencies ++= Dependencies.sbtScalariform,
39 | scalacOptions ++= List(
40 | "-unchecked",
41 | "-deprecation",
42 | "-Xlint",
43 | "-language:_",
44 | "-target:jvm-1.6",
45 | "-encoding", "UTF-8"
46 | ),
47 | ScalariformKeys.preferences := formattingPreferences,
48 | sbtPlugin := true,
49 | publishTo <<= isSnapshot(getPublishToRepo),
50 | publishMavenStyle := true,
51 | publishArtifact in Test := false,
52 | publishArtifact in (Compile, packageSrc) := true,
53 | pomExtra :=
54 | http://github.com/daniel-trinh/sbt-scalariform
55 |
56 |
57 | Apache 2.0
58 | http://www.apache.org/licenses/LICENSE-2.0
59 | repo
60 |
61 |
62 |
63 | git@github.com:daniel-trinh/sbt-scalariform.git
64 | scm:git@github.com:daniel-trinh/sbt-scalariform.git
65 |
66 |
67 |
68 | hseeberger
69 | Heiko Seeberger
70 | http://blog.heikoseeberger.name/
71 |
72 |
73 | daniel-trinh
74 | Daniel Trinh
75 | http://danieltrinh.com
76 |
77 |
78 | )
79 | )
80 | }
81 |
82 | object Resolvers {
83 | val sonatypeSnapshots = "Sonatype OSS Snapshots" at "https://oss.sonatype.org/content/repositories/snapshots"
84 | val sonatypeReleases = "Sonatype OSS Releases" at "https://oss.sonatype.org/service/local/staging/deploy/maven2"
85 |
86 | val resolvers = Seq(
87 | sonatypeSnapshots,
88 | sonatypeReleases
89 | )
90 | }
--------------------------------------------------------------------------------
/project/Dependencies.scala:
--------------------------------------------------------------------------------
1 | import sbt._
2 |
3 | object Version {
4 | val scalariform = "0.1.8"
5 | }
6 |
7 | object Library {
8 | val scalariform = "org.scalariform" %% "scalariform" % Version.scalariform
9 | }
10 |
11 | object Dependencies {
12 |
13 | import Library._
14 |
15 | val sbtScalariform = List(
16 | scalariform
17 | )
18 | }
--------------------------------------------------------------------------------
/project/build.properties:
--------------------------------------------------------------------------------
1 | sbt.version=0.13.9
2 |
--------------------------------------------------------------------------------
/project/plugins.sbt:
--------------------------------------------------------------------------------
1 | addSbtPlugin("org.scalariform" % "sbt-scalariform" % "1.5.1")
2 |
3 | addSbtPlugin("com.typesafe.sbt" % "sbt-pgp" % "0.8.1")
--------------------------------------------------------------------------------
/scalariform.sbt:
--------------------------------------------------------------------------------
1 | import com.typesafe.sbt.SbtScalariform.ScalariformKeys
2 | import scalariform.formatter.preferences._
3 |
4 | ScalariformKeys.preferences := ScalariformKeys.preferences.value
5 | .setPreference(AlignSingleLineCaseStatements, true)
6 | .setPreference(DoubleIndentClassDeclaration, true)
7 | .setPreference(PreserveDanglingCloseParenthesis, true)
8 |
--------------------------------------------------------------------------------
/src/main/resources/LICENSE-2.0.txt:
--------------------------------------------------------------------------------
1 |
2 | Apache License
3 | Version 2.0, January 2004
4 | http://www.apache.org/licenses/
5 |
6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7 |
8 | 1. Definitions.
9 |
10 | "License" shall mean the terms and conditions for use, reproduction,
11 | and distribution as defined by Sections 1 through 9 of this document.
12 |
13 | "Licensor" shall mean the copyright owner or entity authorized by
14 | the copyright owner that is granting the License.
15 |
16 | "Legal Entity" shall mean the union of the acting entity and all
17 | other entities that control, are controlled by, or are under common
18 | control with that entity. For the purposes of this definition,
19 | "control" means (i) the power, direct or indirect, to cause the
20 | direction or management of such entity, whether by contract or
21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
22 | outstanding shares, or (iii) beneficial ownership of such entity.
23 |
24 | "You" (or "Your") shall mean an individual or Legal Entity
25 | exercising permissions granted by this License.
26 |
27 | "Source" form shall mean the preferred form for making modifications,
28 | including but not limited to software source code, documentation
29 | source, and configuration files.
30 |
31 | "Object" form shall mean any form resulting from mechanical
32 | transformation or translation of a Source form, including but
33 | not limited to compiled object code, generated documentation,
34 | and conversions to other media types.
35 |
36 | "Work" shall mean the work of authorship, whether in Source or
37 | Object form, made available under the License, as indicated by a
38 | copyright notice that is included in or attached to the work
39 | (an example is provided in the Appendix below).
40 |
41 | "Derivative Works" shall mean any work, whether in Source or Object
42 | form, that is based on (or derived from) the Work and for which the
43 | editorial revisions, annotations, elaborations, or other modifications
44 | represent, as a whole, an original work of authorship. For the purposes
45 | of this License, Derivative Works shall not include works that remain
46 | separable from, or merely link (or bind by name) to the interfaces of,
47 | the Work and Derivative Works thereof.
48 |
49 | "Contribution" shall mean any work of authorship, including
50 | the original version of the Work and any modifications or additions
51 | to that Work or Derivative Works thereof, that is intentionally
52 | submitted to Licensor for inclusion in the Work by the copyright owner
53 | or by an individual or Legal Entity authorized to submit on behalf of
54 | the copyright owner. For the purposes of this definition, "submitted"
55 | means any form of electronic, verbal, or written communication sent
56 | to the Licensor or its representatives, including but not limited to
57 | communication on electronic mailing lists, source code control systems,
58 | and issue tracking systems that are managed by, or on behalf of, the
59 | Licensor for the purpose of discussing and improving the Work, but
60 | excluding communication that is conspicuously marked or otherwise
61 | designated in writing by the copyright owner as "Not a Contribution."
62 |
63 | "Contributor" shall mean Licensor and any individual or Legal Entity
64 | on behalf of whom a Contribution has been received by Licensor and
65 | subsequently incorporated within the Work.
66 |
67 | 2. Grant of Copyright License. Subject to the terms and conditions of
68 | this License, each Contributor hereby grants to You a perpetual,
69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70 | copyright license to reproduce, prepare Derivative Works of,
71 | publicly display, publicly perform, sublicense, and distribute the
72 | Work and such Derivative Works in Source or Object form.
73 |
74 | 3. Grant of Patent License. Subject to the terms and conditions of
75 | this License, each Contributor hereby grants to You a perpetual,
76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77 | (except as stated in this section) patent license to make, have made,
78 | use, offer to sell, sell, import, and otherwise transfer the Work,
79 | where such license applies only to those patent claims licensable
80 | by such Contributor that are necessarily infringed by their
81 | Contribution(s) alone or by combination of their Contribution(s)
82 | with the Work to which such Contribution(s) was submitted. If You
83 | institute patent litigation against any entity (including a
84 | cross-claim or counterclaim in a lawsuit) alleging that the Work
85 | or a Contribution incorporated within the Work constitutes direct
86 | or contributory patent infringement, then any patent licenses
87 | granted to You under this License for that Work shall terminate
88 | as of the date such litigation is filed.
89 |
90 | 4. Redistribution. You may reproduce and distribute copies of the
91 | Work or Derivative Works thereof in any medium, with or without
92 | modifications, and in Source or Object form, provided that You
93 | meet the following conditions:
94 |
95 | (a) You must give any other recipients of the Work or
96 | Derivative Works a copy of this License; and
97 |
98 | (b) You must cause any modified files to carry prominent notices
99 | stating that You changed the files; and
100 |
101 | (c) You must retain, in the Source form of any Derivative Works
102 | that You distribute, all copyright, patent, trademark, and
103 | attribution notices from the Source form of the Work,
104 | excluding those notices that do not pertain to any part of
105 | the Derivative Works; and
106 |
107 | (d) If the Work includes a "NOTICE" text file as part of its
108 | distribution, then any Derivative Works that You distribute must
109 | include a readable copy of the attribution notices contained
110 | within such NOTICE file, excluding those notices that do not
111 | pertain to any part of the Derivative Works, in at least one
112 | of the following places: within a NOTICE text file distributed
113 | as part of the Derivative Works; within the Source form or
114 | documentation, if provided along with the Derivative Works; or,
115 | within a display generated by the Derivative Works, if and
116 | wherever such third-party notices normally appear. The contents
117 | of the NOTICE file are for informational purposes only and
118 | do not modify the License. You may add Your own attribution
119 | notices within Derivative Works that You distribute, alongside
120 | or as an addendum to the NOTICE text from the Work, provided
121 | that such additional attribution notices cannot be construed
122 | as modifying the License.
123 |
124 | You may add Your own copyright statement to Your modifications and
125 | may provide additional or different license terms and conditions
126 | for use, reproduction, or distribution of Your modifications, or
127 | for any such Derivative Works as a whole, provided Your use,
128 | reproduction, and distribution of the Work otherwise complies with
129 | the conditions stated in this License.
130 |
131 | 5. Submission of Contributions. Unless You explicitly state otherwise,
132 | any Contribution intentionally submitted for inclusion in the Work
133 | by You to the Licensor shall be under the terms and conditions of
134 | this License, without any additional terms or conditions.
135 | Notwithstanding the above, nothing herein shall supersede or modify
136 | the terms of any separate license agreement you may have executed
137 | with Licensor regarding such Contributions.
138 |
139 | 6. Trademarks. This License does not grant permission to use the trade
140 | names, trademarks, service marks, or product names of the Licensor,
141 | except as required for reasonable and customary use in describing the
142 | origin of the Work and reproducing the content of the NOTICE file.
143 |
144 | 7. Disclaimer of Warranty. Unless required by applicable law or
145 | agreed to in writing, Licensor provides the Work (and each
146 | Contributor provides its Contributions) on an "AS IS" BASIS,
147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
148 | implied, including, without limitation, any warranties or conditions
149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
150 | PARTICULAR PURPOSE. You are solely responsible for determining the
151 | appropriateness of using or redistributing the Work and assume any
152 | risks associated with Your exercise of permissions under this License.
153 |
154 | 8. Limitation of Liability. In no event and under no legal theory,
155 | whether in tort (including negligence), contract, or otherwise,
156 | unless required by applicable law (such as deliberate and grossly
157 | negligent acts) or agreed to in writing, shall any Contributor be
158 | liable to You for damages, including any direct, indirect, special,
159 | incidental, or consequential damages of any character arising as a
160 | result of this License or out of the use or inability to use the
161 | Work (including but not limited to damages for loss of goodwill,
162 | work stoppage, computer failure or malfunction, or any and all
163 | other commercial damages or losses), even if such Contributor
164 | has been advised of the possibility of such damages.
165 |
166 | 9. Accepting Warranty or Additional Liability. While redistributing
167 | the Work or Derivative Works thereof, You may choose to offer,
168 | and charge a fee for, acceptance of support, warranty, indemnity,
169 | or other liability obligations and/or rights consistent with this
170 | License. However, in accepting such obligations, You may act only
171 | on Your own behalf and on Your sole responsibility, not on behalf
172 | of any other Contributor, and only if You agree to indemnify,
173 | defend, and hold each Contributor harmless for any liability
174 | incurred by, or claims asserted against, such Contributor by reason
175 | of your accepting any such warranty or additional liability.
176 |
177 | END OF TERMS AND CONDITIONS
178 |
179 | APPENDIX: How to apply the Apache License to your work.
180 |
181 | To apply the Apache License to your work, attach the following
182 | boilerplate notice, with the fields enclosed by brackets "[]"
183 | replaced with your own identifying information. (Don't include
184 | the brackets!) The text should be enclosed in the appropriate
185 | comment syntax for the file format. We also recommend that a
186 | file or class name and description of purpose be included on the
187 | same "printed page" as the copyright notice for easier
188 | identification within third-party archives.
189 |
190 | Copyright [yyyy] [name of copyright owner]
191 |
192 | Licensed under the Apache License, Version 2.0 (the "License");
193 | you may not use this file except in compliance with the License.
194 | You may obtain a copy of the License at
195 |
196 | http://www.apache.org/licenses/LICENSE-2.0
197 |
198 | Unless required by applicable law or agreed to in writing, software
199 | distributed under the License is distributed on an "AS IS" BASIS,
200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
201 | See the License for the specific language governing permissions and
202 | limitations under the License.
203 |
--------------------------------------------------------------------------------
/src/main/scala/com/typesafe/sbt/PreferencesProtocol.scala:
--------------------------------------------------------------------------------
1 | package com.typesafe.sbt
2 |
3 | import java.io.{ StringReader, StringWriter }
4 | import java.util.Properties
5 | import sbinary.Operations._
6 | import sbinary.{ Input, Output, Format, DefaultProtocol }
7 | import scalariform.formatter.preferences.{ PreferencesImporterExporter, IFormattingPreferences }
8 |
9 | object PreferencesProtocol extends DefaultProtocol {
10 |
11 | implicit object PrefFormat extends Format[IFormattingPreferences]() {
12 | override def writes(out: Output, value: IFormattingPreferences): Unit = {
13 | val outStream = new StringWriter()
14 | PreferencesImporterExporter.asProperties(value).store(outStream, null)
15 | write[String](out, outStream.toString)
16 | }
17 |
18 | override def reads(in: Input): IFormattingPreferences = {
19 | val properties = new Properties
20 | properties.load(new StringReader(read[String](in)))
21 | PreferencesImporterExporter.getPreferences(properties)
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/main/scala/com/typesafe/sbt/SbtScalariform.scala:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011-2012 Typesafe Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.typesafe.sbt
18 |
19 | import sbt._
20 | import sbt.plugins.JvmPlugin
21 | import sbt.{ IntegrationTest => It }
22 | import sbt.Keys._
23 | import scala.collection.immutable.Seq
24 | import scalariform.formatter.preferences.IFormattingPreferences
25 |
26 | object SbtScalariform extends AutoPlugin {
27 |
28 | val defaultPreferences = {
29 | import scalariform.formatter.preferences._
30 | FormattingPreferences()
31 | .setPreference(SpacesAroundMultiImports, true) // this was changed in 0.1.7 scalariform, setting this to preserve default.
32 | .setPreference(DoubleIndentClassDeclaration, true)
33 | }
34 |
35 | object autoImport {
36 |
37 | val scalariformFormat: TaskKey[Seq[File]] =
38 | TaskKey[Seq[File]](
39 | prefixed("format"),
40 | "Format (Scala) sources using scalariform"
41 | )
42 |
43 | val scalariformPreferences: SettingKey[IFormattingPreferences] =
44 | SettingKey[IFormattingPreferences](
45 | prefixed("preferences"),
46 | "Scalariform formatting preferences, e.g. indentation"
47 | )
48 | private def prefixed(key: String) = s"scalariform-$key"
49 |
50 | def scalariformSettings: Seq[Setting[_]] =
51 | defaultScalariformSettings ++ List(
52 | compileInputs in (Compile, compile) <<= (compileInputs in (Compile, compile)) dependsOn (scalariformFormat in Compile),
53 | compileInputs in (Test, compile) <<= (compileInputs in (Test, compile)) dependsOn (scalariformFormat in Test)
54 | )
55 | }
56 |
57 | import autoImport._
58 |
59 | override lazy val projectSettings = scalariformSettings
60 | override val trigger = allRequirements
61 | override val requires = JvmPlugin
62 |
63 | object ScalariformKeys {
64 |
65 | val format = autoImport.scalariformFormat
66 |
67 | val preferences = autoImport.scalariformPreferences
68 | }
69 |
70 | def scalariformSettings: Seq[Setting[_]] = autoImport.scalariformSettings
71 |
72 | def scalariformSettingsWithIt: Seq[Setting[_]] =
73 | defaultScalariformSettingsWithIt ++ List(
74 | compileInputs in (Compile, compile) <<= (compileInputs in (Compile, compile)) dependsOn (scalariformFormat in Compile),
75 | compileInputs in (Test, compile) <<= (compileInputs in (Test, compile)) dependsOn (scalariformFormat in Test),
76 | compileInputs in (It, compile) <<= (compileInputs in (It, compile)) dependsOn (scalariformFormat in It)
77 | )
78 |
79 | def defaultScalariformSettings: Seq[Setting[_]] =
80 | noConfigScalariformSettings ++ inConfig(Compile)(configScalariformSettings) ++ inConfig(Test)(configScalariformSettings)
81 |
82 | def defaultScalariformSettingsWithIt: Seq[Setting[_]] =
83 | defaultScalariformSettings ++ inConfig(It)(configScalariformSettings)
84 |
85 | def configScalariformSettings: Seq[Setting[_]] =
86 | List(
87 | (sourceDirectories in Global in scalariformFormat) := List(scalaSource.value),
88 | scalariformFormat := Scalariform(
89 | scalariformPreferences.value,
90 | (sourceDirectories in scalariformFormat).value.toList,
91 | (includeFilter in scalariformFormat).value,
92 | (excludeFilter in scalariformFormat).value,
93 | thisProjectRef.value,
94 | configuration.value,
95 | streams.value,
96 | scalaVersion.value
97 | )
98 | )
99 |
100 | def noConfigScalariformSettings: Seq[Setting[_]] =
101 | List(
102 | scalariformPreferences in Global := defaultPreferences,
103 | includeFilter in Global in scalariformFormat := "*.scala"
104 | )
105 | }
106 |
--------------------------------------------------------------------------------
/src/main/scala/com/typesafe/sbt/Scalariform.scala:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011-2012 Typesafe Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.typesafe.sbt
18 |
19 | import sbt._
20 | import sbt.Keys._
21 | import sbt.{ File, FileFilter, _ }
22 | import scala.collection.immutable.Seq
23 | import scalariform.formatter.ScalaFormatter
24 | import scalariform.formatter.preferences.{ IFormattingPreferences, PreferencesImporterExporter }
25 | import scalariform.parser.ScalaParserException
26 |
27 | private object Scalariform {
28 |
29 | def apply(
30 | preferences: IFormattingPreferences,
31 | sourceDirectories: Seq[File],
32 | includeFilter: FileFilter,
33 | excludeFilter: FileFilter,
34 | ref: ProjectRef,
35 | configuration: Configuration,
36 | streams: TaskStreams,
37 | scalaVersion: String
38 | ): Seq[File] = {
39 |
40 | def log(label: String, logger: Logger)(message: String)(count: String) =
41 | logger.info(message.format(count, label))
42 |
43 | def performFormat(files: Set[File]) =
44 | for (file <- files if file.exists) {
45 | try {
46 | val contents = IO.read(file)
47 | val formatted = ScalaFormatter.format(
48 | contents,
49 | preferences,
50 | scalaVersion = pureScalaVersion(scalaVersion)
51 | )
52 | if (formatted != contents) IO.write(file, formatted)
53 | } catch {
54 | case e: ScalaParserException =>
55 | streams.log.warn("Scalariform parser error for %s: %s".format(file, e.getMessage))
56 | }
57 | }
58 |
59 | val files = sourceDirectories.descendantsExcept(includeFilter, excludeFilter).get.toSet
60 | val cache = streams.cacheDirectory / "scalariform"
61 | val logFun = log("%s(%s)".format(Reference.display(ref), configuration), streams.log) _
62 | if (preferencesChanged(streams.cacheDirectory / "scalariform-preferences")(preferences)) {
63 | IO.delete(cache)
64 | }
65 | handleFiles(files, cache, logFun("Formatting %s %s ..."), performFormat)
66 | handleFiles(files, cache, logFun("Reformatted %s %s."), _ => ()).toList // recalculate cache because we're formatting in-place
67 | }
68 |
69 | def handleFiles(
70 | files: Set[File],
71 | cache: File,
72 | logFun: String => Unit,
73 | updateFun: Set[File] => Unit
74 | ): Set[File] = {
75 |
76 | def handleUpdate(in: ChangeReport[File], out: ChangeReport[File]) = {
77 | val files = in.modified -- in.removed
78 | inc.Analysis.counted("Scala source", "", "s", files.size) foreach logFun
79 | updateFun(files)
80 | files
81 | }
82 |
83 | FileFunction.cached(cache)(FilesInfo.hash, FilesInfo.exists)(handleUpdate)(files)
84 | }
85 |
86 | def pureScalaVersion(scalaVersion: String): String =
87 | scalaVersion split "-" head
88 |
89 | protected def preferencesChanged(cacheDir: File): IFormattingPreferences => Boolean = {
90 | import com.typesafe.sbt.PreferencesProtocol._
91 | val prefChanged = new Changed[IFormattingPreferences](cacheDir)
92 | prefChanged({ _ => true }, { _ => false })
93 | }
94 |
95 | protected implicit val prefEquivalence = new Equiv[IFormattingPreferences]() {
96 | override def equiv(x: IFormattingPreferences, y: IFormattingPreferences): Boolean = {
97 | PreferencesImporterExporter.asProperties(x) == PreferencesImporterExporter.asProperties(y)
98 | }
99 | }
100 |
101 | }
102 |
--------------------------------------------------------------------------------