1+ #! /bin/bash
2+ # Software Name: floss-toolbox
3+ # SPDX-FileCopyrightText: Copyright (c) 2020-2021 Orange
4+ # SPDX-License-Identifier: Apache-2.0
5+ #
6+ # This software is distributed under the Apache 2.0 license.
7+ #
8+ # Author: Pierre-Yves LAPERSONNE <pierreyves(dot)lapersonne(at)orange(dot)com> et al.
9+
10+ # Version.............: 1.0.0
11+ # Since...............: 06/10/2021
12+ # Description.........: Using the Git history, provide a list of contributors
13+ #
14+ # Usage: bash list-contributors-in-history.sh --project path/to/project --loglimit LIMIT
15+ #
16+ # Exit codes:
17+ # 0 - normal exit
18+ # 1 - problem with given parameters
19+ # 2 - problem with preconditions (e.g. files to use by the script)
20+ # 3 - problem with a command
21+ #
22+
23+ set -euo pipefail
24+ # Exits immediately if:
25+ # - any command has non-zero exit status (-e)
26+ # - undefined variable in use (-u)
27+ # and do not mask errors in pipelines (-o pipefail)
28+
29+ VERSION=" 1.0.0"
30+ SCRIPT_NAME=" list-contributors-in-history"
31+
32+ # -------------
33+ # Configuration
34+ # -------------
35+
36+ NORMAL_EXIT_CODE=0
37+ BAD_ARGUMENTS_EXIT_CODE=1
38+ BAD_PRECONDITION_EXIT_CODE=2
39+ UNEXPECTED_RESULT_EXIT_CODE=3
40+
41+ # Folder fo generated files
42+ TEMP_FOLDER=" ./data"
43+
44+ # Prefix for generated files
45+ GENERATED_FILES_PREFIX=" $$ -list-of-contributors"
46+
47+ # File listing the commits which have words hits
48+ HITS_FILE=" $TEMP_FOLDER /$GENERATED_FILES_PREFIX -commits-hits.txt"
49+
50+ # Report file with metrics
51+ REPORT_METRIC_FILE=" $TEMP_FOLDER /$GENERATED_FILES_PREFIX -report.txt"
52+
53+ # Temporary log file for "git log" command
54+ # Assuming this file is handled in a subfolder (project to analyse) and filled by the "git log" command
55+ GIT_LOG_TEMP_FILE=" $GENERATED_FILES_PREFIX -git-log.temp.txt"
56+
57+ # Path to Ruby-written script which will deal fastly in few lines with the git commits messages file
58+ GIT_LOG_RUBY_PARSER=" ./utils/extract-contributors-lists.rb"
59+
60+ # ---------
61+ # Functions
62+ # ---------
63+
64+ # \fn DisplayUsages
65+ # \brief Displays an help message and exists
66+ DisplayUsages (){
67+ echo " ***********************************************"
68+ echo " $SCRIPT_NAME - Version $VERSION "
69+ echo " ***********************************************"
70+ echo " USAGE:"
71+ echo " bash $SCRIPT_NAME .sh --project PROJECT --loglimit LIMIT"
72+ echo -e " \t --project........: PROJECT must point to a git-based directory whith the commits to analyse, placee it in _data_ folder"
73+ echo -e " \t --loglimit.......: [git log] option to define the LIMIT for commit searches, e.g. 2.weeks or 3.years"
74+ }
75+
76+ # \fn NormalExit
77+ # \brief Exits with NORMAL_EXIT_CODE code
78+ NormalExit (){
79+ exit $NORMAL_EXIT_CODE
80+ }
81+
82+ # \fn BadArgumentsExit
83+ # \brief Exits with BAD_ARGUMENTS_EXIT_CODE code
84+ BadArgumentsExit (){
85+ exit $BAD_ARGUMENTS_EXIT_CODE
86+ }
87+
88+ # \fn BadPreconditionsExit
89+ # \brief Exits with BAD_PRECONDITION_EXIT_CODE code
90+ BadPreconditionsExit () {
91+ exit $BAD_PRECONDITION_EXIT_CODE
92+ }
93+
94+ # \fn UnexpectedResultExit
95+ # \brief Exist with UNEXPECTED_RESULT_EXIT_CODE code
96+ UnexpectedResultExit (){
97+ exit $UNEXPECTED_RESULT_EXIT_CODE
98+ }
99+
100+ # \fn PrepareFiles
101+ # \brief If existing removes the work files and then creates them
102+ PrepareFiles () {
103+ if [ -f $HITS_FILE ]; then
104+ rm $HITS_FILE
105+ fi
106+ touch $HITS_FILE
107+ if [ -f $REPORT_METRIC_FILE ]; then
108+ rm $REPORT_METRIC_FILE
109+ fi
110+ touch $REPORT_METRIC_FILE
111+ }
112+
113+ # ----------------
114+ # Step 0 - Prepare
115+ # ----------------
116+
117+ # Check the args numbers and display usage if needed
118+ if [ " $# " -ne 4 ]; then
119+ DisplayUsages
120+ NormalExit
121+ fi
122+
123+ # Get target folder
124+ if [ " $1 " = " --project" ]; then
125+ if [ " $2 " ]; then
126+ git_based_project=$2
127+ else
128+ DisplayUsages
129+ BadArgumentsExit
130+ fi
131+ else
132+ DisplayUsages
133+ BadArgumentsExit
134+ fi
135+
136+ # Get git limit
137+ if [ " $3 " = " --loglimit" ]; then
138+ if [ " $4 " ]; then
139+ git_log_limit=$4
140+ else
141+ DisplayUsages
142+ BadArgumentsExit
143+ fi
144+ else
145+ DisplayUsages
146+ BadArgumentsExit
147+ fi
148+
149+ # Test if find script and project to analyse exist and are readable
150+
151+ if [ ! -f " $GIT_LOG_RUBY_PARSER " ]; then
152+ echo " 💥 Error: $SCRIPT_NAME - $GIT_LOG_RUBY_PARSER is not a script to trigger"
153+ BadPreconditionsExit
154+ fi
155+
156+ if [ ! -r " $GIT_LOG_RUBY_PARSER " ]; then
157+ echo " ⛔ Error: $SCRIPT_NAME - $GIT_LOG_RUBY_PARSER script cannot be read"
158+ BadPreconditionsExit
159+ fi
160+
161+ if [ ! -d " $git_based_project " ]; then
162+ echo " 💥 Error: $git_based_project is not a directory to process"
163+ BadArgumentsExit
164+ fi
165+ if [ ! -r " $git_based_project " ]; then
166+ echo " ⛔ Error: $git_based_project file cannot be read"
167+ BadArgumentsExit
168+ fi
169+
170+ # Run!
171+ SECONDS=0
172+
173+ echo " **************************************************"
174+ echo " $SCRIPT_NAME - Version $VERSION "
175+ echo " **************************************************"
176+
177+ echo -e " \n"
178+
179+ echo " 📋 Project to analyse is $git_based_project "
180+ echo " 📋 Limit for git logs is $git_log_limit "
181+
182+ echo " 📋 Prepare logs"
183+ PrepareFiles
184+
185+ echo -e " \n"
186+
187+ # --------------------------------------------
188+ # Step 1 - Get git log until the defined limit
189+ # --------------------------------------------
190+
191+ echo " 🍥 Retrieving git logs in temporary file named $GIT_LOG_TEMP_FILE ..."
192+
193+ current_folder=` pwd`
194+
195+ cd " $git_based_project "
196+
197+ git_log_file=" ../$GIT_LOG_TEMP_FILE "
198+ if [ -f $git_log_file ]; then
199+ rm $git_log_file
200+ fi
201+ touch $git_log_file
202+
203+ git log --since=$git_log_limit > $git_log_file
204+
205+ if [ ! -s " $git_log_file " ]; then
206+ cd " $current_folder "
207+ echo " 💥 Error: $git_log_file is empty, the git log command seems to have failed. Check the 'loglimit' parameter."
208+ UnexpectedResultExit
209+ fi
210+
211+ cd " $current_folder "
212+
213+ # -------------------------
214+ # Step 3 - Process the logs
215+ # -------------------------
216+
217+ echo -e " 🍥 Running Ruby script (named $GIT_LOG_RUBY_PARSER ) to look in log file for contributors...\n"
218+
219+ # Ruby tool is in toolbox/diver/utils
220+ # Git log file is in toolbox/diver/data
221+ ruby $GIT_LOG_RUBY_PARSER " ./data/$GIT_LOG_TEMP_FILE " > $HITS_FILE
222+
223+ echo -e " \n👌 Git log has been processed\n"
224+
225+ # ------------------------------------------------------------
226+ # Step 5 - Metrics (words and files counts, hits, duration...)
227+ # ------------------------------------------------------------
228+
229+ commits_count=` grep -o ' commit [0-9A-Za-z]*' " data/$GIT_LOG_TEMP_FILE " | wc -l`
230+ echo " 📈 Count of commits to process..............................: $commits_count " >> $REPORT_METRIC_FILE
231+
232+ contributors_count=` cat " $HITS_FILE " | wc -l`
233+ echo " 📈 Count of contributors to process.........................: $contributors_count " >> $REPORT_METRIC_FILE
234+
235+ script_duration=$SECONDS
236+ echo " 📈 Elapsed time.............................................: $(( $script_duration / 60 )) ' $(( $script_duration % 60 )) ''" >> $REPORT_METRIC_FILE
237+
238+ # The end!
239+
240+ echo " Reports available in $REPORT_METRIC_FILE :"
241+ cat $REPORT_METRIC_FILE
242+
243+ echo -e " \nEnd of $SCRIPT_NAME \n"
244+ NormalExit
0 commit comments