Gruntfile.coffee の中身をまとめてみた

<a href="http://qiita.com/wings1685/items/67446d856a10d890c650" target="_blank" title="Gruntfile.js を CoffeeScript で書いて見やすくする - Qiita">Gruntfile.js を CoffeeScript で書いて見やすくする - Qiita</a> から 1 年経っているので、新しく Gruntfile.coffee をまとめてみました。

これを設定した上で <a href="http://qiita.com/wings1685/items/c03ca0676613826ae274" target="_blank" title="grunt のインストールから初回 grunt までコマンド一発で完了させるターミナルシェルスクリプト - Qiita">grunt のインストールから初回 grunt までコマンド一発で完了させるターミナルシェルスクリプト - Qiita</a>をやると、ターミナル上で grunt.command を叩くだけで環境が整います。
# 各ファイルでやりたいこと
## Sass
1. .sass -> .css へのコンパイル（該当ファイルのみ）
2. .css の concat
3. minify

## CoffeeScript
1. .coffee -> .js へのコンパイル
2. minify

## Slim
1. HTML へのコンパイル

## HTML/Python/Ruby/YAML など
1. 正規ディレクトリへコピー

# 共通してやりたいこと
上記の個別ファイル処理後に行います。

1. sftp でアップロード
2. 処理完了音を鳴らす


```coffeescript:Gruntfile.coffee
module.exports = (grunt) ->
	pkg = grunt.file.readJSON 'package.json'
	grunt.initConfig
		compass:
			dev:
				options:
					config: 'config.rb'
					environment: 'development'
					force: true
					specify: '<%= dir.src %>'
			prod:
				options:
					config: 'config.rb'
					environment: 'production'
					force: true
		coffee:
			functions:
				files:
					'<%= dir.dest %>': '<%= dir.src %>'
		slim:
			main:
				files:
					'<%= dir.dest %>': '<%= dir.src %>'
		concat:
			main:
				files:
					'css/styles.css': ['css/reset.css', 'css/fonts.css', 'css/common.css']
		cssmin:
			common:
				files:
					'css/styles.min.css': ['css/styles.css']
			tablet:
				files:
					'css/tablet.min.css': ['css/tablet.css']
			mobile:
				files:
					'css/mobile.min.css': ['css/mobile.css']
		uglify:
			main:
				files:
					'<%= dir.dest_min %>': '<%= dir.files %>'
		copy:
			main:
				src: '<%= dir.src %>'
				dest: '<%= dir.dest %>'
		sftp:
			main:
				files:
					'./': '<%= dir.uploads %>'
				options: fx.setSftp '<%= dir.dir %>'
		play:
			main:
				file: '/System/Library/Sounds/Glass.aiff'
		esteWatch:
			options:
				dirs: ['src/**']
			'*': (file) ->
				response = fx.setTask file
				return unless response
				grunt.config.set 'dir', response.config
				response.tasks

	for t of pkg.devDependencies
		grunt.loadNpmTasks t if t.substring(0, 6) is 'grunt-'

	grunt.registerTask 'w', ['esteWatch']

class FX
	constructor: ->
		@excludes = ['.DS_Store']
		@src = 'src/'
		@sftp = {host: host, username: username, password: password, path: path}
		return

	getTarget: (file) ->
		files = file.split('/')
		{file: file, path: files.slice(1, -1).join('/'), name: String(files.slice -1), type: String(file.split('.').slice -1)}


	setTask: (file) ->
		options = @getTarget file
		return if @excludes.indexOf(options.name) > -1

		response = if @[options.type] then @[options.type] options else @common options
		response.tasks.push 'play'
		response

	common: (options) ->
		dest = options.file.substr(@src.length)
		{config: {src: options.file, dest: dest, dir: options.path, uploads: [dest]}, tasks: ['copy', 'sftp']}

	slim: (options) ->
		response = @common options
		response.config.dest = response.config.dest.replace '.slim', '.html'
		response.config.uploads = [response.config.dest]
		response.tasks[0] = 'slim'
		response

	sass: (options) ->
		target = options.name.replace '.sass', ''
		response = {config: {src: [options.file], uploads: []}, tasks: ['compass:dev']}
		if target is 'tablet' or target is 'mobile'
			response.config.uploads.push "css/#{target}.min.css"
			response.tasks.push "cssmin:#{target}"
		else if target.charAt(0) is '_'
			response.config =
				src: ['src/common.sass', 'src/tablet.sass', 'src/mobile.sass']
				uploads: ['css/styles.min.css', 'css/tablet.min.css', 'css/mobile.min.css']
			response.tasks.push 'concat', 'cssmin:common', 'cssmin:tablet', 'cssmin:mobile'
		else
			response.config.uploads.push 'css/styles.min.css'
			response.tasks.push 'concat', 'cssmin:common'
		response.config.dir = 'css'
		response.tasks.push 'sftp'
		response

	coffee: (options) ->
		response = {config: {src: options.file, dest: options.file.replace(@src, 'js/').replace('.coffee', '.js'), dir: 'js'}, tasks: ['coffee', 'uglify', 'sftp']}
		response.config.files = [response.config.dest]
		response.config.dest_min = response.config.dest.replace '.js', '.min.js'
		response.config.uploads = [response.config.dest_min]
		response

	setSftp: (dir) ->
		options = @sftp
		options.path += dir
		options.srcBasePath = dir
		options

fx = new FX()
```