Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pakets #154

Closed
bartelink opened this issue Sep 23, 2014 · 30 comments
Closed

Pakets #154

bartelink opened this issue Sep 23, 2014 · 30 comments

Comments

@bartelink
Copy link
Member

I'd like to propose a consolidated grammar for the dependencies, lock and reference files based on:

Grammars

paket.references files:

Grammar:

<PaketId>
  • Bare file with single lines, each consisting of a single Paket Id (defined later).
  • No special syntax for file sources etc. anymore

paket.lock file:

Grammar:

Sources
  <NuGetSourceName> nuget <NuGetUrl>
  <FileSourceName> github <RepoAndSubDir>
  <FileSourceName> fssnip <RepoAndSubDir> 
  <FileSourceName> local  <UncPath>

paket <PaketId> (<VerSpec>)
  frameworkAssembly <AssemblyName> 
  dependency <PaketId>
  <NuGetSourceName> <NuGetPackageId> (<VerSpec>) <DestinationPath>
  <FileSourceName> <FileName> (<Hash>)
  // Used by <PaketId> (<DepSpec>)
  • example <NuGetUrl>: http://nuget.org/api/v2
  • example <RepoAndSubDir>: forki/FsUnit
  • example <NuGetPackageId>: NUnit.Framework
  • example <AssemblyName>: System.Numerics
  • example <VerSpec>: 5.2.2
  • example <Hash>: abc12abc12abc12abc12abc12abc12
  • example <DepSpec>: (>= 5.2.2, < 5.3.0)
  • example <FileSourceName> \\MyServer\MyShare\IsReallyReliable
  • NB no split into file and non-file sections anymore
  • See separate proposal re grouping and alternate syntaxes #TBA

paket.dependencies file:

Grammar:

Sources
  <NuGetSourceName> nuget <NuGetUrl>
  <FileSourceName> github <RepoAndSubDir>
  <FileSourceName> fssnip <RepoAndSubDir> 
  <FileSourceName> local  <UncPath>

paket <PaketId>
  frameworkAssembly AssemblyName 
  dependency <PaketId> 
  <NuGetSourceName> <NuGetPackageId> [<VerSpec>]
  <FileSourceName> <FileName> [<DestinationPath>]

<NuGetSourceName> <NuGetPackageId> [<VerSpec>]

<FileSourceName> <FileName> [<DestinationPath>]

  • Examples as per dependencies file (it's just the same syntax with some elements removed

  • top level <NuGetSourceName> <NuGetPackageId> [<VerSpec>] translates to:

    paket <NuGetPackageId>
      <NuGetSourceName> <NuGetPackageId> [<VerSpec>]
    
  • top level <FileSourceName> <FileName> [<DestinationPath>] translates to:

    paket <FileName>
      <FileSourceName> <FileName> `App_Packages\<FileName>`
    
  • inside a paket <PaketId> block, <FileSourceName> <FileName> [<DestinationPath>] has the following default pattern:

    • if <DestinationPath> is not supplied, it's App_Packages\<PaketId>\<FileName>
    • see established conventions in htp://nikcodes.com/2013/10/23/packaging-source-code-with-nuget/

Notes

  • <PaketId>s are case-insensitive strings
  • the only thing that's ever referenced is a <PaketId> (which may ultimately be either a FileName or a <NuGetPackageId>
  • Could define a import paketfilepath.paket primitive which sucks in children recusively (see examples for why one might use that)
  • This ties each file/nuget package to a single source (which I think is good - I want to know where stuff comes from, and doesnt require the doc to state that sources are order-sensitive)
  • @ilkerde I will read about strict mode but to be honest I don't completely understand it and I'd like to make sure it squares well with this proposal

Paket Caching

Paket Installation

  • paket install reads the Lock File, and walks the references files finding <PaketId>s.
    • dependency items are recursively traversed
    • <NuGetSourceName> <NuGetPackageId> [<VerSpec>] elements are installed
    • frameworkAssembly translates to a <Reference (same as NuGet frameworkAssemblies)
    • (IFF Paket Caching above does not translate pakets to .nupkgs) <FileSourceName> <FileName> <DestinationPath> elements translate to <Compile links)

Examples

The examples below assume the following sources:

Sources
  nuget  nuget  http://nuget.org/api/v2
  github github https://github.com
  fssnip fssnip http://www.fssnip.net

  share  local  file://MyServer/MyShare/IsAlwaysUp
  file   local  ./
  myget  nuget  https://www.myget.org/MyAccount
  forki  github https://github.com/forki

Math with required assembly reference and helpers file

paket MyMath
  frameworkAssembly System.Numerics
  nuget MathNet
  github evelgab/MathNetExt FloatPigs.fs 

Testing paket with helpers

paket Testing
  nuget unquote
  nuget xUnit = 1.9.2
  github mycompany/testing xUnitV2Asserts.fs // default target -> App_Packages\Testing\xUnitV2Asserts.fs

Unit-Testing specific, built on paket Testing

paket UnitTesting
  dependency Testing // See separate paket
  nuget AutoFixture.xUnit
  nuget AutoFixture.AutoFoq
  github mycompany/testing AutoFoqExtensions.fs // default target -> App_Packages\UnitTesting\AutoFoqextensions.fs

Property-based testing based on paket Testing

paket PropertyTesting
  dependency Testing
  nuget FsCheck
  file test/helpers FsCheckExtensions.fs // default target -> App_Packages\PropertyTesting\FsCheckExtensions.fs

Property-based testing based on paket Testing, private build on myget

paket PropertyTesting
  dependency Testing
  myget FsCheck
  file test/helpers FsCheckExtensions.fs // default target -> App_Packages\PropertyTesting\FsCheckExtensions.fs

For the Living Documentation with mad helpers that live on a share

paket TickTesting
  dependency Testing
  nuget TickSpec.xUnit
  share test/helpers TickSpecExtensions.fs // default target -> App_Packages\TickTesting\TickSpecExtensions.fs 

fssnip usage

paket TestingWithSnippets
  dependency Testing
  fssnip AE // default target -> App_Packages\AE\AE.fs 

For @bartelink's Web Apps, house-style

paket WebEs
  nuget Microsoft.AspNet.WebApi >= 5.2
  nuget bootstrap >= 3
  nuget hyprlinkr
  myget NEventStore // private build
  github bartelink/FunDomain FunDomain/*.fs // It's not a NuGet yet

For @bartelink's Web Apps, after some evolution

paket Es
  myget NEventStore // private build
  github FunDomain/src FunDomain/*.fs // default target -> App_Packages\Es\*.fs

paket Api
  nuget hyprlinkr
  nuget Microsoft.AspNet.WebApi >= 5.2

paket Web
  dependency api
  dependency es
  nuget bootstrap >= 3

paket WebEs
  dependency Es
  dependency Api
  dependency Web

@forki's house style for tests

paket Test
  nuget NUnit.Runners
  nuget NUnit.Framework > 2.6
  forki FsUnit FsUnit.fs
@forki
Copy link
Member

forki commented Sep 25, 2014

just a short comment: at the moment I feel like

run

and don't even have time to look into this.

For changing the existing file formats I would need a ton of help,

@bartelink
Copy link
Member Author

Good 10,0000 words! Fair enough. I know I'm spouting a lot of 'just' too :)

I will hopefully be able to clear time to do some work on it in some sense (maybe even the 'writing teh codez` sense!).

However I think it is extremely important that you, @agross and @ilkerde read and respond to this stuff at some point and we get some idea of whether any of my rantings are comprehensible and implementable in any reasonable timeframe.

While it might be amusing for me to write the #129 and/or work on the core of this, I too feel it's a bit of a stretch to coordinate day to day dev work such as compexities of the resolution/installation algorithms with a parallel set of work going on related to this esp if I have no insight into how the Owners/Collaborators feel about all of this.

Ultimately this stuff needs to either be deleted from the issues list or some high level plan developed.

I think with some distillation and/or Issue-splitting, this can be sharded into a up-for-grabsable elements and ultimately end up fostering a bigger contributor community than the one that exists now.

Rest assured I'm cross validating a lot of this based on

  1. my experience of distributing pretty intricate SDKs over NuGet for a number of years (which are dramatic simplifications of older models)
  2. my thorough investigation of the Issues around here

and it Just Makes Sense and, as a result, every fibre of my being is shouting This Has to Happen!

It doesn't have to be this week or even next. But it does have to happen.

@agross
Copy link
Contributor

agross commented Sep 25, 2014

Still on vacation, will probably find time to respond next week.

Alex

Alexander Groß
Tiny phone, tiny mail

On Thu, Sep 25, 2014 at 1:38 PM, bartelink notifications@github.com
wrote:

Good 10,0000 words! Fair enough. I know I'm spouting a lot of 'just' too :)
I will hopefully be able to clear time to do some work on it in some sense (maybe even the 'writing teh codezsense!). However I think it *is* **extremely** important that you, @agross and @ilkerde read and respond to this stuff at some point and we get some idea of whether any of my rantings are comprehensible *and* implementable in any reasonable timeframe. While it might be amusing for me to write the #129 and/or work on the core of this, I too feel it's a bit of a stretch to coordinate day to day dev work such as compexities of the resolution/installation algorithms with a parallel set of work going on related to this *esp if I have no insight into how the Owners/Collaborators feel about all of this*. Ultimately this stuff needs to either be deleted from the issues list or some high level plan developed. I think with some distillation and/or Issue-splitting, this can be sharded into aup-for-grabs`able elements and ultimately end up fostering a bigger contributor community than the one that exists now.
Rest assured I'm cross validating a lot of this based on

  1. my experience of distributing pretty intricate SDKs over NuGet for a number of years (which are dramatic simplifications of older models)
  2. my thorough investigation of the Issues around here
    and it Just Makes Sense and, as a result, every fibre of my being is shouting This Has to Happen!

It doesn't have to be this week or even next. But it does have to happen.

Reply to this email directly or view it on GitHub:
#154 (comment)

@forki
Copy link
Member

forki commented Sep 25, 2014

I'm pretty sure we will break file formats before 1.0 - but not today.

@bartelink
Copy link
Member Author

Cool. BTW the only stuff this would 'break' is file: references in paket.references and .lock files would be rewritten.

The nuget syntax is intentionally directly supported - this is for many reasons:

  • its the lightest cleanest syntax that has already been arrived at which is nice for humans
  • backcompat

Also, lock files can stay in their old format as an interim step - it's entirely separable.

You said:

For changing the existing file formats I would need a ton of help,

and

I'm pretty sure we will break file formats before 1.0 - but not today.

If you're referring to packing non-nuget packages in NuGets to complete the #166 story, that's not a ton of work at all - it's a small self contained bit of work after download. And then deleting code allowing it on the packet.references side and/or the special-casd installation logic.

But I accept the "not today" central point of your argument.

@mavnn
Copy link
Contributor

mavnn commented Sep 30, 2014

You make a comment about "This ties each file/nuget package to a single source (which I think is good - I want to know where stuff comes from, and doesnt require the doc to state that sources are order-sensitive)".

I'm unclear whether this is in the .lock file (agreed, good idea) or in the .dependencies - in which case I can see several use cases where this would be unhelpful at best. Care to give a few more details on what you're thinking? :)

@forki
Copy link
Member

forki commented Sep 30, 2014

source order doesn't matter in dependencies file. as long as source is defined before the package

In lock file we pin the package to a source.

@bartelink
Copy link
Member Author

@forki As @mavnn was suggesting, I am explicitly saying that the syntax rules (the idea came from my reading of #125 even if it doesn't necessarily intend this) are explicit about the source in both cases.

In lock file we pin the package to a source.

Clearly, in the .lock this is completely necessary and correct and is already the case as @forki says.

source order doesn't matter in dependencies file. as long as source is defined before the package

I know this is the case in the current impl. And I'm proposing to remove that. My syntax proposal is intended to at this point be explictly saying for the Deps and the Lock file "all sources are defined and named before we start in one place"

I made the choice to have the sources at the top / in a config file that's read at the start on the following basis:

  • I do not see value in having the source defs in >1 place.
  • slight ease of impl / work around error messages
  • ease of documentation
  • ease of humans reading deps files (kinda like how default F# ordering doesnt allow stuff to just be randomly somewhere). Not wed to this. Could allow them to be interspecsed with paket definitions if it provides value that outweighs cost

The choice to have the source bindings explicit is for all the reasons above plus:

  • guaranteed no double-searching network/file traffic needed ever

Clearly it could be done that way but I chose not to. If you look at the examples, you'll see I use the source name pinning and >1 source in many cases.

As I said, if I reference a package and I have a nuget and a myget feed I know which is supposed to come from which. I dont want to have to consider some decision making process when reasoning about where my stuff comes from.

Right now, one can for example say

preprod nuget http://myget.... <- explicit
prod nuget http://nuget.org <- explicit
ci nuget http://teamcity <- explicit
nuget nuget  <> <- Could be dynmically assigned to vary e.g. on commandline, or in #125 `.config` file etc.

The way in which one models stuff that can switch is retargetting a source-alias.

This is very much a strong opinion weakly held... I won't be surprised if there is one, and if we can agree my immediate next step will be to amend my statements that are trying to pin a different behavior and make this intention explict.

So @forki can you explain the case where one can benefit in a clear way from reference needing an algorithm associated with it to decide which source it will be bound to in the .dependencies file (and why that justifies the mroe complex system) ?

EDIT: I guess the fact that all my examples use nuget as the alias for backcompat with the existing syntax is probably the source of the confusion but to be clear - this is a tradeoff I agonised over - the existing fomat is legible so if I don't have a good reason to break it, I wouldnt if possible.

@forki
Copy link
Member

forki commented Sep 30, 2014

The current implementation is only because the idea of multiple sources
wasn't really clear at the beginning.

There were a couple of problems with the original resolver which made this
necessary.

This is now fixed and I also prefer to put the nuget sources to the top.
On Sep 30, 2014 12:32 PM, "bartelink" notifications@github.com wrote:

@forki https://github.com/forki As @mavnn https://github.com/mavnn
was suggesting, I am explicitly saying that the syntax rules (the idea
came from my reading of #125
#125 even if it doesn't
necessarily intend this) are explicit about the source in both cases.

In lock file we pin the package to a source.

Clearly, in the .lock this is completely necessary and correct and is
already the case as @forki https://github.com/forki says.

source order doesn't matter in dependencies file. as long as source is
defined before the package

I know this is the case in the current impl. And I'm proposing to remove
that. My syntax proposal is constrained at this point to say "all sources
are defined and named before we start in one place"

I made this choice on the basis that

  • I do not see value in having the source defs in >1 place.
  • slight ease of impl / work around error messages
  • ease of documentation
  • ease of reading deps files (kinda like how default F# ordering
    doesnt allow stuff to just be randomly somewhere)
  • guaranteed no double-searching network/file traffic needed ever

Clearly it could be done that way but I chose not to. If you look at the
examples, you'll see I use the source name pinning and >1 source in many
cases.

As I said, if I reference a package and I have a nuget and a myget feed I
know which is supposed to come from which. I dont want to have to consider
some decision making process when reasoning about where my stuff comes from.

Right now, one can for example say

preprod nuget http://myget.... <- explicit
prod nuget http://nuget.org <- explicit
ci nuget http://teamcity <- explicit
nuget nuget <> <- Could be dynmically assigned to vary e.g. on commandline, in #125 .config file

The way in which one models stuff that can switch is retargetting a
source-alias.

This is very much a strong opinion weakly held... I won't be surprised if
there is one, and if we can agree my immediate next step will be to amend
my statements that are trying to pin a different behavior and make this
intention explict.

So @forki https://github.com/forki can you explain the case where one
can benefit in a clear way from reference needing an algorithm associated
with it to decide which source it will be bound to in the .dependencies
file (and why that justifies the mroe complex system) ?


Reply to this email directly or view it on GitHub
#154 (comment).

@bartelink
Copy link
Member Author

@forki OK, but do you agree with the second principle: each and every source reference (either top level or within a paket definition) should be referring to something unambiguous. i.e.

nuget FsUnit

always means "find the source called nuget, and interpret the rest in the context of its definition - and use that to decide the single place you are going to look for FsUnit
and definitely does not mean "find all the sources of type nuget and try them in order of definition.

?

@forki
Copy link
Member

forki commented Sep 30, 2014

No I don't agree. This will not work with indirect references which are on
different server. I tried that.
On Sep 30, 2014 12:43 PM, "bartelink" notifications@github.com wrote:

@forki https://github.com/forki OK, but do you agree with the second
principle: each and every source reference (either top level or within a
paket definition) should be referring to something unambiguous. i.e.

nuget FsUnit

always means "find the source called nuget, and interpret the rest in
the context of its definition - and use that to decide the single place you
are going to look for FsUnit
and definitely does not mean "find all the sources of type nuget and
try them in order.

?


Reply to this email directly or view it on GitHub
#154 (comment).

@mavnn
Copy link
Contributor

mavnn commented Sep 30, 2014

I'm not @forki but I do not agree. :)

First big issue is that the dependency of a "paket" may not come from the same source as the paket.

The second big issue is that in source one, you may have version x.0 of a sub dependency, while in source two you have version x.1.

You install a paket each from source one and source two that depend on the that sub dependency: they should both use version x.1 (otherwise, you get back into the whole multiple versions of the same package in the same solution nightmare).

Issue three (not so big):

I might have multiple sources that contain the same paket, and I just want the latest. I don't care where from.

Obviously, all of these concerns only occur at the dependency definition stage. I completely agree that once you've locked, all of the locked deps should be coming from a known source.

@bartelink
Copy link
Member Author

@forki I'll honestly hadnt considered that which is pretty silly, Doh! I'll be making the relevant edits. Right after I respond to @mavnn

At this point, before I read @mavnn's answer, I'm still holding onto the concept for top-level ones....

First big issue is that the dependency of a "paket" may not come from the same source as the paket.

That's covered - I was trying to be explicit about that in the earlier comment. A paket is not tied to anything. A paket can have within it a source-ref such as github forki/FsUnit or myGet FsUnit. Or it can be at top level in which case it happens to create a paket. But a paket does not have a single source - it just comonly only has one child.

The second big issue is that in source one, you may have version x.0 of a sub dependency, while in source two you have version x.1

You install a paket each from source one and source two that depend on the that sub dependency: they should both use version x.1 (otherwise, you get back into the whole multiple versions of the same package in the same solution nightmare).

In other words a top level nuget FsUnit might by an indirect ref elsewhere be forced to come from another source due to constraints there. OK, that collapses all my arguments - thanks.

It seems to me that the sources syntax should convey this - i.e. the grammar should, as part of you putting them there make you realize this. I'll look at how to best express this. Right now, all the source-alias concept in here is doing is confusing matter.

Issue three (not so big):

I might have multiple sources that contain the same paket, and I just want the latest. I don't care where from.

Clearly we need something that can be documented one way or the other. Even if its not yet implemented, we should make the goal clear. @forki (but also others) - should there be a way to say <source> FsUnit >1 and mean "across all sources" versus "the newest within a single source". It would seem to me that both are needed ?

Obviously, all of these concerns only occur at the dependency definition stage. I completely agree that once you've locked, all of the locked deps should be coming from a known source.

And this is where the syntax does definitely make sense. But I'd really like to work out a way to not have a source-ref do double duty as it now is doing. Will thinkg.

@mavnn
Copy link
Contributor

mavnn commented Sep 30, 2014

We might be using the term "paket" in different ways. I used to as a generic term for a package, which may or may not be nuget based, which you are choosing to depend on. The rest of my comment might now make more sense :)

@bartelink
Copy link
Member Author

@mavnn No, you're getting it right - it's the whole point (as I allude to in the @ilkede references)! paket is very much intended to be abstract (OK I get what you mean now - but I've written the above on the basis that you were only missing that single subtlety)

@kolektiv
Copy link

This is definitely not trivial, and it would be good to get a few of us perhaps in chat to clarify (maybe some time this afternoon?) I'm writing parsers at the moment, and there are certainly decisions which can be made which will make that a more or less complex task.

I may need to understand the resolution approach better before I can offer constructive changes/suggestions. It would be good to have a chat as a group :)

@bartelink
Copy link
Member Author

@kolektiv Def. The jabbr Paket room is for this. I'm going to think out loud in markdown with multiple lines here for now though :)

Jabbr can be a disaster for >2 people considering a problem, and clearly >2 is important here!

(I'm thinking I have cases where there needs to be a "floating ref" vs an "explicit" ref and I want them ruled in our out from the perspective of implementability of any kind in a sane resolution engine!)

It seems to me that having an explicit vs loose syntax is important.

Say I want to be able to say:

myget xunit >= 2 <- random people get v2 at least from our private build, and that can referred to by the `<PaketId>` of `xunit`

paket UnitTests
  nuget autofixture.xunit > 3 <- wants xunit 1.6+ ... implicly means the top level `xunit` paket, whatever that turns out to mean (it happens to work it out private build so nothing explicit here)

paket AcceptanceTests
  nuget xunit < 2 <- pins an override for the paket
  nuget tickspec.xunit <- won't work with v2 even though it says >= 1.8 and I know it's one off nuget.org I want - don't go telling me it clashes with my other stipulation from myget

Then a proj .references file can ask for any of the 3 pakets defined above and 2 xunit .nupkg files will be needed.

  • the <2 can live in packages/AcceptanceTests.
  • the >=2 can live in packages/xunit

And all refs are to pakets so nothing is ambiguous

Aside from ruling this sort of thing in or out for short/medium/long term, the next issue that stems from this is how "source-neutrality" interacts with this....

if we have an explicit floating across sources syntax, myget xunit >= 2 becomes ? nuget >= 2 then it will find latest across MyGet and NuGet (and the autofixture.xunit dependency on xunit >1.6 is evaluated alongside).


However, if everything floats by default and we take the sources from #125:

nuget   nugetv2   http://nuget.org/api/v2
github  github    https://github.com
myget   nugetv2   https://www.myget.org
fssnip  fssnip    http://www.fssnip.net
intern  nugetv2   http://acme-corp.local/nugetserver

Then The clearest syntax I can see to express that I want my custom xunit from

// Define 3x sources: `nuget`, `source` and `fssnip`
sources
   nuget
    nugetv2   http://nuget.org/api/v2          <- has xunit < 2
    nugetv2   https://www.myget.org         <- has xunit >= 2  
    nugetv2   http://acme-corp.local/nugetserver
  source github https://github.com
  fssnip  fssnip http://www.fssnip.net

nuget xunit >= 2  <- looks across servers, can only be myget

paket UnitTests
  nuget autofixture.xunit > 3 <- wants xunit 1.6+ => looks across servers, picks myget though a nuget one would have been fine

paket AcceptanceTests
  nuget xunit < 2 <- pins an override for the paket (where, for all nuget sources? for this paket? If so, should an indent subsearch decide what this means?
  nuget tickspec.xunit <- (uses local override)

@bartelink
Copy link
Member Author

Right, prev sample has confused me but hopefully it'll help people gather thougts and answer this:

  • do we need floating indirect dependencies ?
    Think we all agree: yes
  • do we need ability to constrain / alias / pin overrides in a paket
    I think Yes
    others?
  • do we really read floating top level dependencies ?
    I can't explain why - @mavnn ? @forki ? Can you give an example?
    I feel most can be expressed by scoping them in a paket?
  • should/can/does the sources list syntax need to accomodate ways of composing arbitrary sets of feeds so one can pin to a subset?

I think the big thing we need before we have any discussion of any kind is more examples of concrete cases where there is interplay between:

  • source-refs that float across multiple sources
  • ordering of sources dictating version that's picked
  • multiple references with differing rules
  • indirect vs direct references
  • irreconcilible constraints (xunit >= 2 and xunit<2 in same tree)

Step 1 is prob to rule each of these complicating factors is in or out. For instance I feel at this point that something can be achieved by keeping things explicit and rejecting graphs that previously had to be 'fixed up' by reordering sources. Maybe a ruleset such as:

  • source-ref syntax should be targetted at a single target
  • indirect refs are across all by default and it does not take ordering into account - if the rules across the full set conflict, it bails out.
    -> Then one can break the logjam by creating a top level declaration for that packetid which says which one you're choosing
  • doing a floating-reference syntax should be done as a separate exercise after the main things are triangulated - but at least make sure all things people have clear cases for are addressed (yes, mine are not real so should not be admissible)

What I'd like to see next is me stopping with the strawmen and @forki et al indicate the fundamental constraints/assumptions. i.e.

  • source ordering sensitivity in/out
  • fixed target syntax supported/not
  • floating target syntax supported/not
  • explicit rules can override indirects or not
  • indirects have same rules as direct or not etc?

Once we have some clarity on that, I can stop laying out hypotheticals and try to resolve it into a workable set of edits to the original proposal.

Unfortunately (for me but fortunately for others) I'm going to only be intermittently available for the next 4h and then offline for the 5h after that :(

@kolektiv
Copy link

As a syntactical point rather than a semantic one, it would be ideal to change lines like

<NugetSourceName> nuget <NugetSourceUrl>

to

nuget <NugetSourceName> <NugetSourceUrl>

This makes parsers significantly simpler and doesn't, as far as I'm concerned, detract from readability (in fact it probably aids it). Avoiding the requirement for significant lookahead and backtracking in parsers is good when you can do it. Although I certainly can implement it as is, it seems like taking the simpler syntax where we can would be good?

@mavnn
Copy link
Contributor

mavnn commented Sep 30, 2014

@kolektiv Am I being dense? I can't actually see the difference?

@forki
Copy link
Member

forki commented Sep 30, 2014

@mavnn I assume it was formatting issue and now fixed.

@kolektiv: we don't have this syntax now, right? Personally I prefer if we start with the current syntax, since the other options are not decided yet.

@mavnn
Copy link
Contributor

mavnn commented Sep 30, 2014

@bartelink personal preference here, but:

  1. Source ordering should not be significant. The only possible exception here is if two sources have the same version or the same paket, order could be used as a tie breaker.
  2. Fixed target syntax would be nice, but might introduce a surprising amount of accidental complexity when a paket is both directly referenced and a sub-dependency.
  3. Floating targets should definitely be allowed - "give me the newest matching version from any of these sources"
  4. I can't even begin to imagine the pain of specifying indirect dependency constraints manually! I'd try and avoid this unless there's an amazingly useful use case I've not yet thought of
  5. Indirect dependencies should, in my opinion, always take the highest matching version available from all sources. Otherwise you can end up in very painful situations where you can't install two pakets because they have a shared dependency but come from different sources. You can always specify a limited range of versions you're willing to accept.

@kolektiv
Copy link

@forki not totally sure I get what you mean. At the moment we don't have either of those syntaxes that I can see. For now would you prefer the parsers to implement the current form of Paket.dependencies, etc.? I.e.:

source http://nuget.etc    
nuget SomePackage 1.0

That's fine if so :)

@bartelink
Copy link
Member Author

@kolektiv The intention was to have it symmetric with the consumption syntax. I did push it back and forth a few times. I buy your point that it might actually read more clearly the other way. Hence if you want to flip it based on that new input, I have no objection.
@forki I think we need to get some clarity or else @kolektiv needs to stop coding - my stuff waves hands like its a spec, but there are massive holes without answers to the questions. While the intent can obv in most cases be divined from the code, I think the more things can be stated explicitly here about stuff thats def in or out, the better for reasoning about even tokenising (though I'm sure if you treat the parsing are a completely separate thing that can be argued away). I think we have people here who are ready to a) validate a scheme b) implement it and we need to capitalise on that.
@mavnn

  1. Yes, good way to put it
  2. You may well be right but while my post was too long and confusing, there's a strong danger of confirmation bias in a reader without an actual example
  3. Critical to say if you think its a viable primary/default - ultimately if there are two types in the picture either one needs to be strongly favored or we choose a deliberately contrasting pair? Can you nail colours ot the mast and say whether this should really be the main one and then an explicit one should just be for rare use?
  4. Not suggesting only. I'm suggesting if there are 3 sources and the only way to resolve it is by considering the order in which they were registered then it should bail. And it can say "please add a rule <A/B/C> AmbiguousNuGet" to say which one you want. (ref 1 BTW)
    5,. why always ? Does it always deal with all cases or are there cases where having it be overridable can actually resolve an irreconcilable overlapping set of constraints. If its always across all sources, then you end up having to register multiple source sets and/or provide another syntax to break the conflict (yes, arm wavingy but despite not knowing exactly what you're saying, it feels wrong?)

@kolektiv
Copy link

I will take a short pause while we decide on what we should implement now in terms of parsers (if it's parsers for what currently exists, integrated with the existing code, that's fine). I think it's perfectly reasonable to implement what we have now as a "proper" parser, get that integrated and building, and then move forward, evolving that to a new extended syntax, if people would like to do this that way.

@forki
Copy link
Member

forki commented Sep 30, 2014

@mavnn how version ranges work is described in http://fsprojects.github.io/Paket/nuget-dependencies.html#Version-constraints also what we do work around broken packages (! Operator)

@kolektiv yes I don't want to change the file formats at this point. But my hope is you can help to simplify our current parser monster by introducing FParsec.

@kolektiv
Copy link

@forki cool, that's a good way to move forward. I think I can do that :) I'll have some lunch and then spike that.

@bartelink
Copy link
Member Author

@kolektiv Sorry, I should have made it clearer in my #129 comments that it needs to be clarified whether it's "current code", #125 or #154 it's to be based off. At least that's clear now.
@forki and/or @agross as I'm only a chicken, I need pig inputs so I can make valid inferences and fix what is currently a simpler-than-possible pipedream with subtleties that will melt away / grow / change only when it gets unblocked.

@ilkerde
Copy link
Contributor

ilkerde commented Oct 3, 2014

It is very hard for me to follow Paket discussion and get an oversight about the status quo, both on issues as well as conceptually. Please bear with me if I miss things.

First, I'd like to give my prefs on the obvious open ends as requested by @bartelink:

  • source ordering is significant, strategy is first fit.
  • fixed targets is too complex for me. I don't even understand what it means.
  • floating targets as @mavnn describes it is very fine with me.
  • indirect deps may not have differing rules as their direct dep mirror. No overrides whatsoever. direct dep constraints win always.

A personal note: @bartelink I really appreciate your detail and elaborateness. However, it's very hard for me as non-native english speaker to understand everything what you write. This is certainly my fault being very limited on my english. Please bear with me if I don't understand everything at first sight.

@ilkerde
Copy link
Contributor

ilkerde commented Oct 3, 2014

@kolektiv changing source definition syntax from

<NugetSourceName> nuget <NugetSourceUrl>

to

 nuget <NugetSourceName> <NugetSourceUrl>

is very ok with me at least.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants