Number of lines from XCode project [duplicate] - xcode

Is there a way to determine how many lines of code an Xcode project contains? I promise not to use such information for managerial measurement or employee benchmarking purposes. ;)

I see this floating around and use it myself:
find . "(" -name "*.m" -or -name "*.mm" -or -name "*.cpp" -or -name "*.swift" ")" -print0 | xargs -0 wc -l

Check out CLOC.
cloc counts blank lines, comment lines, and physical lines of source code in many programming languages.
(Legacy builds are archived on SourceForge.)

I have been using CLOC as mentioned by Nathan Kinsinger and it is fairly easy to use. It is a PERL script that you can add and run from your project directory.
PERL is already part of Mac OS and you can invoke the script this way to find out your number of lines you have written:
perl cloc-1.56.pl ./YourDirectoryWhereYourSourcesAre
This is an example of output i got from such command:
176 text files.
176 unique files.
4 files ignored.
http://cloc.sourceforge.net v 1.56 T=2.0 s (86.0 files/s, 10838.0 lines/s)
-------------------------------------------------------------------------------
Language files blank comment code
-------------------------------------------------------------------------------
Objective C 80 3848 1876 11844
C/C++ Header 92 980 1716 1412
-------------------------------------------------------------------------------
SUM: 172 4828 3592 13256
-------------------------------------------------------------------------------

Open up Terminal.app, go into your project's root directory, and run this command:
For Swift only:
find . \( -iname \*.swift \) -exec wc -l '{}' \+
For Obj-C only:
find . \( -iname \*.m -o -iname \*.mm -o -iname \*.h \) -exec wc -l '{}' \+
For Obj-C + Swift:
find . \( -iname \*.m -o -iname \*.mm -o -iname \*.h -o -iname \*.swift \) -exec wc -l '{}' \+
For Obj-C + Swift + C + C++:
find . \( -iname \*.m -o -iname \*.mm -o -iname \*.c -o -iname \*.cc -o -iname \*.h -o -iname \*.hh -o -iname \*.hpp -o -iname \*.cpp -o -iname \*.swift \) -exec wc -l '{}' \+
Terminal quick tips:
ls: list directory contents
cd: change directory
Press tab to autocomplete
Remember to put "\" backslash before spaces
I suggest going one folder down from the main project so you get rid of code count from the frameworks

In terminal, change into the project directory and run:
find . -type f -print0 | xargs -0 cat | wc -l
If you want only certain file types, try something like
find . -type f -name \*.[ch]* -print0 | xargs -0 cat | wc -l

open terminal
navigate to your project
execute following command inside your project:
find . -path ./Pods -prune -o -name "*.swift" -print0 ! -name "/Pods" | xargs -0 wc -l
Or:
find . -path ./Pods -prune -o -name "*[hm]" -print0 ! -name "/Pods" | xargs -0 wc -l
(*Excluding pod files count from total count)

Check out Xcode Statistician, it does exactly what you want. It also provides other interesting statistics so is worth a run for fun now and then.
Note that it will not look inside real folders, though it will look in groups. Odds are you aren't using real folders so it'll work great. If you are using folders then you just have to do the count in each folder and add them together.
Note: As of June, 2012, it seems this does not work properly with the latest versions of Xcode.

If you go to your project's directory in terminal and enter:
find . "(" -name "*.h" -or -name "*.m" -or -name "*.mm" -or -name "*.hpp" -or -name "*.cpp" -or -name "*.c" -or -name "*.cc" -or -name "*.swift" ")" -print0 | xargs -0 wc -l
That will give you a project breakdown, as well as the line total for each file and the project as a whole.

Steps to implement CLOC library in Mac as below:
Open Terminal.
Install Homebrew by copying and pasting the below command in the Terminal (including double quotes).
ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
Enter system password if asked.
You will see the terminal screen as below.
System will popup so many permissions, allow all the permissions
If everything goes fine, you will see terminal screen as below,
Now its time to install CLOC using below command.
brew install cloc
Navigate to the project directory and run either of the following commands.
cloc . --exclude-dir=Pods (to exclude pod files)
cloc . (including pod files)
If everything goes fine, it will display the number of lines of code as below,

Nozzi's version doesn't work for me, but this one:
find . -type f -print0 | xargs -0 cat | wc -l

A quick & easy way:
Use a regex search (Find Navigator, choose Find > Regular Expression).
.\n
Works conveniently with Xcode search scopes and you can easily customize it to whatever type of line you'd like to count ;).

You can install SLOCCount through MacPorts. Or, more crudely, you can use wc -l.

I am not familiar with xcode, but if all you need is to count the number of lines from all those specific files within a directory tree, you may use the following command:
find .... match of all those files ... -exec wc -l {} +
Following Joshua Nozzi's answer, in GNU find the regular expression for such files would be like:
find . "(" -name "*.m" -or -name "*.mm" -or -name "*.cpp" -or -name "*.swift" ")" -exec wc -l {} +
or even
find -regex ".*\.\(m\|mm\|cpp\|swift\)$" -exec wc -l {} +
this uses a regular expression to match all files ending in either .m, .mm, .cpp or .swift. You can see more information about those expressions in How to use regex in file find.
If you are working with Mac OS find, then you need a slightly different approach, as explained by Motti Shneor in comments:
find -E . -regex ".*\.([hmc]|mm|cp+|swift|pch)$" -exec wc -l {} +
Both will provide an output on the form of:
234 ./file1
456 ./file2
690 total
So you can either keep it like this or just pipe to tail -1 (that is, find ... | tail -1) so that you just get the last line being the total.

line-counter is a good alternative. It's lighter than CLOC and much more powerful and easier to use than other commands.
A quick overview
This is how you get the tool
$ pip install line-counter
Use line command to get the file count and line count under current directory (recursively)
$ line
Search in /Users/Morgan/Documents/Example/
file count: 4
line count: 839
If you want more detail, just use line -d.
$ line -d
Search in /Users/Morgan/Documents/Example/
Dir A/file C.c 72
Dir A/file D.py 268
file A.py 467
file B.c 32
file count: 4
line count: 839
And the best part of this tool is, you can add .gitignore like configure file to it. You can set up rules to select or ignore what kind of files to count just like what you do in '.gitignore'. Yes, this tool is just invented to make knowing how many lines I have easier.
More description and usage is here: https://github.com/MorganZhang100/line-counter
I'm the author of this simple tool. Hope it can help somebody.

Related

jenkins bash script - remove directory path from find command results

I need to search in my dist directory for minified .js and .css files within jenkins.
I have a bash script with a find cmd, like this:
for path in $(/usr/bin/find dist/renew-online -maxdepth 1 -name "*.js" -or -name "*.css" -type f); do
# URL of the JavaScript file on the web server
url=$linkTarget/$path
echo "url=$linkTarget/$path"
Where linkTarget is: http://uat.xxxx.com/renew-online.
I want to attach the minified files form dist/renew-online to the linkTarget,
for example:
http://uat.xxxx.com/renew-online/main-es2015.cf7da54187dc97781fff.js
BUT I keeping getting: http://uat.xxxx.com/renew-online/dist/renew-online/main-es2015.cf7da54187dc97781fff.js
I've tried with -maxdepth 0 also but can't get the correct url - newbie at scripts!
Hopefully one of you guys can help, thanks your time
This can be achieved by using 'find' command only:
/usr/bin/find dist/renew-online -maxdepth 1 \( -name "*.js" -o -name "*.css" \) -type f -printf "$linkTarget/%f\n"
It is also recommended to isolate 'or' statements inside round brackets.
This is more a bash question than a jenkins one and you have multiple ways to do it.
If all your files are in a single path, and actually you are forcing with the depth, you can use a cut
for path in $(/usr/bin/find dist/renew-online -maxdepth 1 -name "*.js" -or -name "*.css" -type f | cut -d'/' -f2); do
In the other hand the here https://serverfault.com/questions/354403/remove-path-from-find-command-output by the usage of -printf '%f\n'
Please note as well that the usage of find in a for loop is fragile and it is recommended to use a while https://github.com/koalaman/shellcheck/wiki/SC2044
EDIT
the field used in cut depends on the folders you have in your find syntax. The most accurate way is the one in the serverfault link above

How to write the wc's stdout into a file?

The below command will show how many characters contains in every file in current directory.
find -name '*.*' |xargs wc -c
I want to write the standout into a file.
find -name '*.*' |xargs wc -c > /tmp/record.txt
It encounter an issue:
wc: .: Is a directory
How to write all the standard output into a file?
Why -name '*.*'? That will not find every file and will find directories. You need to use -type f, and better than piping the result to xargs is using -exec:
find . -type f -maxdepth 1 -exec wc -c {} + > /tmp/record.txt
-maxdepth 1 guarantees that the search won't dive in subdirectories.
I think you maybe meant find |xargs wc -c?
find -name '.' just returns .
Filter only files, if you want only files.
find -type f

Why is my find and xargs copy command working for one folder and not for the other?

I have two directories, x86_64 and i386.
I want to filter out test RPMS from both of these folders and place them in a seperate one; test_release/{version}-x86_64/x86_64 and test_release/{version}-i386/i386, respectively.
So my first command works fine:
find x86_64/ -type f -name '*test*' -o -name '*demo*' -o -name '*log*' |
xargs cp -rt test_release/${RELEASE}-x86_64/x86_64
My second command is exactly the same, except with different folder names:
find i386/ -type f -name '*test*' -o -name '*demo*' -o -name '*log*' |
xargs cp -rt test_release/${RELEASE}-i386/i386
Only the second command gives me the error:
cp: missing file operand
Am I missing something?
The error happens because your find command doesn't return any files. Disappointingly, xargs still runs cp, but ends up calling it with too few arguments; and so you get the error message.
GNU xargs has an -r option which solves this specific case; but a more portable and more robust solution is to use find -exec.
find i386/ -type f -name '*test*' -o -name '*demo*' -o -name '*log*' \
-exec cp -rt "test_release/${RELEASE}-i386/i386" {} +
The + statement terminator for -exec is not entirely portable, but if you have cp -t I guess you're on Linux, or at least are using a recent find (GNU or not GNU. If not, replacing + with \; is a workaround, though it will end up running more processes than the equivalent xargs construct).

bash: Filtering out directories and extensions from find?

I'm trying to find files modified recently with this
find . -mtime 0
Which gives me
en/content/file.xml
es/file.php
en/file.php.swp
css/main.css
js/main.js
But I'd like to filter out the en and es directories but would like to grab anything else. In addition, I'd like to filter out .swp files from the results of those.
So I want to get back:
css/main.css
js/main.js
xml/foo.xml
In addition to every other file not within es/en and not ending in .swp
properly, just in find:
find -mtime 0 -not \( -name '*.swp' -o -path './es*' -o -path './en*' \)
The -prune command prevents find form descending down the directories you wish to avoid:
find . \( -name en -o -name es \) -prune , -mtime 0 ! -name "*.swp"
Try this:
find . -mtime 0 | grep -v '^en' | grep -v '^es'
Adding the cap character at the beginning of the pattern given to grep ensures that it is a must to find the pattern at the start of the line.
Update: Following Chen Levy's comment(s), use the following instead of the above
find . -mtime 0 | grep -v '^\./en' | grep -v '^\./es'
find is great but the implementation in various UNIX versions differs, so I prefer solutions that are easier to memorize and using commands with more standard options
find . -mtime 0 | grep -v '^en' | grep -v '^es' | grep -v .swp
The -v flag for grep makes it return all lines that don't match the pattern.
The -regex option of find(1) (which can be combined with the -E option to enable extended regular expressions) matches the whole file path as well.
find . -mtime 0 -not \( -name '*.swp' -o -regex '\./es.*' -o -regex '\./en.*' \)
find "$(pwd -P)" -mtime 0 -not \( -name '*.swp' -o -regex '.*/es.*' -o -regex '.*/en.*' \)

How to find out how many lines of code there are in an Xcode project?

Is there a way to determine how many lines of code an Xcode project contains? I promise not to use such information for managerial measurement or employee benchmarking purposes. ;)
I see this floating around and use it myself:
find . "(" -name "*.m" -or -name "*.mm" -or -name "*.cpp" -or -name "*.swift" ")" -print0 | xargs -0 wc -l
Check out CLOC.
cloc counts blank lines, comment lines, and physical lines of source code in many programming languages.
(Legacy builds are archived on SourceForge.)
I have been using CLOC as mentioned by Nathan Kinsinger and it is fairly easy to use. It is a PERL script that you can add and run from your project directory.
PERL is already part of Mac OS and you can invoke the script this way to find out your number of lines you have written:
perl cloc-1.56.pl ./YourDirectoryWhereYourSourcesAre
This is an example of output i got from such command:
176 text files.
176 unique files.
4 files ignored.
http://cloc.sourceforge.net v 1.56 T=2.0 s (86.0 files/s, 10838.0 lines/s)
-------------------------------------------------------------------------------
Language files blank comment code
-------------------------------------------------------------------------------
Objective C 80 3848 1876 11844
C/C++ Header 92 980 1716 1412
-------------------------------------------------------------------------------
SUM: 172 4828 3592 13256
-------------------------------------------------------------------------------
Open up Terminal.app, go into your project's root directory, and run this command:
For Swift only:
find . \( -iname \*.swift \) -exec wc -l '{}' \+
For Obj-C only:
find . \( -iname \*.m -o -iname \*.mm -o -iname \*.h \) -exec wc -l '{}' \+
For Obj-C + Swift:
find . \( -iname \*.m -o -iname \*.mm -o -iname \*.h -o -iname \*.swift \) -exec wc -l '{}' \+
For Obj-C + Swift + C + C++:
find . \( -iname \*.m -o -iname \*.mm -o -iname \*.c -o -iname \*.cc -o -iname \*.h -o -iname \*.hh -o -iname \*.hpp -o -iname \*.cpp -o -iname \*.swift \) -exec wc -l '{}' \+
Terminal quick tips:
ls: list directory contents
cd: change directory
Press tab to autocomplete
Remember to put "\" backslash before spaces
I suggest going one folder down from the main project so you get rid of code count from the frameworks
In terminal, change into the project directory and run:
find . -type f -print0 | xargs -0 cat | wc -l
If you want only certain file types, try something like
find . -type f -name \*.[ch]* -print0 | xargs -0 cat | wc -l
open terminal
navigate to your project
execute following command inside your project:
find . -path ./Pods -prune -o -name "*.swift" -print0 ! -name "/Pods" | xargs -0 wc -l
Or:
find . -path ./Pods -prune -o -name "*[hm]" -print0 ! -name "/Pods" | xargs -0 wc -l
(*Excluding pod files count from total count)
Check out Xcode Statistician, it does exactly what you want. It also provides other interesting statistics so is worth a run for fun now and then.
Note that it will not look inside real folders, though it will look in groups. Odds are you aren't using real folders so it'll work great. If you are using folders then you just have to do the count in each folder and add them together.
Note: As of June, 2012, it seems this does not work properly with the latest versions of Xcode.
If you go to your project's directory in terminal and enter:
find . "(" -name "*.h" -or -name "*.m" -or -name "*.mm" -or -name "*.hpp" -or -name "*.cpp" -or -name "*.c" -or -name "*.cc" -or -name "*.swift" ")" -print0 | xargs -0 wc -l
That will give you a project breakdown, as well as the line total for each file and the project as a whole.
Steps to implement CLOC library in Mac as below:
Open Terminal.
Install Homebrew by copying and pasting the below command in the Terminal (including double quotes).
ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
Enter system password if asked.
You will see the terminal screen as below.
System will popup so many permissions, allow all the permissions
If everything goes fine, you will see terminal screen as below,
Now its time to install CLOC using below command.
brew install cloc
Navigate to the project directory and run either of the following commands.
cloc . --exclude-dir=Pods (to exclude pod files)
cloc . (including pod files)
If everything goes fine, it will display the number of lines of code as below,
Nozzi's version doesn't work for me, but this one:
find . -type f -print0 | xargs -0 cat | wc -l
A quick & easy way:
Use a regex search (Find Navigator, choose Find > Regular Expression).
.\n
Works conveniently with Xcode search scopes and you can easily customize it to whatever type of line you'd like to count ;).
You can install SLOCCount through MacPorts. Or, more crudely, you can use wc -l.
I am not familiar with xcode, but if all you need is to count the number of lines from all those specific files within a directory tree, you may use the following command:
find .... match of all those files ... -exec wc -l {} +
Following Joshua Nozzi's answer, in GNU find the regular expression for such files would be like:
find . "(" -name "*.m" -or -name "*.mm" -or -name "*.cpp" -or -name "*.swift" ")" -exec wc -l {} +
or even
find -regex ".*\.\(m\|mm\|cpp\|swift\)$" -exec wc -l {} +
this uses a regular expression to match all files ending in either .m, .mm, .cpp or .swift. You can see more information about those expressions in How to use regex in file find.
If you are working with Mac OS find, then you need a slightly different approach, as explained by Motti Shneor in comments:
find -E . -regex ".*\.([hmc]|mm|cp+|swift|pch)$" -exec wc -l {} +
Both will provide an output on the form of:
234 ./file1
456 ./file2
690 total
So you can either keep it like this or just pipe to tail -1 (that is, find ... | tail -1) so that you just get the last line being the total.
line-counter is a good alternative. It's lighter than CLOC and much more powerful and easier to use than other commands.
A quick overview
This is how you get the tool
$ pip install line-counter
Use line command to get the file count and line count under current directory (recursively)
$ line
Search in /Users/Morgan/Documents/Example/
file count: 4
line count: 839
If you want more detail, just use line -d.
$ line -d
Search in /Users/Morgan/Documents/Example/
Dir A/file C.c 72
Dir A/file D.py 268
file A.py 467
file B.c 32
file count: 4
line count: 839
And the best part of this tool is, you can add .gitignore like configure file to it. You can set up rules to select or ignore what kind of files to count just like what you do in '.gitignore'. Yes, this tool is just invented to make knowing how many lines I have easier.
More description and usage is here: https://github.com/MorganZhang100/line-counter
I'm the author of this simple tool. Hope it can help somebody.

Resources