physique 0.3.4 → 0.3.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. checksums.yaml +8 -8
  2. data/FLUENT_MIGRATOR.md +301 -0
  3. data/Gemfile.lock +2 -1
  4. data/README.md +338 -15
  5. data/RUBY_SETUP.md +40 -0
  6. data/lib/physique/{project.rb → project_path_resolver.rb} +15 -3
  7. data/lib/physique/task_builders/build.rb +12 -5
  8. data/lib/physique/task_builders/default.rb +11 -0
  9. data/lib/physique/task_builders/fluent_migrator.rb +42 -19
  10. data/lib/physique/task_builders/octopus.rb +5 -5
  11. data/lib/physique/tool_locator.rb +8 -0
  12. data/lib/physique/version.rb +1 -1
  13. data/physique.gemspec +1 -0
  14. data/spec/fluent_migrator_config_spec.rb +1 -3
  15. data/spec/project_spec.rb +25 -8
  16. data/spec/task_builders/build_spec.rb +2 -2
  17. data/spec/task_builders/fluent_migrator_spec.rb +48 -0
  18. data/spec/test_data/solutions/fluent-migrator/.semver +6 -0
  19. data/spec/test_data/solutions/fluent-migrator/Basic.Migrations/Basic.Migrations.csproj +64 -0
  20. data/spec/test_data/solutions/fluent-migrator/Basic.Migrations/Properties/AssemblyInfo.cs +36 -0
  21. data/spec/test_data/solutions/fluent-migrator/Basic.Migrations/TestMigration.cs +19 -0
  22. data/spec/test_data/solutions/fluent-migrator/Basic.Migrations/_Scripts/create.sql +2 -0
  23. data/spec/test_data/solutions/fluent-migrator/Basic.Migrations/_Scripts/drop.sql +5 -0
  24. data/spec/test_data/solutions/fluent-migrator/Basic.Migrations/_Scripts/seed.sql +2 -0
  25. data/spec/test_data/solutions/fluent-migrator/Basic.Migrations/packages.config +4 -0
  26. data/spec/test_data/solutions/fluent-migrator/Basic.Specs/Basic.Specs.csproj +60 -0
  27. data/spec/test_data/solutions/fluent-migrator/Basic.Specs/Class1.cs +12 -0
  28. data/spec/test_data/solutions/fluent-migrator/Basic.Specs/DebuggerShim.cs +42 -0
  29. data/spec/test_data/solutions/fluent-migrator/Basic.Specs/Properties/AssemblyInfo.cs +36 -0
  30. data/spec/test_data/solutions/fluent-migrator/Basic.Specs/packages.config +4 -0
  31. data/spec/test_data/solutions/fluent-migrator/Basic.sln +39 -0
  32. data/spec/test_data/solutions/fluent-migrator/Basic/Basic.csproj +56 -0
  33. data/spec/test_data/solutions/fluent-migrator/Basic/Class1.cs +12 -0
  34. data/spec/test_data/solutions/fluent-migrator/Basic/Properties/AssemblyInfo.cs +36 -0
  35. data/spec/test_data/solutions/fluent-migrator/Basic/packages.config +3 -0
  36. data/spec/test_data/solutions/fluent-migrator/Rakefile.rb +20 -0
  37. data/spec/test_data/solutions/multiple-fluent-migrator/.semver +6 -0
  38. data/spec/test_data/solutions/multiple-fluent-migrator/Basic.Migrations1/Basic.Migrations1.csproj +53 -0
  39. data/spec/test_data/solutions/multiple-fluent-migrator/Basic.Migrations1/Class1.cs +12 -0
  40. data/spec/test_data/solutions/multiple-fluent-migrator/Basic.Migrations1/Properties/AssemblyInfo.cs +36 -0
  41. data/spec/test_data/solutions/multiple-fluent-migrator/Basic.Migrations2/Basic.Migrations2.csproj +53 -0
  42. data/spec/test_data/solutions/multiple-fluent-migrator/Basic.Migrations2/Class1.cs +12 -0
  43. data/spec/test_data/solutions/multiple-fluent-migrator/Basic.Migrations2/Properties/AssemblyInfo.cs +36 -0
  44. data/spec/test_data/solutions/multiple-fluent-migrator/Basic.Specs/Basic.Specs.csproj +60 -0
  45. data/spec/test_data/solutions/multiple-fluent-migrator/Basic.Specs/Class1.cs +12 -0
  46. data/spec/test_data/solutions/multiple-fluent-migrator/Basic.Specs/DebuggerShim.cs +42 -0
  47. data/spec/test_data/solutions/multiple-fluent-migrator/Basic.Specs/Properties/AssemblyInfo.cs +36 -0
  48. data/spec/test_data/solutions/multiple-fluent-migrator/Basic.Specs/packages.config +4 -0
  49. data/spec/test_data/solutions/multiple-fluent-migrator/Basic.sln +45 -0
  50. data/spec/test_data/solutions/multiple-fluent-migrator/Basic/Basic.csproj +56 -0
  51. data/spec/test_data/solutions/multiple-fluent-migrator/Basic/Class1.cs +12 -0
  52. data/spec/test_data/solutions/multiple-fluent-migrator/Basic/Properties/AssemblyInfo.cs +36 -0
  53. data/spec/test_data/solutions/multiple-fluent-migrator/Basic/packages.config +3 -0
  54. data/spec/test_data/solutions/multiple-fluent-migrator/Rakefile.rb +28 -0
  55. metadata +95 -3
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- NWU4MGE4OWY1OGU2ODQyZTZlYmQ1ZjJlNzU0MzU2YTY5ZjllZGViMg==
4
+ MzY3MGZmNzZjZjU2YmVlZTdiMDAxYzZhYzZiZDc5ZTY5NDFjZjNiMw==
5
5
  data.tar.gz: !binary |-
6
- NzE1ZjQ5MmU1MjdhZmMxMDM4ODM1MWUxOWNmZDE5YzA3NWM2MzkzMw==
6
+ N2M3MjUyMDE4ZjMxM2JkZDNjYTZkMjM2Y2M3MzZhYWVhOTcyNjhmOA==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- MDZkMWQxZTMzNGFlNjQzODgyNzI0MmI4YWU5MjVkMzQ0NmU2NTc5ZTg1MDAz
10
- NDIzZDVlNjhlZTZmOGE5YTYxNWRkMzk1YmM2ZTk5YjMxMTEzZjM1Mzk0NDg1
11
- MTIyMjQ3ZjUxNDRiZmZjNDVlYjY5Y2Y2YjQwZTU4ZDJlYzQ1YjM=
9
+ N2I3Y2U3YjFiMDYwMWMxNzk1NjM4ZjEwMmFhNmUwNGYxZWU1ZmE1MDIwNTQz
10
+ YTEwYzI2Y2NhZjQwYmFiMzg3ZTFkYzM0ZWM0MGUwMzYxZTMwOTEyYTE2M2Jj
11
+ OTAwMDdkN2I1MGEzYjE4NmIxYjA2Zjk4ZTNlZTBhNjY1ZTk5OGE=
12
12
  data.tar.gz: !binary |-
13
- MzJiYTg2NzhhZGQxNWMyMDdiMjM3YTQ5YWZiNTFlYjcwNDRjZDMzMWJjNzQx
14
- YzkxNTEwYjY0NWU4MjQxMjJkYWEzMWJjY2I4ZTAxMTExM2UyMDUwNzRmNDY3
15
- OWNlZDVlNTMxYTc2NjYwYjkzYjY2MTA4NmY2NmVjZTYzZjU4N2M=
13
+ Y2RlMDE5ZTUxMjQ4NDEzZTZlYTRlYTQyYTEyZjczMzVjNmE1YmY5YjUxYTVh
14
+ NDA1NDYyYTNlNTRkNTBkNGQ1ZTNlYTE4ZjBmMzRiM2JkZDhhMzA3MGNjZWEw
15
+ YTljN2E1MTVmMzliMjIxNmYzMGM5M2ViYjMzMDhlYjdkNGE4YTc=
@@ -0,0 +1,301 @@
1
+ # Using Physique with Fluent Migrator
2
+
3
+ Physique paired with FluentMigrator creates a great developer workflow for managing databases as part of your build.
4
+
5
+ ## Prerequisites
6
+
7
+ For the purposes of this guide we are making the following assumptions:
8
+
9
+ * You have already configured your solution to use Physique.
10
+
11
+ * You are using a SQL Server database.
12
+
13
+ NOTE: Physique currently only works with SQL Server. Support for other databases is certainly possible, but not yet implemented.
14
+
15
+ * You have SQL Client Tools installed and available on your `PATH`.
16
+
17
+ Physique uses `SQLCMD.exe` to execute scripts on the command line.
18
+
19
+ ## Creating a FluentMigrator Project
20
+
21
+ Create a new database project and add the following files and folders:
22
+
23
+ ├─ MyProject.Database
24
+ │ ├─ _Scripts
25
+ │ │ ├─ create.sql
26
+ │ │ ├─ drop.sql
27
+ │ │ └─ seed.sql
28
+ │ └─ Migrations
29
+ └─ MyProject.Database.csproj
30
+
31
+ In the `create.sql` script add the following:
32
+
33
+ ```sql
34
+ -- Create the database
35
+ CREATE DATABASE $(DATABASE_NAME)
36
+ GO
37
+ ```
38
+
39
+ In the `drop.sql` script add the following:
40
+
41
+ ```sql
42
+ -- Drop the database
43
+ if EXISTS(select name from master.dbo.sysdatabases where name = '$(DATABASE_NAME)') begin
44
+ drop database $(DATABASE_NAME)
45
+ end
46
+ GO
47
+ ```
48
+
49
+ As you can see we are not specifying the database name in the scripts. Instead, we are using a variable that will be substituted by Physique when we run our tasks.
50
+
51
+ ## Configuring your Rakefile to use FluentMigrator
52
+
53
+ Open your Rakefile and add the following to your solution's config:
54
+
55
+ ```ruby
56
+ Physique::Solution.new do |s|
57
+ #...
58
+ s.fluently_migrate do |db|
59
+ db.instance = ENV['DATABASE_SERVER'] || '(local)'
60
+ db.name = ENV['DATABASE_NAME'] || 'MyDatabase'
61
+ db.project = 'src/MyProject.Database/MyProject.Database.csproj'
62
+ db.scripts_dir = '_Scripts'
63
+ end
64
+ end
65
+ ```
66
+
67
+ Here we are telling Physique:
68
+
69
+ * We will be managing a database named 'MyDatabase' on the '(local)' instance.
70
+
71
+ These settings can be overridden when the DATABASE_NAME and DATABASE_INSTANCE variables are present. This is particularly useful when incorporating Physique into your continuous integration or automated deployment process.
72
+
73
+ * The path to the project file where are migrations will be implemented.
74
+
75
+ * The folder within the migrations project that contains our workflow scripts.
76
+
77
+ ## FluentMigrator Tasks
78
+
79
+ Now we can run `bundle exec rake -T` to examine the tasks Physique has created for us. It should look something like this:
80
+
81
+ ```
82
+ rake compile # Builds the solution
83
+ rake compile:build # Builds the solution using the Bu...
84
+ rake compile:clean # Builds the solution using the Cl...
85
+ rake compile:rebuild # Builds the solution using the Re...
86
+ rake db:create # Create the database
87
+ rake db:drop # Drop the database
88
+ rake db:migrate # Migrate database to the latest v...
89
+ rake db:new_migration[name,description] # Create a new migration file with...
90
+ rake db:rebuild # Drop and recreate the database
91
+ rake db:rollback # Rollback the database to the pre...
92
+ rake db:seed # Seed the database with test data
93
+ rake db:setup # Create the database and run all ...
94
+ rake db:try # Migrate and then immediately rol...
95
+ rake restore # Restores all nugets as per the p...
96
+ rake test # Run unit tests
97
+ ```
98
+
99
+ Look at all of our shiny database tasks!
100
+
101
+ In case it wasn't obvious, all of the FluentMigrator tasks are prefixed with `db`. Here's a break down of each task does.
102
+
103
+ ### Basic Tasks
104
+
105
+ * `db:create` - Creates the database.
106
+ * `db:drop` - Drops the database.
107
+ * `db:seed` - Seeds the database with test data.
108
+
109
+ As you might have guessed, these three tasks simply execute the SQL scripts in your project's `_Scripts` folder. You probably won't call these directly too often but they are required by the other tasks.
110
+
111
+ If you don't create these files in your project, FluentMigrator will provide a default implementation for you. However, it's recommended that you create the scripts so that you have fine grained control over these steps.
112
+
113
+ #### A Note About Seed Data
114
+
115
+ The seed script is the place for you to place all of the test data you will need for local development. It's also a great way to provide a consistent set of test data that can be used during integration testing.
116
+
117
+ ### Migration Tasks
118
+
119
+ * `db:migrate` - Builds the migrations DLL and migrates the database to the latest version.
120
+ * `db:rollback` - Builds the migrations DLL and rolls back the most recent migration.
121
+ * `db:try` - A `db:migrate` followed by a `db:rollback`. With this task, you can test a migration that you are working on, then roll it back so that you can continue to add to it.
122
+
123
+ One of the more annoying things I run into when developing migrations is forgetting to build my migrations project before attempting to migrate the database. Physique will make sure the migrations assembly is built before running it.
124
+
125
+ ### Build Tasks
126
+
127
+ * `db:setup` - This task creates the DB, migrates it to the latest version, and executes the seed script to populate it with test data.
128
+ * `db:rebuild` - Drops the database, then executes a `db:setup`. This task is useful in your Continuous Integration process for testing the integrity of your migrations.
129
+
130
+ ### New Migration Task
131
+
132
+ * `db:new_migration[name,description]` - Creates a new migration class and adds it to the migrations project. We'll talk more about this in the following section.
133
+
134
+ ## Developer Workflow
135
+
136
+ ### Starting Fresh
137
+
138
+ Let's say I'm a new developer and it's my first day on the job working on an existing project. The team I joined (in their infinite wisdom) is using Physique to manage their build process. The first thing I want to do is checkout the source, build it, build all of the databases locally and then run all of the unit tests to make sure my local copy is configured correctly.
139
+
140
+ Assuming I have ruby installed on my machine, all I need to do is run the following:
141
+
142
+ ```
143
+ $ git checkout repo-url
144
+ $ bundle install
145
+ $ bundle exec rake test
146
+ ```
147
+
148
+ Thats it!
149
+
150
+ "But I didn't run any of the database tasks," you might be asking. That's true. And therein lies the power behind Physique's build phases. When you configure a migrations project in Physique, the `db:rebuild` step is automatically registered as a dependency of the `test` phase of the build. So when you run your tests, all of your databases are built too.
151
+
152
+ There will be times when you will want to delete and rebuild your local databases: for example, if there were data model changes since your last pull, or if you were experimenting with some db changes on one branch, and need to switch to a different branch to work on something new.
153
+
154
+ To rebuild the databases:
155
+
156
+ ```
157
+ bundle exec rake db:rebuild
158
+ ```
159
+
160
+ ### Creating a New Migration
161
+
162
+ To create a new migration inside your project, run the following:
163
+
164
+ ```
165
+ rake db:new_migration[migration_name,"migration description"]
166
+ ```
167
+
168
+ This will create a new FluentMigrator class and add it to the migrations project. It will automatically add a timestamp to the filename and `MigrationAttribute` to ensure that your migrations are run in sequential order and don’t conflict with anyone else on your team.
169
+
170
+ NOTE: Because this task actually edits the project file, you should make sure that all of your changes are saved to disk before running it.
171
+
172
+ As you can see this task takes a few parameters.
173
+
174
+ * `migration_name` - This is the name of the Migration class you want to create.
175
+ * `migration_description` - (Optional) A description that will be stored in the VersionInfo table after the migration is applied.
176
+
177
+ As a hypothetical example, let’s say we wanted to create a new migration to add a new status column to our Order table. The command might look something like this.
178
+
179
+ ```
180
+ rake db:new_migration[AddStatusToOrder, "Add a new status column to the order table"]
181
+ ```
182
+
183
+ After running this task, the IDE will alert you that the project file has been modified. Select Reload and you should see the new migration in the Migrations folder. At this point, all that’s left to do is add your migration code to the `Up` method.
184
+
185
+ ### Running Your Migrations
186
+
187
+ After creating a new migration, you will want to apply it to your local database. Unsurprisingly, this is done by running:
188
+
189
+ ```
190
+ bundle exec rake db:migrate
191
+ ```
192
+
193
+ This will execute any migrations that have not yet been applied.
194
+
195
+ If you want to rollback the last migration applied, the following command will do the trick.
196
+
197
+ ```
198
+ bundle exec rake db:rollback
199
+ ```
200
+
201
+ It’s common (at least for me) that while you are working on a migration, you might want to test it then continue working on it. Physique provides a convenience task that will run a migration, then immediately roll it back so that you can continue modifying it.
202
+
203
+ ```
204
+ bundle exec rake db:try
205
+ ```
206
+
207
+ ## Working With Multiple Databases
208
+
209
+ Physique also supports solutions with multiple migrations projects. To configure multiple databases, simply add the migrations projects to your `Rakefile`. In this hypothetical example, I have configured two migrations projects for a client and server database.
210
+
211
+ ```ruby
212
+ Physique::Solution.new do |s|
213
+ #...
214
+ s.fluently_migrate do |db|
215
+ db.task_alias = 'client'
216
+ db.instance = ENV['DATABASE_SERVER'] || '(local)'
217
+ db.name = ENV['DATABASE_NAME_CLIENT'] || 'MyClientDatabase'
218
+ db.project = 'src/MyProject.Client.Database/MyProject.Client.Database.csproj'
219
+ db.scripts_dir = '_Scripts'
220
+ end
221
+
222
+ s.fluently_migrate do |db|
223
+ db.task_alias = 'server'
224
+ db.instance = ENV['DATABASE_SERVER'] || '(local)'
225
+ db.name = ENV['DATABASE_NAME_SERVER'] || 'MyServerDatabase'
226
+ db.project = 'src/MyProject.Server.Database/MyProject.Server.Database.csproj'
227
+ db.scripts_dir = '_Scripts'
228
+ end
229
+ end
230
+ ```
231
+
232
+ A couple of things to note here:
233
+
234
+ * I have specified a task alias for each migrations project. This alias will be used when constructing your rake task names. If no alias is provided, the database name is used.
235
+ * I have added some additional environment variables to override the target database server from my continuous integration or deployment builds.
236
+
237
+ Running `bundle exec rake -T` will now yield:
238
+
239
+ ```
240
+ rake compile # Builds the solution
241
+ rake compile:build # Builds the solution using...
242
+ rake compile:clean # Builds the solution using...
243
+ rake compile:rebuild # Builds the solution using...
244
+ rake db:client:create # Create the database
245
+ rake db:client:drop # Drop the database
246
+ rake db:client:migrate # Migrate database to the l...
247
+ rake db:client:new_migration[name,description] # Create a new migration fi...
248
+ rake db:client:rebuild # Drop and recreate the dat...
249
+ rake db:client:rollback # Rollback the database to ...
250
+ rake db:client:seed # Seed the database with te...
251
+ rake db:client:setup # Create the database and r...
252
+ rake db:client:try # Migrate and then immediat...
253
+ rake db:create # Create all databases
254
+ rake db:drop # Drop all databases
255
+ rake db:migrate # Migrates all databases to...
256
+ rake db:rebuild # Drop and recreate all dat...
257
+ rake db:seed # Seed all databases with t...
258
+ rake db:server:create # Create the database
259
+ rake db:server:drop # Drop the database
260
+ rake db:server:migrate # Migrate database to the l...
261
+ rake db:server:new_migration[name,description] # Create a new migration fi...
262
+ rake db:server:rebuild # Drop and recreate the dat...
263
+ rake db:server:rollback # Rollback the database to ...
264
+ rake db:server:seed # Seed the database with te...
265
+ rake db:server:setup # Create the database and r...
266
+ rake db:server:try # Migrate and then immediat...
267
+ rake db:setup # Build all databases and m...
268
+ rake restore # Restores all nugets as pe...
269
+ rake test # Run unit tests
270
+ ```
271
+
272
+ We now have tasks that operate on each database individually as well as tasks that operate on all databases at once.
273
+
274
+ ### Database Specific Tasks
275
+
276
+ The naming convention for db specific tasks is `db:{db_alias}:{task}`. In this example, if you wanted to rebuild just the client database, you would run the following:
277
+
278
+ ```
279
+ bundle exec rake db:client:rebuild
280
+ ```
281
+
282
+ Some tasks, like `rollback` and `new_migration` only make sense in the context of a specific database, so remember to add the alias to your task name when running them.
283
+
284
+ ```
285
+ bundle exec rake db:client:rollback
286
+ ```
287
+
288
+ ### Global Tasks
289
+
290
+ The following tasks operate on all databases at once.
291
+
292
+ * `db:create` - Create all databases.
293
+ * `db:drop` - Drop all databases.
294
+ * `db:seed` - Seed all databases with test data.
295
+ * `db:migrate` - Migrate all databases to the latest version.
296
+ * `db:setup` - Create all databases, migrate them to the latest version and populate them with seed data.
297
+ * `db:rebuild` - Drop and setup all databases.
298
+
299
+ ## Happy Migrating!
300
+
301
+ At this point you should be a Physique migration pro! Feel free to contact me [@scardetto](https://twitter.com/scardetto) if you have any questions.
@@ -1,11 +1,12 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- physique (0.3.3)
4
+ physique (0.3.4)
5
5
  activesupport (~> 4.1)
6
6
  albacore (~> 2.3)
7
7
  map (~> 6.5)
8
8
  rake (~> 10)
9
+ semver2 (~> 3.4)
9
10
 
10
11
  GEM
11
12
  remote: https://rubygems.org/
data/README.md CHANGED
@@ -1,36 +1,359 @@
1
- # physique
1
+ # Physique - Beautiful builds for .NET
2
2
 
3
- Beautiful builds for .NET
3
+ Physique is an opinionated build framework that allows you to create a professional build process for your solution with minimal configuration. You tell physique a little about your solution, and it creates a complete set of rake tasks to build, test and package your apps for deployment.
4
4
 
5
- ## Installation
5
+ ## Features
6
6
 
7
- Add this line to your application's Gemfile:
7
+ * Integrates with any unit testing framework. Provides built in support for [NUnit](http://www.nunit.org/) and [NSpec](http://nspec.org/).
8
+ * Support for packaging and publishing your assemblies as NuGet packages.
9
+ * Provides powerful developer workflow tools when paired with [FluentMigrator](https://github.com/schambers/fluentmigrator).
10
+ * Built-in support for packaging and publishing applications to [Octopus Deploy](https://octopusdeploy.com/)
11
+ * Built on top of [Albacore](http://github.com/Albacore/albacore) which provides a rich suite of build tools to support any project.
12
+ * Actively maintained with several companies using it in production.
8
13
 
9
- gem 'physique'
14
+ ## Getting Started with Physique
10
15
 
11
- And then execute:
16
+ ### Installing Ruby
12
17
 
13
- $ bundle
18
+ You will need to [install Ruby](RUBY_SETUP.md) on your workstation and build servers.
14
19
 
15
- Or install it yourself as:
20
+ ### Project Structure
16
21
 
17
- $ gem install physique
22
+ Physique was designed to minimize the amount of ceremony in defining a build process. It uses a set of practical conventions that when followed, eliminate most of the configuration required to set up your builds.
18
23
 
19
- ## Usage
24
+ Out of the box, Physique expects your repo to look something like this:
20
25
 
21
- In your project's Rakefile:
26
+ ├─ build # Compiled files
27
+ │ └─ packages # Compiled packages will be built here.
28
+ ├─ docs # Documentation files
29
+ ├─ lib # Included libraries
30
+ ├─ src # Source folder
31
+ │ ├─ packages # Nuget restore location
32
+ │ ├─ .nuget # Nuget files
33
+ │ │ └─ nuget.exe # Nuget executable
34
+ │ ├─ YourProject # Project folder
35
+ │ │ └─ YourProject.csproj # Project file
36
+ │ ├─ YourProject.Tests # Test Project folder
37
+ │ │ └─ YourProject.Tests.csproj # Test Project file
38
+ │ └─ YourProject.sln # Solution file
39
+ ├─ tools # Tools and utilities
40
+ └─ README.md
41
+
42
+ If your project doesn't look anything like this, don't worry, you can customize any of the conventions to match the structure of your solution.
43
+
44
+ ### Preparing Your Project
45
+
46
+ * Open a command prompt and `cd` to the root of your repo.
47
+
48
+ * Create a `Gemfile` in the root and add the following:
49
+
50
+ ```ruby
51
+ source 'https://rubygems.org/'
52
+
53
+ gem 'physique', '~> 0.3'
54
+ ```
55
+
56
+ * Install the Bundler gem and install the required Ruby gems
57
+
58
+ ```
59
+ $ gem install bundler
60
+ $ bundle install
61
+ ```
62
+
63
+ * Physique uses the [semver2](https://github.com/haf/semver) gem to manage the version your solution. Use the included command line tool to create a `.semver` file for the solution.
64
+
65
+ ```
66
+ $ bundle exec semver init
67
+ ```
68
+
69
+ * Create a `Rakefile` in the root and add the following:
70
+
71
+ ```ruby
72
+ require 'physique'
73
+
74
+ Physique::Solution.new do |s|
75
+ s.file = 'src/YourSolution.sln'
76
+ end
77
+ ```
78
+
79
+ * If everything is set up correctly you should be able to run the following and see a list of tasks that Physique has created for you.
80
+
81
+ ```
82
+ $ bundle exec rake --tasks
83
+
84
+ rake compile # Builds the solution
85
+ rake compile:build # Builds the solution using the Build target
86
+ rake compile:clean # Builds the solution using the Clean target
87
+ rake compile:rebuild # Builds the solution using the Rebuild target
88
+ rake restore # Restores all nugets as per the packages.config files
89
+ rake test # Run unit tests
90
+ ```
91
+
92
+ * Now you can run your rake tasks. For example, to compile your solution, run the following:
93
+
94
+ ```
95
+ $ bundle exec rake compile
96
+ ```
97
+
98
+ ## The Default Build Process
99
+
100
+ Physique's default build process consists of the following phases:
101
+
102
+ 1. `version` - Determines the version of the build.
103
+ 2. `restore` - Scans your repo for `packages.config` files and downloads the discovered packages to the Nuget restore location.
104
+ 3. `compile` - Runs MSBuild on your solution file.
105
+ 4. `test` - Scans your repo for test assemblies and runs all tests.
106
+ 5. `package` - Packages your apps and/or assemblies for deployment.
107
+ 6. `publish` - Publishes your packages to a Nuget repository.
108
+
109
+ Each phase depends on the ones before it. This means when you run the tests, Physique will run the `restore` and `compile` tasks to ensure you your assemblies are up to date. In addition, you can register custom tasks to run at the different phases of the build process.
110
+
111
+ ## Customizing Your Build
112
+
113
+ Physique provides several customizations to tailor your build to your needs. You configure these options in your `Rakefile` which is just a Ruby code file. Having the full power of the Ruby programming language at your disposal to define your builds is one of the best features of rake, and by extension Physique, over XML-based tools like NAnt or MSBuild. If you don't know Ruby, never fear, Physique's configuration syntax is straightforward enough for any .NET developer to pick up quickly.
114
+
115
+ The following describes the available configuration options. Unless otherwise specified, these examples show the default values.
116
+
117
+ ### NuGet Configuration
118
+
119
+ You can customize how NuGet packages are handled in your solution.
22
120
 
23
121
  ```ruby
24
- require 'physique'
122
+ Physique::Solution.new do |s|
123
+ s.file = 'src/YourSolution.sln'
124
+
125
+ s.use_nuget do |n|
126
+ n.exe = 'src/.nuget/NuGet.exe' # Path to the NuGet executable
127
+ n.restore_location = 'src/packages' # NuGet package restore location
128
+ n.build_location = 'build/packages' # Output folder for built NuGet packages
129
+ end
130
+ end
131
+ ```
132
+
133
+ ### Compilation Configuration
25
134
 
135
+ You can customize MSBuild configuration and targets.
136
+
137
+ ```ruby
26
138
  Physique::Solution.new do |s|
27
- s.file = 'src/your-solution.sln'
139
+ s.file = 'src/YourSolution.sln'
140
+
141
+ s.compilation do |c|
142
+ c.default_targets = ['Clean', 'Rebuild'] # The default targets executed by the 'compile' task
143
+ c.configuration = 'Release' # The build configuration
144
+ c.logging = 'normal' # MSBuild logging level
145
+ end
146
+ end
147
+ ```
148
+
149
+ If you have custom MSBuild targets you can tell Physique about them.
150
+
151
+ ```ruby
152
+ s.compilation do |c|
153
+ c.add_target 'Custom'
28
154
  end
29
155
  ```
30
156
 
31
- To view the available `rake` tasks:
157
+ Physique will then add a rake task for each target which you can call from the command line.
158
+
159
+ ```
160
+ $ bundle exec rake compile:custom
161
+ ```
162
+
163
+ By default, Physique will create additional tasks for the Clean, Build and Rebuild targets.
164
+
165
+ ### Unit Testing Configuration
166
+
167
+ To execute your tests, Physique will look for the test runner executable in the NuGet restore location at runtime. If multiple versions are available, the latest version will be used. Make sure that you include the NuGet package for the test runner in a `packages.config` file somewhere in your solution.
168
+
169
+ Physique supports NUnit by default, but also has built in support for NSpec. Each of these test runners have their own defaults. If you are using something different, it's easy to provide a custom configuration.
170
+
171
+ #### NUnit Configuration
172
+
173
+ Since NUnit is the default, no additional configuration is required to use it. Physique will automatically find and run any assembly ending in ".Tests".
174
+
175
+ To tweak this behavior, you have the following configuration options:
176
+
177
+ ```ruby
178
+ Physique::Solution.new do |s|
179
+ s.file = 'src/YourSolution.sln'
180
+
181
+ s.run_tests do |t|
182
+ # Find all assemblies ending in '.Tests'
183
+ t.files = FileList["**/*.Tests/bin/#{configuration}/*.Tests.dll"]
184
+
185
+ # Default command line args
186
+ t.parameters = ['/labels', '/trace=Verbose']
187
+ end
188
+ end
189
+ ```
190
+
191
+ #### NSpec Configuration
192
+
193
+ With the NSpec runner configured, Physique will automatically find and run any assembly ending in ".Specs".
194
+
195
+ Like wth NUnit, you have the following configuration options. Note the runner must be set to `:nspec`.
196
+
197
+ ```ruby
198
+ Physique::Solution.new do |s|
199
+ s.file = 'src/YourSolution.sln'
200
+
201
+ s.run_tests do |t|
202
+ t.runner = :nspec
203
+
204
+ # The default method for finding NSpec assemblies
205
+ t.files = FileList["**/*.Specs/bin/#{configuration}/*.Specs.dll"]
206
+
207
+ # You can add additional command line args
208
+ t.parameters = ['--failfast']
209
+ end
210
+ end
211
+ ```
212
+
213
+ #### Custom Configuration
214
+
215
+ You can use any unit testing framework. You just need to provide a bit more configuration.
216
+
217
+ ```ruby
218
+ s.run_tests do |t|
219
+ t.runner = :custom
220
+
221
+ # Specify the test runner
222
+ t.exe = 'root-relative-path/to/the/test-runner.exe'
223
+
224
+ # Specify the test assemblies
225
+ t.files = FileList["**/*.Tests/bin/#{configuration}/*.Tests.dll"]
226
+
227
+ # Specify additional command line args
228
+ t.parameters = ['/option1', '/option2']
229
+ end
230
+ ```
231
+
232
+ ### NuGet Publishing Configuration
233
+
234
+ Physique provides an easy way to publish your NuGet packages to public or private Nuget repos. Each assembly in your solution will be published as a separate NuGet package with the correct dependencies.
235
+
236
+ ```ruby
237
+ Physique::Solution.new do |s|
238
+ s.file = 'src/YourSolution.sln'
239
+
240
+ s.publish_nugets do |p|
241
+ # The NuGet repo you want to publish to
242
+ p.feed_url = 'https://www.nuget.org'
243
+
244
+ # The NuGet repo for your symbol package (Optional)
245
+ p.symbols_feed_url = 'http://nuget.gw.symbolsource.org/Public/NuGet'
246
+
247
+ # The API key to authenticate to the repo.
248
+ # If your source code is public, make sure to pass this in as an environment variable.
249
+ p.api_key = ENV['NUGET_API_KEY']
250
+
251
+ # Metadata to be included in your Nuspec
252
+ p.with_metadata do |m|
253
+ m.description = 'Common libraries for crux applications'
254
+ m.authors = 'Robert Scaduto, Leo Hernandez'
255
+ end
256
+ end
257
+ end
258
+ ```
259
+
260
+ When you configure NuGet publishing, the `package` and `publish` tasks become available.
261
+
262
+ ```
263
+ $ bundle exec rake --tasks
264
+ ...
265
+ rake nuget:package # Package all NuGets
266
+ rake nuget:publish # Publish nuget packages to feed
267
+ rake nuget:publish:local # Copy nuget packages to local path
268
+ ...
269
+ ```
270
+
271
+ ## Third Party Tools
272
+
273
+ ### FluentMigrator Configuration
274
+
275
+ If you are using FluentMigrator to manage your databases, Physique can create several useful tasks to improve your development workflow. Simply tell Physique where your migrations project is located and it will take care of the rest.
276
+
277
+ ```ruby
278
+ Physique::Solution.new do |s|
279
+ s.file = 'src/YourSolution.sln'
280
+
281
+ s.fluently_migrate do |db|
282
+ db.instance = '(local)'
283
+ db.name = 'MyDatabase'
284
+ db.project = 'src\MyProject.Database\MyProject.Database.csproj'
285
+ end
286
+ end
287
+ ```
288
+
289
+ Currently Physique only works with SQL Server, but support for additional databases is planned.
290
+
291
+ For more information, see [Using Physique with Fluent Migrator](FLUENT_MIGRATOR.md)
292
+
293
+ ### Octopus Deploy Configuration
294
+
295
+ If you are deploying your applications with Octopus Deploy, Physique allows you to package and publish your applications without needing to modify your project file.
296
+
297
+ ```ruby
298
+ Physique::Solution.new do |s|
299
+ s.file = 'src/YourSolution.sln'
300
+
301
+ s.octopus_deploy do |octo|
302
+ # Octopus Deploy server's NuGet feed URL
303
+ octo.server = 'http://octopus-deploy-server/nuget/packages'
304
+
305
+ # Octopus Deploy API key
306
+ # For security it's a good idea to pass this in as an environment variable.
307
+ octo.api_key = ENV['OCTOPUS_API_KEY']
308
+
309
+ # You can specify multiple apps to deploy
310
+
311
+ # A hypothetical web application
312
+ octo.deploy_app do |app|
313
+ # App name for rake tasks
314
+ app.name = 'web'
315
+
316
+ # App type
317
+ # Valid options include :service, :website, :console
318
+ app.type = :website
319
+
320
+ # App project file
321
+ app.project = 'src/MyProject.Website/MyProject.Website.csproj'
322
+
323
+ # Nuspec metadata for your application
324
+ app.with_metadata do |m|
325
+ m.description = 'My Web Application'
326
+ m.authors = 'My Company, Inc.'
327
+ end
328
+ end
329
+ end
330
+ end
331
+ ```
332
+
333
+ When you configure Octopus deployments, the `octo:package` and `octo:publish` tasks become available.
334
+
335
+ The following tasks would be available with the configuration above:
336
+
337
+ ```
338
+ $ bundle exec rake --tasks
339
+ ...
340
+ rake octo:package # Package all applications
341
+ rake octo:package:web # Package MyProject.Website for Oct...
342
+ rake octo:publish # Publish all apps to Octopus ...
343
+ rake octo:publish:web # Publish MyProject.Website app to ...
344
+ ...
345
+ ```
346
+
347
+ ## Roadmap
348
+
349
+ * Add conventions for more unit test frameworks.
350
+ * Add support for additional databases.
351
+ * Optionally use [Packet](https://github.com/fsprojects/Paket) instead of NuGet during `restore` phase
352
+ * Mono support is possible but completely untested.
353
+
354
+ ## Support
32
355
 
33
- $ rake --tasks
356
+ Feel free to contact me [@scardetto](https://twitter.com/scardetto) if you have any questions.
34
357
 
35
358
  ## Contributing
36
359