1 /** 2 Copyright: Copyright (c) 2017, Joakim Brännström. All rights reserved. 3 License: MPL-2 4 Author: Joakim Brännström (joakim.brannstrom@gmx.com) 5 6 This Source Code Form is subject to the terms of the Mozilla Public License, 7 v.2.0. If a copy of the MPL was not distributed with this file, You can obtain 8 one at http://mozilla.org/MPL/2.0/. 9 10 This file contains the integration needed for using dfmt to format D code. 11 */ 12 module autoformat.format_d; 13 14 import std.algorithm; 15 import std.array; 16 import std.exception; 17 import std.file; 18 import std.string : join; 19 import std.process; 20 import logger = std.experimental.logger; 21 22 import std.typecons : Flag; 23 24 import autoformat.types; 25 26 private immutable string[] dfmtConf = import("dfmt.conf").splitter("\n") 27 .filter!(a => a.length > 0).array(); 28 29 // Thread local optimization that reduced the console spam when the program 30 // isn't installed. 31 bool installed = true; 32 33 // TODO dry_run not supported. 34 auto runDfmt(AbsolutePath fname, Flag!"backup" backup, Flag!"dryRun" dry_run) nothrow { 35 if (dry_run || !installed) { 36 return FormatterResult(Unchanged.init); 37 } 38 39 string[] opts = dfmtConf.map!(a => a.idup).array(); 40 41 auto rval = FormatterResult(FormatError.init); 42 43 try { 44 if (backup) { 45 copy(fname, fname.toString ~ ".orig"); 46 } 47 48 auto arg = ["dfmt"] ~ opts ~ [cast(string) fname]; 49 logger.trace(arg.join(" ")); 50 auto res = execute(arg); 51 logger.trace(res.output); 52 53 rval = FormatterResult(FormattedOk.init); 54 } catch (ProcessException ex) { 55 // dfmt isn't installed 56 rval = FormatterResult(FailedWithUserMsg(ex.msg)); 57 installed = false; 58 } catch (Exception ex) { 59 rval = FormatterResult(FailedWithUserMsg(ex.msg)); 60 } 61 62 return rval; 63 }