-
Notifications
You must be signed in to change notification settings - Fork 14
Address #27 from fsprojects/Projekt #32
base: master
Are you sure you want to change the base?
Changes from 3 commits
90deb10
fe6cac8
0d80ce1
048f0bb
721a559
0a75b69
4acc5d8
cee9d36
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,111 +1,90 @@ | ||
module Projekt.Args | ||
|
||
open Projekt.Types | ||
open System.IO | ||
open Nessos.UnionArgParser | ||
|
||
type private Args = | ||
| Template of string | ||
| [<AltCommandLine("-fxv")>] FrameworkVersion of string | ||
| Organisation of string | ||
| Direction of string | ||
| Repeat of int | ||
| Link of string | ||
| Compile of bool | ||
with | ||
interface IArgParserTemplate with | ||
member s.Usage = | ||
match s with | ||
| Template _ -> "init -- specify the template (library|console) [default: library]" | ||
| Direction _ -> "movefile -- specify the direction (down|up)" | ||
| Repeat _ -> "movefile -- specify the distance [default: 1]" | ||
| FrameworkVersion _ -> "init -- specify the framework version (4.0|4.5|4.5.1) [default: 4.5]" | ||
| Organisation _ -> "init -- specify the organisation" | ||
| Link _ -> "addfile -- specify an optional Link attribute" | ||
| Compile _ -> "addfile -- should the file be compiled or not [default: true]" | ||
module Args = | ||
open CommandLine | ||
|
||
let private templateArg (res : ArgParseResults<Args>) = | ||
match res.TryGetResult(<@ Template @>) with | ||
| Some (ToLower "console") -> Console | ||
| Some (ToLower "library") -> Library | ||
| None -> Library | ||
| _ -> failwith "invalid template argument specified" | ||
[<Verb("init", HelpText = "create a new project")>] | ||
type public InitOptions = | ||
{ [<Value(0, Required = true, MetaName = "project path")>] path : string | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. strictly speaking it should be a single space after { and record field names should not be lined up (personally don't care so much about the last one) Record field names should be PascalCased There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. also thanks! |
||
[<Option(Default = "library")>] template : string | ||
[<Option(Default = "4.5")>] frameworkVersion : string | ||
[<Option>] organization : string option } | ||
with | ||
member x.ToOperation = | ||
match x.path with | ||
| FullPath p -> | ||
let template = x.template |> Template.Create |> Some | ||
let frmwkVersion = x.frameworkVersion |> FrameworkVersion.Create |> Some | ||
(ProjectInitData.create | ||
p | ||
template | ||
frmwkVersion | ||
x.organization) |> Init | ||
|
||
let private frameworkVersionArg (res : ArgParseResults<Args>) = | ||
match res.TryGetResult(<@ FrameworkVersion @>) with | ||
| Some "4.0" -> V4_0 | ||
| Some "4.5" -> V4_5 | ||
| Some "4.5.1" -> V4_5_1 | ||
| None -> V4_5 | ||
| _ -> failwith "invalid framework version argument specified" | ||
| _ -> failwith "not given a full path" | ||
|
||
let private parseDirection s = | ||
match s with | ||
| ToLower "up" -> Up | ||
| ToLower "down" -> Down | ||
| _ -> failwith "invalid direction specified" | ||
[<Verb("reference", HelpText = "reference a dll")>] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Currently this verb is for referencing projects. Referencing dlls is planned: #23 (@kjnilsson you fancy it?) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'll clean that up for sure. |
||
type public ReferenceOptions = | ||
{ [<Value(0, Required = true, MetaName = "project path")>] projectPath : string | ||
[<Value(1, Required = true, MetaName = "reference path")>] referencePath : string } | ||
with | ||
member x.ToOperation = | ||
match x.projectPath, x.referencePath with | ||
| FullPath project, FullPath reference -> | ||
{ProjPath = project; Reference = reference} |> Reference | ||
| _,_ -> failwith "one or both paths were invalid" | ||
|
||
let private parser = UnionArgParser.Create<Args>() | ||
|
||
let private (|Options|) (args : string list) = | ||
let results = parser.Parse(List.toArray args) | ||
results | ||
|
||
let (|FullPath|_|) (path : string) = | ||
try | ||
Path.GetFullPath path |> Some | ||
[<Verb("movefile", HelpText = "Move a file within a project")>] | ||
type public MoveFileOptions = | ||
{ [<Value(0, Required = true, MetaName = "project path")>] projectPath : string | ||
[<Value(1, Required = true, MetaName = "file path")>] filePath : string | ||
[<Option(Required = true)>] direction : string | ||
[<Option(Default = 1)>] repeat : int } | ||
with | ||
| _ -> None | ||
|
||
let commandUsage = "projekt (init|reference|movefile|addfile|delfile|version) /path/to/project [/path/to/(file|project)]" | ||
member x.ToOperation = | ||
match x.projectPath, x.filePath, Direction.Create x.direction with | ||
| FullPath project, FullPath file, dir -> | ||
{ProjPath = project; FilePath = file; Direction = dir; Repeat = x.repeat} |> MoveFile | ||
| _,_,_ -> failwith "invalid paths or direction" | ||
|
||
let parse (ToList args) : Result<Operation> = | ||
try | ||
match args with | ||
| [] -> | ||
parser.Usage commandUsage | ||
|> Failure | ||
[<Verb("addfile", HelpText = "Add a file to a project")>] | ||
type public AddFileOptions = | ||
{ [<Value(0, Required = true, MetaName = "project path")>] projectPath : string | ||
[<Value(1, Required = true, MetaName = "file path")>] filePath : string | ||
[<Option>] link : string option | ||
[<Option(Default = true)>] compile : bool } | ||
with | ||
member x.ToOperation = | ||
match x.projectPath, x.filePath with | ||
| FullPath project, FullPath file -> | ||
{ProjPath = project; FilePath = file; Link = x.link; Compile = x.compile} |> AddFile | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this line can be shortened by putting each record field assignment on a new line. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ah, yes, of course. |
||
| _,_ -> failwith "invalid paths" | ||
|
||
| ToLower "version" :: _ -> | ||
Success Version | ||
|
||
| ToLower "init" :: FullPath path :: Options opts -> | ||
let template = templateArg opts | ||
let fxv = frameworkVersionArg opts | ||
let org = | ||
match opts.TryGetResult(<@ Organisation @>) with | ||
| Some org -> org | ||
| None -> "MyOrg" | ||
Init (ProjectInitData.create (path, template, fxv, org)) |> Success | ||
|
||
| ToLower "addfile" :: FullPath project :: FullPath file :: Options opts -> | ||
let compile = opts.GetResult(<@ Compile @>, true) | ||
AddFile { ProjPath = project | ||
FilePath = file | ||
Link = opts.TryGetResult <@ Link @> | ||
Compile = compile } | ||
|> Success | ||
|
||
| [ToLower "delfile"; FullPath project; FullPath file] -> | ||
DelFile { ProjPath = project; FilePath = file } | ||
|> Success | ||
|
||
| ToLower "movefile" :: FullPath project :: FullPath file :: Options opts | ||
when opts.Contains <@ Direction @> -> | ||
[<Verb("delfile", HelpText = "Delete a file from a project")>] | ||
type public DelFileOptions = | ||
{ [<Value(0, Required = true, MetaName = "project path")>] projectPath : string | ||
[<Value(1, Required = true, MetaName = "file path")>] filePath : string } | ||
with | ||
member x.ToOperation = | ||
match x.projectPath, x.filePath with | ||
| FullPath project, FullPath file -> | ||
// typing needed here because of the duplication between MoveFileData and DelFileData records | ||
// TODO: maybe consolidate? | ||
({ProjPath = project; FilePath = file} : DelFileData) |> DelFile | ||
| _,_ -> failwith "invalid paths" | ||
|
||
let direction = opts.PostProcessResult(<@ Direction @>, parseDirection) | ||
MoveFile { ProjPath = project | ||
FilePath = file | ||
Direction = direction | ||
Repeat = opts.GetResult(<@ Repeat @>, 1)} | ||
|> Success | ||
|
||
| [ToLower "reference"; FullPath project; FullPath reference] -> | ||
Reference { ProjPath = project; Reference = reference } |> Success | ||
let parse args = | ||
let parsed = CommandLine.Parser.Default.ParseArguments<InitOptions, ReferenceOptions, MoveFileOptions, AddFileOptions, DelFileOptions>(args) | ||
// tried to get fancy here with a statically resolved type param to invoke the ToOperation member on the individal option cases, but I couldn't get it to work.... | ||
|
||
| _ -> Failure (parser.Usage (sprintf "Error: '%s' is not a recognized command or received incorrect arguments.\n\n%s" args.Head commandUsage)) | ||
with | ||
| :? System.ArgumentException as e -> | ||
let lines = e.Message.Split([|'\n'|]) | ||
let msg = parser.Usage (sprintf "%s\n\n%s" lines.[0] commandUsage) | ||
Failure msg | ||
parsed.Return<InitOptions, ReferenceOptions, MoveFileOptions, AddFileOptions, DelFileOptions, Result<Operation>>( | ||
(fun (init : InitOptions) -> init.ToOperation |> Success), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. are the parens needed here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think they are, since this call is a C#-style method call which needs the whole batch of tupled arguments . If I remove the parens and the separating commas the call doesn't compile. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think if you leave the commas in you can remove the parens - minor detail tho :) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ah well :) On Mon, 3 Aug 2015 at 16:17 Chester Husk III [email protected]
|
||
(fun (ref : ReferenceOptions) -> ref.ToOperation |> Success), | ||
(fun (mv : MoveFileOptions) -> mv.ToOperation |> Success), | ||
(fun (add : AddFileOptions) -> add.ToOperation |> Success), | ||
(fun (del : DelFileOptions) -> del.ToOperation |> Success), | ||
(fun errs -> errs |> Seq.map (fun e -> e.ToString()) |> String.concat ";" |> Failure) | ||
) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | ||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> | ||
<PropertyGroup> | ||
|
@@ -36,30 +36,6 @@ | |
<DocumentationFile>.\bin\Release\Projekt.xml</DocumentationFile> | ||
<OtherFlags>--warnon:1182</OtherFlags> | ||
</PropertyGroup> | ||
<ItemGroup> | ||
<Reference Include="mscorlib" /> | ||
<Reference Include="FSharp.Core, Version=$(TargetFSharpCoreVersion), Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"> | ||
<Private>True</Private> | ||
</Reference> | ||
<Reference Include="System" /> | ||
<Reference Include="System.Core" /> | ||
<Reference Include="System.Numerics" /> | ||
<Reference Include="System.Xml" /> | ||
<Reference Include="System.Xml.Linq" /> | ||
</ItemGroup> | ||
<ItemGroup> | ||
<Compile Include="AssemblyInfo.fs" /> | ||
<Compile Include="Util.fs" /> | ||
<Compile Include="Types.fs" /> | ||
<Compile Include="Template.fs" /> | ||
<Compile Include="Args.fs" /> | ||
<Compile Include="XmlLinqHelpers.fs" /> | ||
<Compile Include="Project.fs" /> | ||
<Compile Include="Main.fs" /> | ||
<None Include="bootstrap.fsx" /> | ||
<None Include="paket.references" /> | ||
<None Include="paket.template" /> | ||
</ItemGroup> | ||
<PropertyGroup> | ||
<MinimumVisualStudioVersion Condition="'$(MinimumVisualStudioVersion)' == ''">11</MinimumVisualStudioVersion> | ||
</PropertyGroup> | ||
|
@@ -81,16 +57,54 @@ | |
<Target Name="BeforeBuild"> | ||
</Target> | ||
--> | ||
<ItemGroup> | ||
<Templates Include="$(SolutionDir)\templates\**\*.*"/> | ||
</ItemGroup> | ||
<Target Name="AfterBuild"> | ||
<Copy | ||
SourceFiles="@(Templates)" | ||
DestinationFolder="$(OutputPath)\templates\%(Templates.RecursiveDir)" | ||
/> | ||
<Copy SourceFiles="@(Templates)" DestinationFolder="$(OutputPath)\templates\%(Templates.RecursiveDir)" /> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The Templates ItemGroup has been removed so this doesn't work anymore. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, I had that problem with VS as well, but I don't normally use VS! I just tried splitting it into a separate file, so create a new
and use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, that worked. So this is one of those times where I begin to realize how much I don't know. Does msbuild not evaluate the Imported elements with the same level of rigor as top-level nodes? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No it absolutely does, but msbuild understands the wildcard perfectly well, I was hoping that the over-eager VS check was implemented separately. |
||
</Target> | ||
<Import Project="..\..\.paket\paket.targets" /> | ||
<ItemGroup> | ||
<Compile Include="AssemblyInfo.fs" /> | ||
<Compile Include="Util.fs" /> | ||
<Compile Include="Types.fs" /> | ||
<Compile Include="Template.fs" /> | ||
<Compile Include="Args.fs" /> | ||
<Compile Include="XmlLinqHelpers.fs" /> | ||
<Compile Include="Project.fs" /> | ||
<Compile Include="Main.fs" /> | ||
<None Include="bootstrap.fsx" /> | ||
<None Include="paket.references" /> | ||
<None Include="paket.template" /> | ||
</ItemGroup> | ||
<ItemGroup> | ||
<Reference Include="mscorlib" /> | ||
<Reference Include="FSharp.Core, Version=$(TargetFSharpCoreVersion), Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"> | ||
<Private>True</Private> | ||
</Reference> | ||
<Reference Include="System" /> | ||
<Reference Include="System.Core" /> | ||
<Reference Include="System.Numerics" /> | ||
<Reference Include="System.Xml" /> | ||
<Reference Include="System.Xml.Linq" /> | ||
</ItemGroup> | ||
<Choose> | ||
<When Condition="$(TargetFrameworkIdentifier) == '.NETFramework' And ($(TargetFrameworkVersion) == 'v4.0')"> | ||
<ItemGroup> | ||
<Reference Include="CommandLine"> | ||
<HintPath>..\..\packages\CommandLineParser\lib\net40\CommandLine.dll</HintPath> | ||
<Private>True</Private> | ||
<Paket>True</Paket> | ||
</Reference> | ||
</ItemGroup> | ||
</When> | ||
<When Condition="($(TargetFrameworkIdentifier) == '.NETFramework' And ($(TargetFrameworkVersion) == 'v4.5' Or $(TargetFrameworkVersion) == 'v4.5.1' Or $(TargetFrameworkVersion) == 'v4.5.2' Or $(TargetFrameworkVersion) == 'v4.5.3' Or $(TargetFrameworkVersion) == 'v4.6')) Or ($(TargetFrameworkIdentifier) == 'MonoAndroid') Or ($(TargetFrameworkIdentifier) == 'MonoTouch')"> | ||
<ItemGroup> | ||
<Reference Include="CommandLine"> | ||
<HintPath>..\..\packages\CommandLineParser\lib\net45\CommandLine.dll</HintPath> | ||
<Private>True</Private> | ||
<Paket>True</Paket> | ||
</Reference> | ||
</ItemGroup> | ||
</When> | ||
</Choose> | ||
<Choose> | ||
<When Condition="$(TargetFrameworkIdentifier) == '.NETFramework' And $(TargetFrameworkVersion) == 'v3.5'"> | ||
<ItemGroup> | ||
|
@@ -111,4 +125,4 @@ | |
</ItemGroup> | ||
</When> | ||
</Choose> | ||
</Project> | ||
</Project> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no need for the 'public' accessor
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks, will fix.