LINUX.ORG.RU

Совместная разработка

 , ,


0

1

Привет.
Уточню сразу - у меня нет опыта совместной разработки. Допустим, у меня есть некая многопоточная софтина, как правильно организовать совместную работы с малоизвестными энтузиастами? Подозреваю что нужно сделать некое ядро (в которое никого не пускать) и модульную систему с чётко описанным интерфейсом, и принимать pull request’ы в виде модулей. Ну не пускать же первого встречного править всё что угодно.

Может у кого есть реальный опыт/мысли? Как организуется процесс в реальных проектах, разграничивается «зона ответственности». Поделитесь, пожалуйста.

★★

Ответ на: комментарий от Norgat

Работа ведется через github\gitlab

фирмы уровнем чуть выше ИП Козявкин на чужие хостинги внутренние проекты не выкладывают

next_time ★★★★★
()
Ответ на: комментарий от next_time

фирмы уровнем чуть выше ИП Козявкин на чужие хостинги внутренние проекты не выкладывают

Слышал про Open Source там или про корпоративный gitlab?

Norgat ★★★★★
()
Ответ на: комментарий от next_time

А затраты на саппорт собственного они считают? Или просто включают паранойю, что их код сопрёт Microsoft?

Begemoth ★★★★★
()
Ответ на: комментарий от next_time

И ещё один вопрос - используют ли «фирмы уровнем чуть выше ИП Козявкин» чужие датацентры или публичные облака? Или непременно строят свои?

Begemoth ★★★★★
()
Последнее исправление: Begemoth (всего исправлений: 1)
Ответ на: комментарий от Begemoth

ИП Козявкин

Это мой главный конкурент.

С уважением, ИП Пиписькин

anonymous
()
Ответ на: комментарий от next_time

Промышленный шпионаж до появления интернета? Нет, не слышал

Begemoth ★★★★★
()

Как-то не полшло со всякими тестовыми фреймворками. Не вижу смысла всё настолько переусложнять. Вот такой каркас себе накостылил:

#include <iostream>
#include <functional>
#include <stdexcept>
#include <string>
#include <array>

enum Expected_result
{
	EXPECTED_PASS,
	EXPECTED_FAIL
};

struct Test
{
	std::string name;
	Expected_result expected;
	std::function<bool()> test;
};
#define TEST(name, expected)  Test{#name, expected, []()

auto &test_suite()
{
	static std::array tests = {
		TEST(first_test, EXPECTED_PASS) {
			return 1;
		}},
		TEST(second_test, EXPECTED_FAIL) {
			return 1;
		}},
		TEST(third_test, EXPECTED_PASS) {
			return 0;
		}},
		TEST(fourth_test, EXPECTED_FAIL) {
			return 0;
		}},
		TEST(fifth_test, EXPECTED_FAIL) {
			throw std::logic_error("hello form exception");
			return 0;
		}}
	};
	return tests;
}

int main(int argc, const char *argv[])
{
#define C(color)  "\033["#color"m"
	std::cerr << C(32)
		<< "============================================================="
		"===============\n"
		<< C(0)"Testsuite: " << argv[0] << '\n';
	unsigned pass = 0, xfail = 0, fail = 0, xpass = 0, error = 0;
	for (auto &test : test_suite()) {
		try {
			if (argc > 1  && std::string(argv[1]) != test.name)
				continue;
			std::cerr << C(0);
			switch (test.test()) {
				case true:
					if (test.expected == EXPECTED_PASS) {
						++ pass;
						std::cerr << C(32)"PASS: " << test.name << std::endl;
					}
					else {
						++ xpass;
						std::cerr << C(31)"XPASS: " << test.name << std::endl;
					}
					break;
				case false:
					if (test.expected == EXPECTED_FAIL) {
						++ xfail;
						std::cerr << C(32)"XFAIL: " << test.name << std::endl;
					}
					else {
						++ fail;
						std::cerr << C(31)"FAIL: " << test.name << std::endl;
					}
			}
		}
		catch(std::exception &e) {
			++ error;
			std::cerr << C(31)"ERROR: " << test.name << std::endl;
			std::cerr << "  what(): " << e.what() << std::endl;
		}
		catch(...) {
			++ error;
			std::cerr << C(31)"ERROR: " << test.name << std::endl;
		}
	}
	std::cerr << C(32)"--------------------------------------------------------"
		"--------------------\n"
		<< C(0)"Testsuite summary for "  << argv[0] << std::endl
		<< "# TOTAL = " << pass+xfail+fail+xpass+error << '\n'
		<< C(32)"# PASS  = " << pass << '\n'
		<< "# XFAIL = " << xfail << '\n'
		<< C(31)"# XPASS = " << xpass << '\n'
		<< "# ERROR = " << error << '\n';
}
AUTOMAKE_OPTIONS = serial-tests
TESTS = test1
check_PROGRAMS = test1
test1_SOURCES = main_test.cc 
test1_LDADD = ../libtemp.a
test1_CXXFLAGS = -std=c++17
pavlick-fm /tmp/1/src/tests $ make check 2>&1 > /dev/null | tee /tmp/log
============================================================================
Testsuite: ./test1
PASS: first_test
XPASS: second_test
FAIL: third_test
XFAIL: fourth_test
ERROR: fifth_test
  what(): hello form exception
----------------------------------------------------------------------------
Testsuite summary for ./test1
# TOTAL = 5
# PASS  = 1
# XFAIL = 1
# XPASS = 1
# ERROR = 1

Логи, цветной вывод, запуск теста по имени и всё такое. Думал о всяки moc’ах, fake’ах - можно тупо подменять для тестового исполняемого файла объектные файлы. Для этого разбил файлы тестеруемого проекта на

specific_src = main.cc net_api.cc
src = q.cc f.cc

из src строю lib.a, а файлы из specific_src можно подменять. Целый день пытался въехать в существующие фреймворки, смотрел на ютубе всяких умных дядек, в итоге плюнул и за час накостылил ))

pavlick ★★
() автор топика
Ответ на: комментарий от pavlick

и чего ты ждешь? чтобы твое говно кто-то на вкус пробовал потому что ты не осилил тестовые фреймворки? ладно бы ты написал, что именно ты не смог осилить, с этого хоть поржать можно было бы

anonymous
()
Ответ на: комментарий от fsb4000

Да boost.test наверняка хорош, но я как глянул объем доков к нему, так стало страшно.

и чего ты ждешь? чтобы твое говно кто-то на вкус пробовал потому что ты не осилил тестовые фреймворки?

Я часто коды выкладываю для себя в основном, ну всякое бывает, всегда можно подсмотреть. Если кто-то найдёт полезным - то вообще отлично. Я честно пытался разобраться, но, по-моему, игра свечь не стоит.

pavlick ★★
() автор топика
Последнее исправление: pavlick (всего исправлений: 1)

Место не совсем подходящее, наверное. Не обращайте внимания, пожалуйста. Причёсанная версия:

#include <iostream>
#include <functional>
#include <stdexcept>
#include <string>
#include <array>

enum Expected_result { EXPECTED_PASS, EXPECTED_FAIL };
enum Test_return { RET_SUCCESS = 1, RET_SKIPPED = 77, RET_FAILURE = 0 };
struct Test { std::string name; Expected_result expected; std::function<int()> test; };
#define TEST(name, expected)  Test{#name, expected, []()->int

auto &test_suite()
{
    static std::array tests = {
        TEST(first_test, EXPECTED_PASS) {
            return RET_SUCCESS;
        }},
        TEST(second_test, EXPECTED_FAIL) {
            return RET_SUCCESS;
        }},
        TEST(third_test, EXPECTED_PASS) {
            return RET_FAILURE;
        }},
        TEST(fourth_test, EXPECTED_FAIL) {
            return RET_FAILURE;
        }},
        TEST(fifth_test, EXPECTED_FAIL) {
            throw std::logic_error("hello form exception");
            return RET_FAILURE;
        }},
        TEST(sixth_test, EXPECTED_PASS) {
            return RET_SKIPPED;
        }}
    };
    return tests;
}

int main(int argc, const char *argv[])
{
    using namespace std;
#define C(color)  "\033["#color"m"
    cerr << C(32) << string(76, '=') << C(0)"\nTestsuite: " << argv[0] << '\n';
    unsigned pass = 0, skip = 0, xfail = 0, fail = 0, xpass = 0, error = 0;
    for (auto &test : test_suite()) {
        try {
            if (argc > 1  && argv[1] != test.name) continue; cerr << C(0);
            switch (test.test()) {
                case RET_SUCCESS:
                    if (test.expected == EXPECTED_PASS) {
                        ++ pass; cerr << C(32)"PASS:  " << test.name << endl;
                    }
                    else {++xpass;cerr<<C(31)"XPASS: "<<test.name<<endl;} break;
                case RET_SKIPPED:
                    ++skip; cerr<<C(36)"SKIP:  "<<test.name<<endl; break;
                default:
                    if (test.expected == EXPECTED_FAIL) {
                        ++ xfail; cerr << C(32)"XFAIL: " << test.name << endl;
                    }
                    else {++fail; cerr<<C(31)"FAIL:  "<<test.name<<endl;}
            }
        }
#define PRER  cerr << C(31)"ERROR: " << test.name << endl
        catch(exception &e) {++ error;PRER;cerr<< "  what(): "<<e.what()<<endl;}
        catch(...) { ++ error; PRER; }
    }
    cerr<<C(32)<<string(76, '-')<<"\n" C(0) "Summary for: "<<argv[0]<<'\n'
        << "# TOTAL = " << pass+skip+xfail+fail+xpass+error << '\n'
        <<C(32)"# PASS  = "<<pass<< '\n' << C(36)"# SKIP  = "<<skip<<'\n'
        <<C(32)"# XFAIL = "<<xfail<<'\n' << C(31)"# FAIL  = "<<fail<<'\n'
        << C(31)"# XPASS = " << xpass << '\n' << "# ERROR = " << error << '\n';
    cerr << C(32) << string(76, '=') << '\n';
}

pavlick ★★
() автор топика
Ответ на: комментарий от Begemoth

он же не ИП Козявкин какой-то

anonymous
()
Ответ на: комментарий от Begemoth

Неужели места жалко … . Я вообще не собирался костылить, так вышло. Тем временем обернул всё в макросы

#include "my_test_fraemwork.hh"
//-----------------------------------------------------------------------------+
PTEST_SUITE_START                                                            //|
//-----------------------------------------------------------------------------+
TEST(first_test, EXPECTED_PASS) {
	TEST_ASSERT(1==1);
	return RET_SUCCESS;
}
TEST_END
TEST(second_test, EXPECTED_FAIL) {
	return true;
}
TEST_END
//-----------------------------------------------------------------------------+
PTEST_SUITE_END                                                              //|
//-----------------------------------------------------------------------------+
pavlick ★★
() автор топика
Ответ на: комментарий от pavlick

Ты-то сам как собираешься потом к этому коду обращаться?

Begemoth ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.