Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@joelmartinez
Copy link
Member

You can now maintain documentation for a library that is supported on multiple platforms in a single set of documentation. Types and members will be tagged with information about what platform it is supported on. The slightly more general concept of "owner" was chosen because this feature will eventually support more than just platforms ... it will ideally also support things like being able to tag the documentation with what PCL profile it's supported in.

The biggest change is that the docs are now stored in the “unified” form on disk. After an mdoc update,
the XML files will be stored in folders that lack the “dropped namespace” (previously, it was stored in “classic” form, or with the dropped namespace). This makes it easier to have multiple frameworks that share common namespaces (other than the dropped prefix). Running mdoc update with the appropriate dropns parameter will reformat and move files into the now-correct folders. If there are conflicting type XMLs between the two assemblies that are being merged, the version from the first assembly on the dropns list will be given preference.

This pull request also slightly changes the format for dropping namespaces on both the update and assemble
commands from previous versions.

To add owner information … just add =ownerName to the assembly list. So in the example below, Assembly1 is attributed to "Framework1", while Assembly2 is attributed to "Framework2":

mdoc update Assembly1.dll=Framework1 Assembly2.dll=Framework2 -o en

Dropping namespaces … the assembly from which the namespace is being dropped is now added to the list
of dropped namespaces. This makes it easier from an implementation standpoint to know which types and members should the resulting namespace be dropped from:

mdoc update Assembly1.dll=Framework1 Assembly2.dll=Framework2 --dropns=Assembly1.dll=DroppedNS --dropns=Assembly2.dll=OtherDroppedNS

When assembling the classic doc set (ie. tree/zip) after a namespace has been dropped, you now specify the namespaces that have been dropped. Unified does not need any special command line formulation (it was reversed previously) for this particular feature (though you'd still have to pass in ntypes if the "unified" assembly has those special native types):

mdoc assemble en/ --droppedns=DroppedNS --droppedns=OtherDroppedNS --out=out-docs

The corresponding changes to support the display of this new "owner" information has been added to monodoc and the XSL templates.

@jonpryor
Copy link
Contributor

If possible, please update your commit message (git commit --amend):

  1. The final example command is missing the mdoc command
  2. You have "smart quotes" in the final command line.

The final example command should be:

mdoc assemble en/ --droppedns="DroppedNS OtherDroppedNS" —out=out-docs

@jonpryor
Copy link
Contributor

Your commit message also appears to have em-dashes instead of "normal" dashes (or double-dashes) --. This will hinder copy/pasting of commands for documentation, testing, sanity checking, etc.

@joelmartinez
Copy link
Member Author

@jonpryor ... these two pieces of feedback have been amended and a new version pushed. That's what I get for writing my pull request notes in Notes.app :)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I really don't like this semantic of whitespace-separated values.

I would far prefer that each "dropped namespace" be a separate command-line option, e.g. instead of:

mdoc update Assembly1.dll Assembly2.dll —dropns="Assembly1.dll=DroppedNS Assembly2.dll=OtherDroppedNS"

have:

mdoc update Assembly1.dll Assembly2.dll \
    --dropedpns=Assembly1.dll=DroppedNS \
    --dropedpns=Assembly2.dll=OtherDroppedNS

This can also be more reasonably supported within OptionSet by using OptionSet.Add<TKey, TValue>(string prototype, string description, OptionAction<TKey, TValue> action):

{"droppedns=",
    "The namespace(s) that have been dropped in the documentation from this version of the assembly."
    (assembly, ns) => {
            droppedNamespaces.Add (assembly + "=" + ns);
}},

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahh, interesting ... so that Action will basically just get called multiple times for each instance of the parameter that's included. Ok, I can make that change :)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jonpryor alright, I made a small change to make sure this syntax is supported, and updated the commit message and pull request description with updated examples For the syntax you suggested :)

@joelmartinez
Copy link
Member Author

@jonpryor Happy new years :) wanted to follow up on this. Are there any other pieces of feedback, or issues with this pull request that I need to address?

@jonpryor
Copy link
Contributor

jonpryor commented Jan 5, 2015

@joelmartinez As per recent mono email thread, we would like PRs to be a single (squashed) commit (for cleaner history, etc.). It's also troubling that the Merged Build failed (though I'm not sure why it failed).

@joelmartinez
Copy link
Member Author

@jonpryor oh, I kept the two commits separate because they were changes to different areas (mdoc and monodoc). But let me squash those.

I believe the build failure was unrelated to these changes as the mdoc and monodoc test suites are passing (at least, for me locally). But those results have been since removed from jenkins ... once I push up these changes squashed, it should kick off another build, so let's see what's up then :)

@akoeplinger
Copy link
Member

@jonpryor @joelmartinez I interpreted that email in the way that we shouldn't have multiple commits in the PR doing "uninteresting" things like fixing typos, adjust formatting etc. Those should be combined into the original commit. IMO it's perfectly fine to use separate commits where it makes sense, i.e. per work unit as has been done here.

@joelmartinez
Copy link
Member Author

I can go either way with this :) But in any case, while I was looking at this again, I discovered another edge case ... I've added another test to reproduce it and am in the process of fixing it. I will submit another update once that's fixed.

@directhex
Copy link
Contributor

build

@akoeplinger
Copy link
Member

@joelmartinez looks like the Jenkins build failed:

MDOC    [net_4_5] Mono.tree
Warning: couldn't process directory `./../class/Commons.Xml.Relaxng/Documentation/en' as it has no index.xml file
mdoc: System.InvalidOperationException: ReadSubtree() can be invoked only when the reader is positioned on an element. Current node is None.   (line 1, column 2573)
  at System.Xml.XmlReader.ReadSubtree () [0x00000] in <filename unknown>:0 
  at Monodoc.Providers.EcmaDoc.PopulateTreeFromIndexFile (System.String indexFilePath, System.String idPrefix, Monodoc.Tree tree, IDocStorage storage, System.Collections.Generic.Dictionary`2 nsSummaries, System.Func`2 indexGenerator, IEcmaProviderFileSource fileSource, System.Collections.Generic.List`1 ownerList) [0x00000] in <filename unknown>:0 
  at Monodoc.Providers.EcmaProvider.PopulateTree (Monodoc.Tree tree) [0x00000] in <filename unknown>:0 
  at Mono.Documentation.MDocAssembler.Run (IEnumerable`1 args) [0x00000] in <filename unknown>:0 
  at Mono.Documentation.MDoc.Run (System.String[] args) [0x00000] in <filename unknown>:0 
  at Mono.Documentation.MDoc.Main (System.String[] args) [0x00000] in <filename unknown>:0 
See `mdoc help' for more information.
make[7]: *** [Mono.tree] Error 1

@joelmartinez
Copy link
Member Author

Ahh, thanks for triggering that rebuild. I will take a look at what's causing the failure.

@joelmartinez
Copy link
Member Author

Just a quick update ... this build failure has proven tricky to track down. I fixed the code I thought it was introducing this issue, however, I haven't been able to reproduce this error locally, and the error keeps occurring. So I've added some additional error handling/output to see if I can track down the issue more effectively.

Waiting for this build to run ... Stay tuned :)

@akoeplinger
Copy link
Member

@joelmartinez I can reproduce this by going into ./mcs/docs and running make clean && make.

@joelmartinez
Copy link
Member Author

Ahh, finally ... got this sorted :) thanks for that tip @akoeplinger, it was really helpful.

I've also gone ahead and squashed the two commits into one. The build should work, or at least, not fail due to mdoc/monodoc ... let's see how this goes.

@joelmartinez
Copy link
Member Author

Well it looks like the build failed, but if I'm reading the build output correctly, it doesn't have anything to do with mdoc or monodoc ... thoughts?

@akoeplinger
Copy link
Member

build

@akoeplinger
Copy link
Member

The build failed due to bb9d05a, so let's try another one.

@joelmartinez
Copy link
Member Author

@akoeplinger should I try to rebase from master or something?

@akoeplinger
Copy link
Member

@joelmartinez yeah , you can try that, though I think something is weird with the build workers atm :D

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@joelmartinez Are those whitespace changes in the en.expected.importecmadoc files intended? We talked about it via email a while back, looks like this is why the Jenkins build fails.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it? just out of curiosity could you point out where you see this in the build spew (in the interest of me learning how to interpret the results better)?

That being said, I don't remember making this change explicitly ... I rebased my branch after that commit was merged into master that we talked about via email (the one with the xml formatter changed), so in theory, it should match whatever is in master ... no? let me check

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@joelmartinez it's actually quite easy, just grep for the first occurence of "Error 1" in the build output.

in theory, it should match whatever is in master ... no?

No, as in that case it wouldn't show up as a change here :)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh geez ... duh, of course, had a momentary brainfart and didn't realize this was the diff against master :P

Ahh I see, so then the build output changed when you ran the build again? I guess it was just a temporary glitch with the build server? cool ... in any case. let me rebase against master and make sure there aren't any errant XML changes.

@joelmartinez
Copy link
Member Author

@akoeplinger rebased to master, and double checked that the test that was failing due to the formatting issue you pointed out is not failing after the rebase, nor does it have that funky formatting. Honestly, not really sure as I didn't make any changes other than simply to rebase. Let's see if this build passes.

@akoeplinger
Copy link
Member

@joelmartinez I still see those formatting changes for en.expected.importedecmadoc included in the diff, are you sure you reverted them (simply rebasing won't work I guess since you squashed everything into a single commit before)?

@joelmartinez
Copy link
Member Author

Ok, this is really weird ... I don't understand why these tests are not failing locally. When I run make check-monodocer-importecmadoc locally, it works, and the diff is passing correctly.

sigh my apologies for the back and forth on this. I guess I will manually copy down those particular files that are failing in the build output and see how that works? I'm guessing something went wonky with my original rebase and maybe I reverted the XML changes we were talking about earlier ... but it still doesn't explain why it's not failing locally. Oh well, we'll figure it out :)

@akoeplinger
Copy link
Member

@joelmartinez fwiw, I pulled down this PR and ran make check-monodocer-importecmadoc and it failed for me locally, so something might be weird with your checkout. Try a git clean -xdf (will wipe any untracked changes) and then building.

@joelmartinez
Copy link
Member Author

image

@akoeplinger
Copy link
Member

Finally 😄 🎉

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't like this, because it's not particularly clear why "if any argument is null, use the count".

It also seems duplicative; there's already a EcmaDesc.GenericTypeArgumentsIsNumeric property, which seems to have the same intent behind it; shouldn't GenericTypeArgumentsIsNumeric be used here, instead of .Any()?

Also, GenericTypeArgumentsIsNumeric should probably be updated to use .Any() instead of .FirstOrDefault().

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't notice that property ... so I will definitely refactor to use it (along with the other few comments in this area), thanks for pointing it out.

As for the intent behind this ... it's because when building up the ecma URLs, if the "type" is available, we can print out URLs such as SomeClass<T,K> ... but if even one of those type arguments is null, then we have no way of printing out the correct signature, and so it needs to default back to the SomeClass`2 form of the signature.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand why this is now a List<EcmaProvider>, particularly since only one provider will ever be added to it -- when ecma == null! ecma.Add() is only performed once; there's no need for this to be a list.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahh, you know what ... this is an artifact from an earlier implementation that I was going for. I eventually changed how I was going to do multiple runs (because I needed to be able to do everything, for both classic and unified assemblies in one invocation, but it's much easier to keep the logic separate while it's running ... so I just run it twice internally for each set of assemblies).

I can change this and will resubmit

@joelmartinez
Copy link
Member Author

@jonpryor I've made the requested changes to remove the unnecessary List<EcmaProvider>, and also to reuse the GenericTypeArgumentsCount and GenericTypeArgumentsIsNumeric properties.

@joelmartinez
Copy link
Member Author

@akoeplinger looks like the build failed again due to unrelated issues?

make[10]: *** [run-test-lib] Error 1
make[10]: Target `run-test-local' not remade because of errors.
make[10]: Leaving directory `/var/lib/jenkins/workspace/test-mono-pull-request/label/debian-amd64/mcs/class/System'

Does the build need to be triggered again?

@akoeplinger
Copy link
Member

@joelmartinez master is in flux lately, wait a bit for it to settle down :)

@joelmartinez
Copy link
Member Author

ahh ok, no worries :)

@joelmartinez
Copy link
Member Author

@akoeplinger ... has the master branch stabilized? any chance you could re-trigger the build to see if it passes checks? :)

@akoeplinger
Copy link
Member

@joelmartinez let's just try it :) the ARM builds will still fail however. Btw you should be able to trigger a build as well since everyone in the Xamarin org should be whitelisted.

@akoeplinger
Copy link
Member

build

@migueldeicaza
Copy link
Contributor

It looks like the build failed for reasons unrelated to this patch.

Jonathan, any updates on this?

@joelmartinez
Copy link
Member Author

FYI, @migueldeicaza, I'm making the requested changes for the icons and layout. I've already implemented the new icons, and am looking at the layout changes. I'll ping this thread when I push a new version that includes those :)

@xamarin-cla-bot
Copy link

Hey @joelmartinez,
Thank you for your Pull Request! We <3 our contributors!

However, it looks like you haven't signed our CLA (Contributor License Agreement) yet. In order for us to accept your pull request, you have to sign our CLA first.
Once you do this, we can check over your pull request. You should only have to do this once.

You can read and sign our full Contributor License Agreement here.

Thanks,

Your friendly Xamarin CLA Bot#

@joelmartinez
Copy link
Member Author

quick FYI on the status of this PR ... we are going to change the way we are deploying API docs, as such please don't accept this PR for a few weeks :P I should be done and ready for this to be merged sometime in early April

@jonpryor
Copy link
Contributor

@joelmartinez: Then while you're doing that, could you please split this up into smaller parts so that it's not a 6400+ line patch? :-)

This feature allows you to assign framework or platform ownership to types
and individual members. Included in this patch are two icons specifically
for mac and ios.

Additionally, there is also a bugfix included for EcmaDesc's ToEcmaCref
method; it did not support generic parameters of the form "SomeType`1" correctly,
so even though you could parse one of those URLs, it could throw an exception
when trying to turn it back into a string.
…k/platform ownership.

The biggest change is that the docs are now stored in the “unified” form on disk. After an `mdoc update`,
the XML files will be stored in folders that lack the “dropped namespace” (previously, it was stored in “classic” form, or with the dropped namespace). This makes it easier to have multiple frameworks. Speaking of which,
you can now pass in owner/platform information on the assembly list (see example below). This will mark
types and members with owner information that will be displayed in the rendered documentation.

Also, slightly changed the format for dropping namespaces on both the update and assemble
commands.

Owner … just add `=owner` to the assembly list:

    mdoc update Assembly1=Framework1 Assembly2=Framework2 -o en

Dropping namespaces … the assembly from which the namespace is being dropped is now added to the `dropns` parameter
along with the dropped namespace.:

    mdoc update Assembly1=Framework1 Assembly2=Framework1 --dropns=Assembly1=DroppedNS --dropns=Assembly2=OtherDroppedNS

Assembling classic doc sets after a namespace has been dropped. unified doesn’t need any special command line formulation, other than the fact that you no longer need to include the `dropns` parameter since it’s being handled in the classic update now:

    mdoc assemble en/ --droppedns=DroppedNS --droppedns=OtherDroppedNS --out=out-docs
@xamarin-cla-bot
Copy link

Hey @joelmartinez,
Thank you for your Pull Request! We <3 our contributors!

However, it looks like you haven't signed our CLA (Contributor License Agreement) yet. In order for us to accept your pull request, you have to sign our CLA first.
Once you do this, we can check over your pull request. You should only have to do this once.

You can read and sign our full Contributor License Agreement here.

Thanks,

Your friendly Xamarin CLA Bot#

@joelmartinez
Copy link
Member Author

@jonpryor ... I've split the PR into two separate commits; one for mdoc and one for monodoc.

@migueldeicaza ... this latest commit resolves the issue you encountered with the GetAppearance member on UIActivityIndicatorView. I tested it after refreshing the merged repository and verified that that member correctly contained both the classic and unified signatures (in addition to the two non-generic versions that were added in the update); and also that subsequent re-runs will not produce duplicate nodes.

Please note that if/when we commit to moving to this version of mdoc, the mdoc update invocation will be slightly different. I've included all the details in that email that I'd sent previously, but you can ping me for any additional details.

@jonpryor
Copy link
Contributor

This feature allows you to assign framework or platform ownership to types
and individual members.

What does this mean? What is a "platform owner"? An email address? URI? "Just" a name?

Examples?

Why do we care? What's the use case? What uses it?

Is "owner" even the right name? For example, the commit adds owner-ios-32.png and owner-mac-32.png images. This is presumably to show in the documentation which "owners" are supported.

When describing the resulting web page, is that the wording you'd use? "The method String.ToString() is owned by iOS and Mac."?

No. Not it isn't.

Instead, look at the mdoc commit message:

Owner … just add =owner to the assembly list:

mdoc update Assembly1=Framework1 Assembly2=Framework2 -o en

The example uses "Framework1", not owner.

Thus, the entire "owner" concept is misleading; it should be "framework", "frameworkName", "frameworkIdentifier", etc.

Additionally, there is also a bugfix included for EcmaDesc's ToEcmaCref method;

That should probably be a separate commit/PR.

@joelmartinez
Copy link
Member Author

@jonpryor the "magic type" is a holdover from what ultimately became the "native types" that came along with the unified version of the iOS APIs (ie. nint, nfloat, etc.) ... this was just implemented before we started referring to them as native types. I can change how this is referenced internally to match the parameter that kicks it off (-ntypes)

@joelmartinez
Copy link
Member Author

@jonpryor in response to the comment about the naming of 'owner' ... I'll explain the use case, and my thinking behind the name. Totally open to suggestions on how we should proceed, but at least the discussion can have more information :)

So the core requirement I was given for this feature was to be able to store Mac and iOS API documentation in the same set of XML documents. So originally, what I eventually called owner was going to be platform based on the requirements alone. The reason I decided to generalize the term; yes, the ambiguity was, in some ways, on purpose; was because I saw that this could be used to support a feature that we've seen from support feedback as a necessity ... richer versioning information for API docs. Similar to what they have on MSDN:
image
To give you an example of where this comes up, people regularly come across System.Web on the Android API docs and email in to support asking why this doesn't work on Android. Of course the reason is that we simply have the mono BCL docs on there, but not the version that's supported on Android.

I reasoned that perhaps in the future, we could run this process against all of the relevant incarnations of the BCL and be able to tell the user that a given method was supported on, say: ios, android, mac, windows, pclX, pclY, pclZ. And so, I chose a more general name, owner (as in, "this API is owned by both MonoTouch and Xamarin.iOS". This particular phrasing came up in conversation during discussions.

But for the time being, all I needed to support was ios and mac, and so I left it as owner in hopes that we could leverage the feature in the future to expand the semantic value of our docs with all this additional information.

So given that information ... do you think that simply renaming this to framework would suffice?

@jonpryor
Copy link
Contributor

I chose a more general name, owner (as in, "this API is owned by both MonoTouch and Xamarin.iOS".

My problem is that I can't imagine actually using that phrasing, ever. Maybe that's just me.

I can imagine saying "This API is provided by Xamarin.iOS and Xamarin.Android", or "supported in", or "exists", and probably any number of synonyms for those, but "owned by" is just...weird.

Furthermore, "Supported in" is the phrasing that MSDN uses:

Supported in: 3.0, 2.0, 1.0
Supported in: Windows Phone 8.1
Supported in: Windows Phone Silverlight 8.1
...

Based on that, I'd go with "supported in" as the phrasing.

@jonpryor
Copy link
Contributor

Then there's the previous comment about how to use/provide this information, e.g. the example in the original commit message:

 mdoc update Assembly1.dll=Framework1 Assembly2.dll=Framework2 -o en

It's...not quite right?

Let's use a specific example:

mdoc update mscorlib.dll=Xamarin.iOS System.dll=Xamarin.Android

The problem is that we know mscorlib.dll will also be provided in both Xamarin.iOS and Xamarin.Android (and the desktop, and...), and the same is true for System.dll.

Does the above command line even make sense?

The intent, as I understand it, that the current <Member/>/etc. elements would have an <Owner/> child element, which would contain these "owner names", and specifying the owner name after the assembly would allow all types/members from that assembly to be updated to have new <Owner/> elements.

Assuming that's true, why do you need to support providing multiple different "owners" at the same time? Why not just specify it once and have it be used by all assemblies?

mdoc update --supported-in=Xamarin.iOS mscorlib.dll ...

Furthermore, and sorry for not actually checking, what happens for members that were supported in previous "owner" assemblies but are not anymore?

For example, between public releases we do work on mscorlib.dll, adding Mono.Runtime.SomeMethod():

mdoc update --supported-in=Xamarin.iOS mscorlib.dll...

At this point, we'll produce a Runtime.xml file in which the SomeMethod member has <Owner>Xamarin.iOS</Owner>.

Then, assume this was actually a mistake, and Xamarin.iOS shouldn't have Runtime.SomeMethod(), so it gets removed from the Xamarin.iOS profile, and we update the docs...

mdoc update --supported-in=Xamarin.iOS mscorlib.dll...

Will the above command go through every XML file and member to remove <Owner/> elements that match --supported-in but *don't currently exist` in the reference assemblies?

If not, then I think it should.

@joelmartinez
Copy link
Member Author

@jonpryor, I've created a separate pull request that breaks out several of the unrelated modifications present in this pull request (other than in the sense that they were necessary to implement for this feature to work): #1641

@migueldeicaza, in particular, the commit that unblocks you is f75548e8790283d581648982f58d4ddf7277fb69

In the meantime, I will rebase this branch (ie. #1460) to include the changes from #1641). Should I just close this and start a new/fresh PR when that's done?

@jonpryor
Copy link
Contributor

jonpryor commented Apr 2, 2015

@joelmartinez: It should be fine staying with this PR.

@lewurm
Copy link
Contributor

lewurm commented Mar 28, 2016

I'm not quite sure if #1641 covers all the changes now? @joelmartinez: can you either rebase or close this PR?

@joelmartinez
Copy link
Member Author

That particular PR was just a few bug fixes that I broke out ... however, you're right that the strategy has changed. This functionality will be provided by the changes coming in #2377 and beyond

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

Successfully merging this pull request may close these issues.

7 participants