Gendarme.Rules.Portability

Gendarme's portability rules are located in the Gendarme.Rules.Portability.dll assembly. Latest sources are available from anonymous SVN (http://anonsvn.mono-project.com/viewvc/trunk/mono-tools/gendarme/rules/Gendarme.Rules.Portability/).

Rules

DoNotHardcodePathsRule

This rule check for strings that contains valid filenames, either under Unix or Windows operating systems file systems. Such filenames are often not portable across operating systems (e.g. different path separators). To ensure correct cross-platform functionality they should be replaced by calls to Path.Combine and/or Environment.GetFolderPath.

Bad example:

void ReadConfig ()
{
    using (FileStream fs = File.Open ("~/.local/share/myapp/user.config")) {
        // read configuration
    }
}

Good example:

void ReadConfig ()
{
    string config_file = Environment.GetFolderPath (SpecialFolder.LocalApplicationData);
    config_file = Path.Combine (Path.Combine (config_file, "myapp"), "user.config");
    using (FileStream fs = File.Open (config_file)) {
        // read configuration
    }
}

Notes

  • This rule is available since Gendarme 2.0

ExitCodeIsLimitedOnUnixRule

This rule applies to all executable (i.e. EXE) assemblies. Something that many Windows developers might not be aware of is that on Unix systems, process exit code must be between zero and 255, unlike in Windows where it can be any valid integer value. This rule warns if the returned value might be out of range either by:

  • returning an unknown value from int Main();
  • setting the Environment.ExitCode property; or
  • calling Environment.Exit(exitCode) method.

An error is reported in case number which is definitely out of range is being returned as an exit code.

Bad example:

class MainClass {
    static int Main ()
    {
        Environment.ExitCode = 1000;
        Environment.Exit (512);
        return -1;
    }
}

Good example:

class MainClass {
    static int Main ()
    {
        Environment.ExitCode = 42;
        Environment.Exit (100);
        return 1;
    }
}

Notes

  • This rule is available since Gendarme 2.0

FeatureRequiresRootPrivilegeOnUnixRule

This rule check usage of features that are, by default, restricted under Unix.

  • System.Net.NetworkInformation.Ping: This type can only be used by root on Unix systems. As an alternative you can execute the ping command and parse it's result.
  • System.Diagnostics.Process: The PriorityClass property can only be set to Normal by non-root users. To avoid this problem you can do a platform check before assigning a priority.


Bad example:

process.PriorityClass = ProcessPriorityClass.AboveNormal;
process.Start ();

Good example:

if (Environment.OSVersion.Platform != PlatformID.Unix) {
    process.PriorityClass = ProcessPriorityClass.AboveNormal;
}
process.Start ();

MonoCompatibilityReviewRule

This rule uses MoMA definition files to analyze assemblies and warns if called methods are:

  • marked with a [MonoTODO] attribute;
  • throw a NotImplementedException; or
  • do not exist in the current version of Mono::

The rule looks for the definitions in ~/.local/share/Gendarme/definitions.zip. If the file is missing it will try to download the latest version.

Notes

  • This rule does not replace MoMA (which is obviously the easiest solution for Windows developers). It's goal is to help analyze multiple portability issues from the Linux side (where Gendarme is most likely being used)

NewLineLiteralRule

This rule warns about any methods, including properties, that are using the literal \r and/or \n for new lines. This isn't portable across operating systems. To ensure correct cross-platform functionality they should be replaced by Environment.NewLine.

Bad example:

Console.WriteLine ("Hello,\nYou should be using Gendarme!");

Good example:

Console.WriteLine ("Hello,{0}You must be using Gendarme!", Environment.NewLine);

Feedback

Please report any documentation errors, typos or suggestions to the Gendarme Google Group (http://groups.google.com/group/gendarme). Thanks!