Giter VIP home page Giter VIP logo

powerargs's Issues

license

there is currently no license, could you add one? Because, you know, lack of license means no one can legally use it :-)

Upgrading to 2.3.1.0 introduces a content file

After upgrading, Resource/DefaultBrowserUsageTemplate.html appears in my project.

The new ArgUsage.GenerateUsageFromTemplate<T>() works fine without it so this file is noise. Can it be removed from the package?

In Usage Options output the whitespace is missing

When PowerArgs/ArgUsage.cs was rewritten in 0910357 the whitespace was removed inadvertently. In the latest code, the opening parentheses is missing the whitespace.

PowerArgs/ArgUsage.cs - June 4 (Lines 359-365)

                if (inlineAliasInfo != string.Empty) inlineAliasInfo = "(" + inlineAliasInfo + ")";

                rows.Add(new List<ConsoleString>()
                {
                    new ConsoleString("-")+(usageInfo.Name + inlineAliasInfo),
                    descriptionString,
                });

PowerArgs/ArgUsage.cs - May 24 (Lines 343-347)

                rows.Add(new List<ConsoleString>()
                {
                    new ConsoleString(indicator)+(usageInfo.Name + (usageInfo.Aliases.Count > 0 ? " ("+ usageInfo.Aliases[0] +")" : "")),
                    descriptionString,
                });

ArgUsage.GenerateUsageFromTemplate<T>() formatting regressions

In comparison to the old ArgUsage.GetStyledUsage<T>, the default rendering from the new ArgUsage.GenerateUsageFromTemplate<T>() has several shortcomings:

  • No TYPE column in arguments list
  • No required (*) indicator on parameters
  • No indentation for arguments list
  • Poor examples layout:-
    • No blank line after each example (hard to tell where one ends and the next begins), Moreover, there isn't even a line break between each example, which means the description of the next example blends into the parameters of the previous example
    • No colour distinction between the parameters of the example and its description

Enum types abbreviations

It'd be nice if Enum parameters also got assigned single letters to abbreviate each enum member.

Internal Command Driven App

Adam,

Nice work. I found your PowerArgs while looking for a library to parse internal command line strings. The various command line parsing libraries all work on the Main Args list. It would seem that PowerArgs could be enhanced to handle any string even before it is broken into the Args list. That way the library could be used inside an application to handle an internal command driven interface. Any thoughts?

dgp

Error when methods are in-lined

I just found that when I build PowerArgs in release, I get a TargetInvocationException (and NullReferenceException inner exception) from the AttrOverride.cs Set method, at this line here:

if (callingMethod.Name.StartsWith("set_") == false || callingMethod.IsSpecialName == false)

I have been told it's happening because:

  • In the two lines above, it's using the StackTrace to find the calling member.
  • It looks one frame ahead, and extracts the method name and tries to cast to MethodInfo
StackTrace stackTrace = new StackTrace();
var callingMethod = stackTrace.GetFrame(1).GetMethod() as MethodInfo;
  • What actually happens, is that the calling method has been optimised away by the compiler, and so what comes back from stackTrace.GetFrame(1).GetMethod() is in fact a RuntimeConstructorInfo, not method info.
  • Then, it calls callingMethod.Name in the offending line, which throws a NullReferenceException

There are 7 references to this method, in CommandLineArgument.cs and CommandLineAction.cs

StackTrace is also used in the Get method of AttrOverride.cs but at the moment, it isn't being inlined (though the compiler is within its rights to at some point in the future!)

One workaround is to always build debug and release without optimisation.
image

Another is to decorate all of the calling members' sets like this:

public string Description
{
    get
    {
        return overrides.Get<ArgDescription, string>(Metadata, d => d.Description, string.Empty);
    }
    [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
    set
    {
        overrides.Set(value);
    }
}

With either of these methods, it runs fine.

What might be a better long-term solution is getting the name using CallerMemberName instead of stackTrace.GetFrame():
http://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.callermembernameattribute(v=vs.110).aspx

(This is .Net 4.5 though)

arrays of enum

Could you recognize arrays of enums?

e.g.
OptionsEnum[] arg1

Displaying help documention

How do you set up the help for a parser that uses the Action Framework?

If I paraphrase the superencoder code snippets, what I'd want/expect is something does:

superencoder -help

-- displays the help docs

superencoder encode -help

-- displays EncodeArgs help docs

superencoder clip -help

-- displays ClipArgs help docs

At the moment, what I actually get is the following behaviour:

superencoder -help

-- displays the help docs and the error "No action was specified"

superencoder encode -help

-- displays EncodeArgs help docs and the error "The argument 'Source' is required"

superencoder clip -help

-- displays ClipArgs help docs and the error "The argument 'Source' is required"

So basically:

  1. Can you add a -help property to a parent class (which has actions) without having to specify an Action?
  2. Is it possible to make arguments Required when the user tries to use them, but not, for example, if another property, bool Help = true?

Cheers!

Action framework usage displaying incorrectly.

This seems to be an issue with 1.7.0.0 and 1.8.0.0.

I tested a usage message generated from the code given in the Advanced Example of the readme and this was the output.

Usage: ConsoleApplication22 options

   OPTION        TYPE         POSITION   DESCRIPTION                                     
   -action       string*      0          Either encode or clip                           
   -encodeargs   encodeargs   NA         Encode a new video file                         
   -clipargs     clipargs     NA         Save a portion of a video to a new video file   

   EXAMPLE: superencoder encode fromFile toFile -encoder Wmv
   Encode the file at 'fromFile' to an AVI at 'toFile'

The expected output (and how it functions in 1.6.0.0) is

Usage: ConsoleApplication22 <action> options

EXAMPLE: superencoder encode fromFile toFile -encoder Wmv
Encode the file at 'fromFile' to an AVI at 'toFile'

Actions:

encode - Encode a new video file

   OPTION          TYPE      POSITION   DESCRIPTION                                                    
   -source (-s)    string*   1          The source video file                                          
   -output (-o)    string    2          Output file.  If not specfied, defaults to current directory   
   -encoder (-e)   encoder   NA         The type of encoder to use                                     


clip - Save a portion of a video to a new video file

   OPTION           TYPE      POSITION   DESCRIPTION                                                    
   -source (-so)    string*   1          The source video file                                          
   -output (-ou)    string    2          Output file.  If not specfied, defaults to current directory   
   -from (-f)       double    NA         The starting point of the video, in seconds                    
   -to (-t)         double    NA         The ending point of the video, in seconds                      
   -encoder (-en)   encoder   NA         The type of encoder to use                                     

Add ability to require arguments by group

A feature that I'd love to see in PowerArgs is the ability to require arguments by group.

For example, let's say my console application declares four switch arguments: A, B, C and D. I want to require users to choose exactly two switches: one from A/B and one from C/D. The following combinations would be valid:

myapp.exe -a -c
myapp.exe -a -d
myapp.exe -b -c
myapp.exe -b -d

But the following would NOT be valid:

myapp.exe -a -b
myapp.exe -c -d

This is a feature that CommmandLineParser supports via the MutuallyExclusiveSet property, and which prevents me from switching over to PA.

Non interactive mode

It would be great if there were some kind of option to put the argument parsing in "non interative mode" for applications running outside of a UI context, that will supress PromptIfMissing and TabCompletion.

C:\> MyApp.exe -noninteractive otheroptions

Usage string

GetUsage<T> doesn't allow to fully modify usage string. There is a need to get less detailed output in scriptcs/scriptcs - without type and position information.

Should we just add detailed parameter (true by default) to the GetUsage<T>, so if it's set - type and position information should be included, otherwise - not.

If this solution is suitable I can make a PR with it.

Question - Custom HelpHooks

How would I go about creating a custom help hook, that opened up a URL instead of writing to console, for example?

I created UrlHelpHook : HelpHook and overrode the AfterCancel event, but whichever one I call, it always performs both the HelpHook AfterCancel and the UrlHelpHook AfterCancel.

[AttributeUsage(AttributeTargets.Property|AttributeTargets.Parameter)]
    public class UrlHelpHookAttribute : HelpHook
    {
        private string helpUrl;

        public UrlHelpHookAttribute(string url)
            :base()
        {
            this.helpUrl = Path.GetFullPath(url);

            if (!File.Exists(this.helpUrl))
            {
                throw new ValidationArgException("File not found - " + url, new FileNotFoundException());
            }
        }

        public override void AfterCancel(HookContext context)
        {
            if (WriteHelp == false) return;

            Console.WriteLine(@"Launching default browser to display HTML ...");
            Process.Start(this.helpUrl);
        }
    }

Interactive mode raises an exception when started from PowerShell

I have an args class marked with [TabCompletion]. My console application seems to start fine in interactive mode from a command prompt but raises an exception when started from PowerShell (3.0 running from PowerShell ISE)

Unhandled Exception: 
System.IO.IOException: The handle is invalid.
   at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   at System.Console.GetBufferInfo(Boolean throwOnNoConsole, Boolean& succeeded)
   at System.Console.get_CursorLeft()
   at PowerArgs.StdConsoleProvider.get_CursorLeft()
   at PowerArgs.ConsoleHelper.ReadLine(String& rawInput, List`1 history, ITabCompletionSource[] tabCompletionHooks)
   at PowerArgs.TabCompletion.BeforeParse(HookContext context)
   at PowerArgs.ArgHook.HookContext.<RunBeforeParse>b__5(ArgHook h)
   at PowerArgs.ArgHook.HookContext.RunHook(Func`2 orderby, Action`1 hookAction)
   at PowerArgs.ArgHook.HookContext.RunBeforeParse()
   at PowerArgs.Args.ParseInternal(CommandLineArgumentsDefinition definition, String[] input)
   at PowerArgs.Args.ParseInternal[T](String[] input)
   at PowerArgs.Args.<>c__DisplayClass1`1.<ParseAction>b__0()
   at PowerArgs.Args.Execute[T](Func`1 argsProcessingCode)
   at PowerArgs.Args.ParseAction[T](String[] args)
   at PowerArgs.Args.<>c__DisplayClass11`1.<InvokeAction>b__10(String[] a)
   at PowerArgs.REPL.DriveREPL[T](TabCompletion t, Func`2 eval, String[] args)
   at PowerArgs.Args.<>c__DisplayClass11`1.<InvokeAction>b__f()
   at PowerArgs.Args.Execute[T](Func`1 argsProcessingCode)
   at PowerArgs.Args.InvokeAction[T](String[] args)
   at TurfSport.BackOffice.Services.Console.Program.Main(String[] args) in C:\svn\turfsport\TurfSportBackOffice\TurfSport4\trunk\TurfSport.BackOffice.Services.Console\Program.cs:line 26
    [TabCompletion]
    [ArgExceptionBehavior(ArgExceptionPolicy.StandardExceptionHandling)]
    [ArgExample("info", "About info")]
    public class ServiceActions
    {
        [ArgActionMethod, ArgDescription("Get info about the service console.")]
        public void Info(Actions.Info info)
        {
            info.DoAction();
        }
    }

And I am invoking using

private static void Main(string[] args)
        {
            log4net.Config.XmlConfigurator.Configure();

            Args.InvokeAction<ServiceActions>(args);
        }

Descrition and default behavior.

First off - nice work, this is the best Args parser I could find for c#. Here my suggestion:

I end up replicating something like this:

            if (args.Length > 0) { 
                    try { 
                        var cliParameter = PowerArgs.Args.Parse<CliParameter>(args);
                        if (cliParameter.Help) {
                            Console.WriteLine( CliParameter.Description );
                            PowerArgs.ArgUsage.GetStyledUsage<CliParameter>().Write();
                            return;
                        }
                        # Do more work here ....  
                        return;
                    }
                    catch (PowerArgs.ArgException)
                    {
                        ;
                    }
            }
            PowerArgs.ArgUsage.GetStyledUsage<CliParameter>().Write();

How about adding:

  1. Support for having a [Description] tag in the Cli-Parameter class to provide some text that is prepended on the usage to explain what the problem does.
  2. Handling the above as a default behavior (eliminating the check for no-args and exceptions) with e.g. PowerArgs.Args.Parse(args, HandleIt = true );

Any thoughts?

ArgIgnoreCase

Hi,

Is ArgIgnoreCase honoured when using an enum as a property. I know System.Enum.TryParseEnum allows you to pass whether to ignore case.

Regards,
Alex

Allow applying multiple shortcuts to the same arg.

Currently the ArgShortcutAttribute is set to AllowMultiple=false. This prevents multiple shortcuts for the same arg.

I'd like to do something like this.

[ArgShortcut("h")]
[ArgShortcut("?")]
public bool Help { get; set; }

Allowing a user to specify -help, -h OR -?.

How to suppress UnexpectedArgException

I have a BaseArgs class and a bunch of derived specialized argument classes. The BaseArgs class has an Enum for the action to be invoked. Actions are complex enough to warrant their own specific classes to hold their args.

I was hoping to use Args.Parse<BaseArgs>(args) to get the Action enum, then based on the result, use Args.Parse<DerivedArgs>(args), since DerivedArgs's type corresponds to the Action I got from the previous call. Is there a way to do this, or would I have to just try to parse as each derived class and catch the exceptions myself?

Multiple ArgActionType attributes or multiple Types in the attribute

I would like to see support for the deferred action methods to be placed in multiple, separate classes which should promote better separation of concerns and cleaner code.

In other words doing this:

[ArgActionType(AActions)]
[ArgActionType(BActions)]
public class MainActions { ... }

public class AActions { ... }
public class BActions { ... }

Or allow for multiple types in a single attribute such as:

[ArgActionType(AActions, BActions)]
public class MainActions { ... }

public class AActions { ... }
public class BActions { ... }

ArgUsage.GenerateUsageFromTemplate omits shortcuts

The obsolete GetStyledUsage displays shortcuts in addition to the long-form argument names, but the new GenerateUsageFromTemplate does not. I couldn't find any documentation on how to compose a template or find alternate options besides the default, so for now I have to go back to the obsolete GetStyledUsage and suppress the compiler warning. :-)

add ability to check if an arg was provided by a user

First let me say how awesome this lib is and thank you for it!

one feature idea i have is that I would really like to be able to say

parsed.AnArge.WasProvidedByUser()

naturally the method call can be anything you want it to be but the feature is something i would like to have.

this is partly because i currently have 3 date arguments, start and end date or an as of date. either start and end date must be provided or as of date so i am not able to mark them all as required. looking into solving this with a custom validator but it seems like i will still not be able to leverage the prompt if not provided attribute so if you can come up with another solution that would allow that, maybe an argument dependency option.

[ArgRequiredWith(ArgClass.OtherArg)]

[ArgRequireIfOtherArgumentNotProvided(ArgClass.OtherArg)]

thanks again for everything!

"double dash" option for command options

Would be fantastic to be able to use a "double dash" for options, or sub commands of a single dash.

I.e.

LogQuery -log --html -dst:C:\la\

The : would also be great :)

--Brendan

GetUsage<T>() fails when called from unit test

When called via a unit test, GetUsage()'s call to Assembly.GetEntryAssembly() returns null which causes a null reference exception when trying to access the assembly's location.

The following test code illustrates the problem:

using Microsoft.VisualStudio.TestTools.UnitTesting;
using PowerArgs;

namespace ArgsTests
{
    [TestClass]
    public class ArgUsageTests
    {

        [TestMethod]
        public void TestArgUsage()
        {
            string[] args = new string[] { "test" };
            var commandArgs = Args.Parse<SomeArgs>(args);
            string usage = ArgUsage.GetUsage<SomeArgs>();
            Assert.IsTrue(usage.Contains("Usage"));
        }
    }

    public class SomeArgs
    {
        [ArgDescription("File name")]
        [ArgPosition(0)]
        public string FileName { get; set; }
    }

}

[Retitled] - Support aliases (or shortcuts) for action names

A working class with action methods is now throwing exceptions after upgrading from 1.8.? to 2.0.?. Neither the class containing the action methods nor the class invoking it has changed. Is the syntax new, or are new attributes necessary? (I didn't see any new arguments to the ArgActionMethod() attribute constructor...)

Will try rolling back to 1.8 for now.

DefaultValueAttribute vs Constructor

In many command line parsers I see custom DefaultValueAttribute or similar but I can set default values for properties in constructor of my args class. And my question is: what is purpose of DefaultValueAttribute? Do we really need it? One reason in my head is API beauty because we set default values near others metadata like Required.

Exceptions hierarchy

In current version, ArgException is used for almost every exceptional situation - for args parsing errors, validating errors, and so on. Even such code, that's related to library using, uses ArgException:

var assembly = Assembly.GetEntryAssembly();
if (assembly == null)
{
    throw new ArgException("PowerArgs could not determine the name of your executable automatically.  This may happen if you run GetUsage<T>() from within unit tests.  Use GetUsageT>(string exeName) in unit tests to avoid this exception.");
}

The main issue that ArgException isn't useful, when it comes to proper error handling. For example:

     try
        {
            var parsed = Args.Parse<MyArgs>(args);
            Console.WriteLine("You entered string '{0}' and int '{1}'", parsed.StringArg, parsed.IntArg);
        }
        catch (ArgException ex)
        {
            Console.WriteLine(ex.Message);
            Console.WriteLine(ArgUsage.GetUsage<MyArgs>());
        }

Here we can't react properly - we just don't have information about exceptional situation - just a string message and that's all. We have 2 ways: to write message to the user (can be kinda cryptic for him) or to parse the string message (so we can know more about exceptional situation and react to it in other ways).

Solving this issue should involve exceptional situtions handling refactoring and creating of some exceptions hierarchy for the goods of library API.

Request: Enhanced enum & flags support

It would be really useful to have more powerful support for enum features, specifically (in order of importance):

  • Bitmasked enum (flag) values as arguments without custom type converters or ILists
  • ArgDescription attributes on enum values, which appear in the generated help text
  • ArgShortcut attributes on enum values, functioning the same as on parameter-level arguments

Get list of "unmatched" arguments

It would be great to somehow get a list of "unmatched" arguments when calling Args.Parse<T>. For scriptcs, this would be useful for passing those parameters further down to the running script (see scriptcs #173).

This could be done in many ways, i.e.:

  • Add an overload to Args.Parse<T> that takes a callback for unmatched argument handling:
var args = Args.Parse<MyArguments>(args, unmatchedArgument => 
    {
        // Do something with the unmatchedArgument, i.e. pass it to script...
    }
  • Catching an UnmatchedArgumentException that has a list of arguments (could be part of #11):
try
{
    var args = Args.Parse<MyArguments>(args);
} 
catch (UnmatchedArgumentException ex)
{
    // Do something with ex.UnmatchedArguments...
}
  • Add a TryParse<T> method, that returns false when an argument couldn't be matched with a property and adds the arguments to the list.
var unmatchedArguments = new List<KeyValuePair<string, string>>();
if (!Args.TryParse<MyArguments>(out unmatchedArguments, args))
{
    // Do something with unmatchedArguments
}

I personally like the first solution. Is this something that can be achieved easily? I'd be happy to do the work ๐Ÿ˜„

Help text not displaying available Enum string values, when property type is Enum[]

If one of my properties is of type Enum "Category", in the help text displayed, I get a very useful list of the categories available:
image

If I decorate this enum with the [Flags] attribute, and specify that multiple categories can be selected, I can change the type of my property to Category[] and PowerArgs is clever enough to parse a comma separated list of categories, and store them against my property.

But
In the help text, it no longer displays the list of Categories the user can choose from:
image

I don't think this is a Reviver issue, so is there a way to keep that functionality in?

Arg Commands

Hi,

Would it be possible to set-up arguments as commands like in linux. For example "apt-get install" and then the command can have options (which you have already), though it would be nice if the long version of the options could be treated with a -- rather than -.

You can look at http://linux.die.net/man/8/apt-get to see what I mean.

Regards,
Alex

Parameters seem to behave differently in the latest version

Hi,

I have an app that uses PowerArgs. The usage looks like the following:

Usage: spec options

OPTION TYPE POSITION DESCRIPTION

-path (-p) String 0 The path to search all the Spec assemblies. The default is spec.

-example (-e) String NA The example to execute. This could be a spec, example group or an e
xample.
-pattern (-P) String NA Load files matching pattern. The default is Specs.

-output (-o) String NA The output path of the test results. The default is test-results.xm
l.
-format (-f) ConsoleFormatterType NA Specifies what format to use for output.

-dryrun (-d) Switch NA Invokes formatters without executing the examples.

-version (-v) Switch NA Display the version.

-colour (-c) Switch NA Enable colour in the output.

-help (-h) Switch NA You're looking at it.

EXAMPLE: spec.(exe|sh) spec
Execute all the specs in the folder spec.

I use to be able to run the program as spec.exe artifacts -P Unit.Specs. Now I get

Unexpected Argument: artifacts

Now if I run spec.exe -p artifacts -P Unit.Specs it tells me

Argument specified more than once: path

So this is treating it as -p and -P as the same option, which I am guessing is incorrect.

The only way for me to get it working is to specify the long form:

spec.exe -path artifacts -pattern Unit.Specs

Hopefully this highlights my issues:

CustomReviver does not work if argument type and reviver are not defined in the same assembly

The cause is:

In ValidateArgScaffold method, ArgRevivers.CanRevive is called with the type of the property. But ArgRevivers.CanRevive loads custom revivers by searching the assembly of the type passed in. So if the type and custom reviver are not defined in the same assembly, the custom reviver cannot be found.

I encountered the problem when using System.Net.Mail.MailAddress as argument type. The code is pasted here to help you debug the issue: (in F#)

type MailAddressReviver()=
     [<ArgReviver>]
     static member Revive (key:string) (address:string) = 
           new System.Net.Mail.MailAddress(address)

 [<TabCompletion>]
 type MyArgs()=
     [<ArgDescription("Show this help information")>]
     [<ArgShortcut("h")>]
     member val Help = false with get, set

     [<ArgDescription("Mail to")>]
     [<ArgShortcut("mt")>]
     member val MailTo:System.Net.Mail.MailAddress = null with get, set

ArgActionMethods must declare 1 parameter...

In the ActionFrameworkV2 tests, I clearly see parameterless actions being invoked, but get the above-named exception when I attempt this myself. Has this feature not made it into the current Nuget version yet? (I'm using 1.8)

HelpHook - ArgCancelProcessingException not being thrown all the way up

How are you supposed to use Args.Parse together with HelpHook?

I've seen this example:

var parsed = Args.Parse<MyArgs>(args);
if (parsed.Help)
{
      ArgUsage.GetStyledUsage<MyArgs>().Write();
}

but it seems to make the HelpHook redundant.

For example:

From my Program.Main, I call this:

try
{
    var parsed = Args.Parse<MyArgs>(args);

    Console.WriteLine("Your name is {0}", parsed.Name);
}
catch(ArgException ex)
{
    ArgUsage.GetStyledUsage<MyArgs>().Write();
    Console.WriteLine(ex.Message);
}

I have a bool property Help, and it is decorated with the HelpHook attribute.

If I pass the argument -help (or -?) it runs the AfterCancel method of HelpHook, but the ArgCancelProcessingException eventually gets caught by:

private static T Execute<T>(Func<T> argsProcessingCode) where T : class
{
    executeRecursionCounter++;
    ArgHook.HookContext.Current = new ArgHook.HookContext();

    try
    {
        return argsProcessingCode();
    }
    catch (ArgCancelProcessingException ex)
    {
        if (executeRecursionCounter > 1)
        {
            throw;
        }

        return CreateEmptyResult<T>(ArgHook.HookContext.Current, cancelled: true);
    }

and CreateEmptyResult returns null, later giving "Object reference not set to an instance of an object" when it tries to access parsed.Name.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.