diff options
-rw-r--r-- | doc/advopt.txt | 1 | ||||
-rw-r--r-- | doc/nimrodc.txt | 52 | ||||
-rw-r--r-- | lib/pure/os.nim | 65 |
3 files changed, 106 insertions, 12 deletions
diff --git a/doc/advopt.txt b/doc/advopt.txt index 08465e457..7a11e9041 100644 --- a/doc/advopt.txt +++ b/doc/advopt.txt @@ -12,6 +12,7 @@ Advanced commands: module dependency graph //dump dump all defined conditionals and search paths //check checks the project for syntax and semantic + //pretty homogenizes source code style //idetools compiler support for IDEs: possible options: --track:FILE,LINE,COL track a file/cursor position --trackDirty:DIRTY_FILE,ORIG_FILE,LINE,COL diff --git a/doc/nimrodc.txt b/doc/nimrodc.txt index 428c42f39..90fad7f9c 100644 --- a/doc/nimrodc.txt +++ b/doc/nimrodc.txt @@ -540,6 +540,58 @@ in C/C++). **Note**: This pragma will not exist for the LLVM backend. +Source code style +================= + +Nimrod allows you to `mix freely case and underscores as identifier separators +<manual.html#identifiers-keywords>`_, so variables named ``MyPrecioussInt`` and +``my_preciouss_int`` are equivalent: + +.. code-block:: Nimrod + var MyPrecioussInt = 3 + # Following line compiles fine! + echo my_preciouss_int + +Since this can lead to many variants of the same source code (you can use +`nimgrep <nimgrep.html>`_ instead of your typical ``grep`` to ignore style +problems) the compiler provides the command ``pretty`` to help unifying the +style of source code. Running ``nimrod pretty ugly_test.nim`` with this +example will generate a secondary file named ``ugly_test.pretty.nim`` with the +following content: + +.. code-block:: Nimrod + var MyPrecioussInt = 3 + # Following line compiles fine! + echo MyPrecioussInt + +During execution the ``pretty`` command will also run on Nimrod's standard +library, since it doesn't differentiate the standard library as something +special, and hence will warn of many *errors* which are out of your hand to +fix, creating respective ``.pretty.nim`` files all the way. You can ignore +these errors if they don't belong to your source and simply compare your +original version to the new pretty one. In fact, running ``pretty`` on our test +file will show the following:: + + Hint: ugly_test [Processing] + ugly_test.nim(1, 4) Error: name should be: myPrecioussInt + ugly_test.nim(1, 4) Error: name should be: myPrecioussInt + +At the moment ``pretty`` will homogenize the style of symbols but will leave +important changes for you to review. In this case the command is warning that a +variable name should not start with a capital letter, which is usually reserved +to `object types <tut2.html#objects>`_. To learn about the accepted `camel case +style <https://en.wikipedia.org/wiki/Camelcase>`_ read `Coding Guidelines in +the Internals of Nimrod Compiler <intern.html#coding-guidelines>`_ or `Coding +Guidelines <https://github.com/Araq/Nimrod/wiki/Coding-Guidelines>`_ and `NEP 1 +: Style Guide for Nimrod Code +<https://github.com/Araq/Nimrod/wiki/NEP-1-:-Style-Guide-for-Nimrod-Code>`_ +from the Nimrod `GitHub wiki<https://github.com/Araq/Nimrod/wiki>`_. + +This command is safe to run because it will never attempt to overwrite your +existing sources, but the respective ``.pretty.nim`` files **will** be +overwritten without notice. + + DynlibOverride ============== diff --git a/lib/pure/os.nim b/lib/pure/os.nim index a7f4f7d91..a70bfa7f1 100644 --- a/lib/pure/os.nim +++ b/lib/pure/os.nim @@ -955,11 +955,12 @@ proc copyFile*(source, dest: string) {.rtl, extern: "nos$1", ## ## If this fails, `EOS` is raised. On the Windows platform this proc will ## copy the source file's attributes into dest. On other platforms you need - ## to use getFilePermissions and setFilePermissions to copy them by hand (or - ## use the convenience copyFileWithPermissions() proc), otherwise `dest` will - ## inherit the default permissions of a newly created file for the user. If - ## `dest` already exists, the file attributes will be preserved and the - ## content overwritten. + ## to use `getFilePermissions() <#getFilePermissions>`_ and + ## `setFilePermissions() <#setFilePermissions>`_ to copy them by hand (or use + ## the convenience `copyFileWithPermissions() <#copyFileWithPermissions>`_ + ## proc), otherwise `dest` will inherit the default permissions of a newly + ## created file for the user. If `dest` already exists, the file attributes + ## will be preserved and the content overwritten. when defined(Windows): when useWinUnicode: let s = newWideCString(source) @@ -1363,7 +1364,13 @@ proc createDir*(dir: string) {.rtl, extern: "nos$1", tags: [FWriteDir].} = proc copyDir*(source, dest: string) {.rtl, extern: "nos$1", tags: [FWriteIO, FReadIO].} = - ## Copies a directory from `source` to `dest`. If this fails, `EOS` is raised. + ## Copies a directory from `source` to `dest`. + ## + ## If this fails, `EOS` is raised. On the Windows platform this proc will + ## copy the attributes from `source` into `dest`. On other platforms created + ## files and directories will inherit the default permissions of a newly + ## created file/directory for the user. To preserve attributes recursively on + ## these platforms use `copyDirWithPermissions() <#copyDirWithPermissions>`_. createDir(dest) for kind, path in walkDir(source): var noSource = path.substr(source.len()+1) @@ -1507,14 +1514,17 @@ proc copyFileWithPermissions*(source, dest: string, ignorePermissionErrors = true) = ## Copies a file from `source` to `dest` preserving file permissions. ## - ## This is a wrapper proc around copyFile, getFilePermissions and - ## setFilePermissions on non Windows platform. On windows this proc is just a - ## wrapper for copyFile since that proc already copies attributes. + ## This is a wrapper proc around `copyFile() <#copyFile>`_, + ## `getFilePermissions() <#getFilePermissions>`_ and `setFilePermissions() + ## <#setFilePermissions>`_ on non Windows platform. On Windows this proc is + ## just a wrapper for `copyFile() <#copyFile>`_ since that proc already + ## copies attributes. ## - ## On non windows systems permissions are copied after the file itself has + ## On non Windows systems permissions are copied after the file itself has ## been copied, which won't happen atomically and could lead to a race - ## condition. If ignorePermissionErrors is true, errors while reading/setting - ## file attributes will be ignored, otherwise will raise `OSError`. + ## condition. If `ignorePermissionErrors` is true, errors while + ## reading/setting file attributes will be ignored, otherwise will raise + ## `OSError`. copyFile(source, dest) when not defined(Windows): try: @@ -1523,6 +1533,37 @@ proc copyFileWithPermissions*(source, dest: string, if not ignorePermissionErrors: raise +proc copyDirWithPermissions*(source, dest: string, + ignorePermissionErrors = true) {.rtl, extern: "nos$1", + tags: [FWriteIO, FReadIO].} = + ## Copies a directory from `source` to `dest` preserving file permissions. + ## + ## If this fails, `EOS` is raised. This is a wrapper proc around `copyDir() + ## <#copyDir>`_ and `copyFileWithPermissions() <#copyFileWithPermissions>`_ + ## on non Windows platforms. On Windows this proc is just a wrapper for + ## `copyDir() <#copyDir>`_ since that proc already copies attributes. + ## + ## On non Windows systems permissions are copied after the file or directory + ## itself has been copied, which won't happen atomically and could lead to a + ## race condition. If `ignorePermissionErrors` is true, errors while + ## reading/setting file attributes will be ignored, otherwise will raise + ## `OSError`. + createDir(dest) + when not defined(Windows): + try: + setFilePermissions(dest, getFilePermissions(source)) + except: + if not ignorePermissionErrors: + raise + for kind, path in walkDir(source): + var noSource = path.substr(source.len()+1) + case kind + of pcFile: + copyFileWithPermissions(path, dest / noSource, ignorePermissionErrors) + of pcDir: + copyDirWithPermissions(path, dest / noSource, ignorePermissionErrors) + else: discard + proc inclFilePermissions*(filename: string, permissions: set[TFilePermission]) {. rtl, extern: "nos$1", tags: [FReadDir, FWriteDir].} = |