2014-04-04 6 views
32

क्या कोई तरीका है कि आप clang-format को ऐसे मोड में चला सकते हैं जहां यह रिपोर्ट करता है कि फ़ाइल निर्दिष्ट प्रारूप को पूरा करती है या नहीं? एक प्रकार का ड्राई-रन मोड जहां यह रिपोर्ट करता है कि परिवर्तन की आवश्यकता है, लेकिन परिवर्तन नहीं करता है। आदर्श रूप से मुझे फ़ाइल को परिवर्तन की आवश्यकता होने पर एक गैर-शून्य निकास कोड वापस करने के लिए क्लैंग-प्रारूप चाहिए। या, यहां तक ​​कि अधिक आदर्श, एक गैर-शून्य निकास कोड और उन फ़ाइलों की एक सूची जिन्हें मानक आउटपुट पर परिवर्तन की आवश्यकता है।क्या क्लैंग-प्रारूप मुझे बता सकता है कि फ़ॉर्मेटिंग परिवर्तन आवश्यक हैं या नहीं?

मैं सवाल सामान्य रखने की कोशिश कर रहा हूं, ताकि अधिक लोग उत्तर दे सकें, लेकिन जो मैं करने की कोशिश कर रहा हूं वह एक गिट प्री-प्रतिबद्ध हुक लिखता है जो किसी भी काम को अस्वीकार कर देगा जो उम्मीद से मेल नहीं खाता है। -फॉर्मेट सूचकांक में फ़ाइलों की सूची पर क्लैंग-प्रारूप चलाने में आसान है। लेकिन यह जानना मुश्किल है कि क्लैंग-प्रारूप वास्तव में कुछ भी बदल गया है या नहीं।

मेरे पास -output-replacements-xml (जो मैं एक उत्तर के रूप में पोस्ट करूंगा) पर आधारित एक संभावित समाधान है, लेकिन यह एक हैक है और मुझे लगता है कि यह अधिक सरल होना चाहिए। टिप्पणियां/सुझाव, संपादन, विभिन्न उत्तरों/दृष्टिकोण सभी का स्वागत है।

उत्तर

24

मुझे ऐसा कारणों में से एक कारण यह आसान होना चाहिए क्योंकि -उपूट-प्रतिस्थापन-एक्सएमएल अनिवार्य रूप से मुझे वह उत्तर देता है जो मैं चाहता हूं, यह मुझे इसे उपभोग करने में आसानी से नहीं देता है। हालांकि, आउटपुट के बाद से अगर कोई प्रतिस्थापन की आवश्यकता नहीं है तो अनुमान लगाया जा सकता है, आउटपुट को पार्स करना बहुत मुश्किल नहीं है। के बाद से ग्रेप अगर कुछ मेल खाता रिटर्न 0, 1, तो कुछ नहीं करता है

क्या मैं अभी है,

clang-format -style=file -output-replacements-xml | grep -c "<replacement " >/dev/null 

यह वास्तव में बाहर निकलने के कोड मैं चाहता हूँ की प्रतिलोम देता है। लेकिन यह निपटने के लिए काफी आसान है।

तो मेरी Git के प्रासंगिक बिट पूर्व प्रतिबद्ध हुक होगा

git diff --cached --name-only --diff-filter=ACMRT | grep "\.[cmh]$" | xargs -n1 clang-format -style=file -output-replacements-xml | grep "<replacement " >/dev/null 
if [ $? -ne 1 ] 
then 
    echo "Commit did not match clang-format" 
    exit 1; 
fi 
  1. (सूचकांक में फ़ाइलों का पूरा फ़ाइल नाम प्राप्त फ़ाइलों को नष्ट कर दिया जा रहा है और अन्य असामान्य मामलों को छोड़कर, जहां मैं हो सकता है फ़ाइल पर कार्रवाई करने)
  2. केवल xargs के माध्यम से चीजों की फ़ाइल नाम रखने मैं (बस ग, मी के स्वरूपण की जाँच करने के मेरे मामले में चाहते हैं, और ज फ़ाइलें)
  3. भागो परिणाम नहीं चाहते करने के लिए अनिवार्य रूप से "प्रत्येक के लिए" अगला आदेश
  4. सभी फ़ाइलों पर आउटपुट-प्रतिस्थापन-एक्सएमएल विकल्प के साथ क्लैंग-प्रारूप चलाएं
  5. प्रतिस्थापन के लिए खोजें (प्रतिस्थापन के विपरीत) जो इंगित करता है कि क्लैंग-प्रारूप को एक प्रतिस्थापन मिला है जो वह बनाना चाहता है। (एक्सएमएल के रूप में सभी आउटपुट को छोड़कर उपयोगकर्ता के लिए सार्थक नहीं होगा।)
  6. अंतिम आदेश 1 से बाहर निकलता है (grep कहते हैं कि हमें कुछ नहीं मिला) हम कर रहे हैं और चीजें ठीक हैं।
  7. यदि नहीं, तो एक संदेश प्रदर्शित करें और 1 से बाहर निकलें, जो प्रतिबद्धता को रद्द करता है। दुर्भाग्य से हमारे पास उपयोगकर्ता को यह बताने का कोई आसान तरीका नहीं है कि फ़ाइल कौन सी समस्या थी, लेकिन वे स्वयं को क्लैंग-प्रारूप चला सकते हैं और देख सकते हैं।
+0

मुझे आश्चर्य है कि यह एक अधिक लोकप्रिय प्रश्न/उत्तर नहीं है। मैं वही कर रहा हूं जो आप कर रहे हैं। क्या आप इसे करने के लिए पूरे गिट हुक पोस्ट कर सकते हैं? –

+0

उपरोक्त कोड स्निपेट शीर्ष पर '#!/Bin/bash' के अलावा, हुक के लिए आवश्यक सब कुछ होना चाहिए। (मैं पूरी हुक को गस्ट पर रखूंगा लेकिन इसमें अन्य प्रोजेक्ट-विशिष्ट चीजें थीं।) मेरे हुक में एकमात्र अंतर टिप्पणियां थीं जो उपर्युक्त चीजों और क्लैंग-प्रारूप पथ के पूर्ण-योग्यता की व्याख्या करती हैं। –

+4

मेरे दो सेंट: 'diff -u <(cat src/*) <(clang-format src/*)' XML – phs

4

मुझे पूरी तरह से यकीन नहीं है कि आपका उपयोग केस क्या है, लेकिन गिट-क्लैंग-प्रारूप (https://llvm.org/svn/llvm-project/cfe/trunk/tools/clang-format/git-clang-format) देखें। यह मूल रूप से गिट के लिए एक क्लैंग-प्रारूप एकीकरण प्रदान करता है और शायद यही वह है जिसे आप ढूंढ रहे हैं।

+1

मैं उत्तर की सराहना करता हूं, मैं इसे देख लूंगा। हालांकि, यह वास्तव में सवाल का जवाब नहीं देता है या मेरे उपयोग के मामले को हल नहीं करता है। ऐसा लगता है कि बदले गए फाइलों पर सिर्फ क्लैंग-फॉर्मेट चल रहा है। अनिवार्य रूप से मैं एक सुरक्षा की तलाश में हूं जो सुनिश्चित करता है कि वर्तमान शैली (जैसा कि क्लैंग-प्रारूप में परिभाषित किया गया है) पूरा हो गया है, लेकिन यह मनमाने ढंग से क्लैंग-प्रारूप नहीं चलाता है। (मुझे कम से कम किसी भी स्वरूपण परिवर्तन की समीक्षा करने का मौका चाहिए जो क्लैंग-फॉर्मेट करेगा: यह हमेशा जिस तरह से मैं चाहता हूं, वह हमेशा लाइनों को तोड़ता नहीं है।) –

+10

तो, कैसे करें: 'clang-format | diff -'? क्लैंग-प्रारूप ('-i' विकल्प के बिना) आपकी फ़ाइल में कोई भी बदलाव नहीं करेगा, बस इसे stdout पर प्रिंट करें। – djasper

1

मैं git-clang-format का उपयोग करें और एक माइक रोड्स 'ब्लॉग से स्क्रिप्ट पूर्व प्रतिबद्ध:

#!/bin/python 

import subprocess 
output = subprocess.check_output(["git", "clang-format", "--diff"]) 

if output not in ['no modified files to format\n', 'clang-format did not modify any files\n']: 
    print "Run git clang-format, then commit.\n" 
    exit(1) 
else: 
    exit(0) 

जब कोई करता हैं लिपि में है कि यह काम नहीं करता है एक छोटी सी त्रुटि है (सिर के खिलाफ जांच करने के लिए कोशिश कर रहा जो अभी तक मौजूद नहीं है)। इसे बाईपास करने के लिए, -n या --no-verify विकल्प का उपयोग करें।

प्री-स्क्रिप्ट स्क्रिप्ट को छोड़ने के लिए -n का उपयोग करना भी सहायक हो सकता है जब आप चेक को बाईपास करना चाहते हैं क्योंकि इसमें बड़े कोडबेस के लिए लंबा समय लग सकता है।

मूल पोस्ट यहाँ है: http://www.dx13.co.uk/articles/2015/4/3/Setting-up-git-clang-format.html

0

बाद मैं David Ogren's post द्वारा प्रेरित हुआ मैं एक pre-commit हुक कि मंचन परिवर्तन पर काम करने में सक्षम है बनाया है। यह सुनिश्चित करेगा कि pre-commit हुक कोड पर काम करेगा जो वास्तव में प्रतिबद्धता की सामग्री को बनाएगा और clang-format रन द्वारा बेवकूफ नहीं बनाया जा सकता है जो चरणबद्ध नहीं हुआ था।

#!/bin/bash 

files=() 
for file in `git diff --cached --name-only --diff-filter=ACMRT | grep -E "\.(cpp|hpp)$"`; do 
    if ! cmp -s <(git show :${file}) <(git show :${file}|clang-format); then 
    files+=("${file}") 
    fi 
done 

if [ -n "${files}" ]; then 
echo Format error within the following files: 
printf "%s\n" "${files[@]}" 
exit 1 
fi 
संबंधित मुद्दे