degooglizzazione/_build.js

139 lines
5.3 KiB
JavaScript

// Build tool for generating README.md
const os = require('os');
const path = require('path');
const fs = require('fs-extra');
const YAML = require('yaml');
// A hacky sort of "class" to contain methods for each section
const BUILD_SECTION = {
// TODO: Make more of these YAML-based functions
header: () => readFile('md/_header.md'),
index: () => readFile('md/_index.md'),
contributing: () => readFile('md/_contributing.md'),
browserExtensions: () => readFile('md/_browserExtensions.md'),
disclaimer: () => readFile('md/_disclaimer.md'),
webBasedProducts: () => generateCategorySection('Web-based products', readYaml()['web based products']),
operatingSystems: () => generateCategorySection('Operating systems', readYaml()['operating systems']),
desktopApps: () => generateCategorySection('Desktop apps', readYaml()['desktop applications']),
mobileApps: () => generateCategorySection('Mobile apps', readYaml()['mobile applications']),
hardware: () => generateCategorySection('Hardware', readYaml()['hardware']),
useful: () => '# Useful links, tools, and advice',
resources: () => readFile('md/_resources.md'),
books: () => readFile('md/_books.md'),
blogs: () => readFile('md/_blogs.md'),
news: () => readFile('md/_news.md'),
lighterSide: () => readFile('md/_lighterSide.md'),
closingRemarks: () => readFile('md/_closingRemarks.md')
}
// Button that brings the user to the top of the page
const BACK_TO_TOP = '[![Back to top](https://img.shields.io/badge/Back%20to%20top-lightgrey.svg)](https://github.com/tycrek/degoogle#readme)';
/**
* Main method
*/
function __main__() {
// dgSectionData will be join at the end and represents the full contents of README.md
let dgSectionData = [];
// Add all the sections
dgSectionData.push(BUILD_SECTION.header());
dgSectionData.push(BUILD_SECTION.index());
dgSectionData.push(BUILD_SECTION.contributing());
dgSectionData.push(BUILD_SECTION.browserExtensions());
dgSectionData.push(BUILD_SECTION.disclaimer());
dgSectionData.push(BUILD_SECTION.webBasedProducts());
dgSectionData.push(BUILD_SECTION.operatingSystems());
dgSectionData.push(BUILD_SECTION.desktopApps());
dgSectionData.push(BUILD_SECTION.mobileApps());
dgSectionData.push(BUILD_SECTION.hardware());
dgSectionData.push(BUILD_SECTION.useful());
dgSectionData.push(BUILD_SECTION.resources());
dgSectionData.push(BUILD_SECTION.books());
dgSectionData.push(BUILD_SECTION.blogs());
dgSectionData.push(BUILD_SECTION.news());
dgSectionData.push(BUILD_SECTION.lighterSide());
dgSectionData.push(BUILD_SECTION.closingRemarks());
// Write to the README file
fs.writeFileSync(path.join(__dirname, 'README.md'), dgSectionData.join(os.EOL + os.EOL));
console.log('Done!')
}
/**
* Synchronously reads a file using fs-extra and path.join()
* @param {String} filename The file to read
*/
function readFile(filename) {
return fs.readFileSync(path.join(__dirname, filename)).toString();
}
/**
* Reads degoogle.yml
*/
function readYaml() {
return YAML.parse(fs.readFileSync(path.join(__dirname, 'degoogle.yml')).toString());
}
/**
* Generates a major section or "category" such as Mobile Apps
* @param {String} header Title for section
* @param {Object} data Object of data to populate README.md with
*/
function generateCategorySection(header, data) {
if (!data) return '';
// Set the header to HTML <h5>
let categorySection = '## ' + header + ' ' + BACK_TO_TOP + os.EOL + os.EOL;
// Generate service sections for this category
Object.keys(data).forEach((key) => categorySection = categorySection.concat(generateServiceSection(data[key]) + os.EOL + os.EOL));
return categorySection;
}
/**
* Generates a service (such as Gmail) section to be placed under a category section
* @param {Array} data
*/
function generateServiceSection(data) {
// Start the section with an <h4> header and the start of a Markdown table
let serviceSection = `#### ${data[0].title + os.EOL + os.EOL}| Name | Eyes | Description |${os.EOL}| ---- | ---- | ----------- |${os.EOL}`;
let notes = os.EOL + '';
// Iterate over each alternative service and add it to the table
data.forEach(item => {
// If the object has length one, it's either title or note
if (Object.keys(item).length == 1) {
if (!item.notes) return;
else item.notes.forEach((note) => notes = notes.concat(`- *${note.trim()}*${os.EOL}`))
} else {
// Build the cells for the table
let name = `[${item.name}](${item.url})`;
let eyes = item.eyes ? `**${item.eyes}-eyes**` : '';
let text = item.text.trim();
// Append the F-Droid badge to the name
if (item.fdroid) name = name.concat(' ' + fdroidLink(item.fdroid))
// Build the row
let tableItem = `| ${name} | ${eyes} | ${text} |`;
// Add the row to the table
serviceSection = serviceSection.concat(tableItem + os.EOL)
}
});
return serviceSection + notes;
}
/**
* Returns a badge acting as a link to an F-Droid page for an app.
* @param {String} appId The package identifier on F-Droid
*/
function fdroidLink(appId) {
return `[![F-Droid](https://img.shields.io/f-droid/v/${appId})](https://f-droid.org/en/packages/${appId}/)`;
}
__main__();