<commit_before>//
//  Formatting.swift
//  Carthage
//
//  Created by <NAME> on 1/29/15.
//  Copyright (c) 2015 Carthage. All rights reserved.
//

import Commandant
import Foundation
import LlamaKit
import PrettyColors
import ReactiveCocoa

extension Color.Wrap {
	func autowrap(string: String) -> String {
		return ColorOptions.colorful ? wrap(string) : string
	}
}

internal struct Formatting {

	static let bulletin = Color.Wrap(foreground: .Blue, style: .Bold)
	static let bullets: String = {
		return bulletin.autowrap("***") + " "
	}()
	
	static let URL = Color.Wrap(styles: .Underlined)
	static let projectName = Color.Wrap(styles: .Bold)
	static let path = Color.Wrap(foreground: .Yellow)
	
	static func quote(string: String, quotationMark: String = "\"") -> String {
		return Color.Wrap(foreground: .Green).autowrap(quotationMark + string + quotationMark)
	}
	
}

internal struct Terminal {
	static let term: String? = getEnvironmentVariable("TERM").value()
	static let isDumb: Bool = (Terminal.term?.lowercaseString as NSString?)?.isEqualToString("dumb") ?? false
	static let isTTY: Bool = isatty(STDOUT_FILENO) == 1
}

public enum ColorArgument: String, ArgumentType {
	case Auto = "auto"
	case Never = "never"
	case Always = "always"
	
	public var isColorful: Bool {
		switch self {
		case .Always:
			return true
		case .Never:
			return false
		case .Auto:
			return Terminal.isTTY && !Terminal.isDumb
		}
	}
	
	public static let name = "color"
	
	public static func fromString(string: String) -> ColorArgument? {
		return self(rawValue: string.lowercaseString)
	}
	
}

public struct ColorOptions: OptionsType {
	public let argument: ColorArgument
	
	static var colorful: Bool {

		if let colorful = Static.colorful {
			return colorful
		} else {
			var arguments = Process.arguments
			assert(arguments.count >= 1)
			
			// Remove the executable name.
			arguments.removeAtIndex(0)
			
			switch ColorOptions.evaluate(.Arguments(ArgumentParser(arguments))) {
			case .Success(let options):
				return options.unbox.argument.isColorful
			case .Failure(let error):
				fatalError(error.description)
			}

		}
	}

	private struct Static {
		static var colorful: Bool? = nil
		static var token: dispatch_once_t = 0
	}
	
	public static func create(argument: ColorArgument) -> ColorOptions {
		dispatch_once(&Static.token) { Static.colorful = argument.isColorful }
		return self(argument: argument)
	}
	
	public static func evaluate(m: CommandMode) -> Result<ColorOptions> {
		return create
			<*> m <| Option(key: "color", defaultValue: ColorArgument.Auto, usage: "Terminal coloring and styling — values: ‘auto’ || ‘always’ || ‘never’")
	}
}<commit_msg>Comment on rareness of `fatalError`.<commit_after>//
//  Formatting.swift
//  Carthage
//
//  Created by <NAME> on 1/29/15.
//  Copyright (c) 2015 Carthage. All rights reserved.
//

import Commandant
import Foundation
import LlamaKit
import PrettyColors
import ReactiveCocoa

extension Color.Wrap {
	func autowrap(string: String) -> String {
		return ColorOptions.colorful ? wrap(string) : string
	}
}

internal struct Formatting {

	static let bulletin = Color.Wrap(foreground: .Blue, style: .Bold)
	static let bullets: String = {
		return bulletin.autowrap("***") + " "
	}()
	
	static let URL = Color.Wrap(styles: .Underlined)
	static let projectName = Color.Wrap(styles: .Bold)
	static let path = Color.Wrap(foreground: .Yellow)
	
	static func quote(string: String, quotationMark: String = "\"") -> String {
		return Color.Wrap(foreground: .Green).autowrap(quotationMark + string + quotationMark)
	}
	
}

internal struct Terminal {
	static let term: String? = getEnvironmentVariable("TERM").value()
	static let isDumb: Bool = (Terminal.term?.lowercaseString as NSString?)?.isEqualToString("dumb") ?? false
	static let isTTY: Bool = isatty(STDOUT_FILENO) == 1
}

public enum ColorArgument: String, ArgumentType {
	case Auto = "auto"
	case Never = "never"
	case Always = "always"
	
	public var isColorful: Bool {
		switch self {
		case .Always:
			return true
		case .Never:
			return false
		case .Auto:
			return Terminal.isTTY && !Terminal.isDumb
		}
	}
	
	public static let name = "color"
	
	public static func fromString(string: String) -> ColorArgument? {
		return self(rawValue: string.lowercaseString)
	}
	
}

public struct ColorOptions: OptionsType {
	public let argument: ColorArgument
	
	static var colorful: Bool {

		if let colorful = Static.colorful {
			return colorful
		} else {
			var arguments = Process.arguments
			assert(arguments.count >= 1)
			
			// Remove the executable name.
			arguments.removeAtIndex(0)
			
			switch ColorOptions.evaluate(.Arguments(ArgumentParser(arguments))) {
			case .Success(let options):
				return options.unbox.argument.isColorful
			case .Failure(let error):
				// Most likely an illegal value for `--color`.
				fatalError(error.description)
			}

		}
	}

	private struct Static {
		static var colorful: Bool? = nil
		static var token: dispatch_once_t = 0
	}
	
	public static func create(argument: ColorArgument) -> ColorOptions {
		dispatch_once(&Static.token) { Static.colorful = argument.isColorful }
		return self(argument: argument)
	}
	
	public static func evaluate(m: CommandMode) -> Result<ColorOptions> {
		return create
			<*> m <| Option(key: "color", defaultValue: ColorArgument.Auto, usage: "Terminal coloring and styling — values: ‘auto’ || ‘always’ || ‘never’")
	}
}
{'fraction_non_alphanumeric': 0.11431742508324085, 'fraction_numerical': 0.004809470958194599, 'mean_word_length': 3.893212669683258, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6865244', 'n_tokens_mistral': 1882, 'n_tokens_neox': 1649, 'n_words': 481}