Module: Kettle::Jem::TemplateChecksums
- Defined in:
- lib/kettle/jem.rb
Constant Summary collapse
- YAML_KEY =
"kettle-jem"- CHECKSUMS_SUBKEY =
"checksums"- VERSION_SUBKEY =
"version"- APPLIED_AT_SUBKEY =
"applied_at"- CHANGELOG_REPLAY_SUBKEY =
"changelog_replay"- LAST_ENTRY_KEY_SUBKEY =
"last_entry_key"- LAST_ENTRY_DATE_SUBKEY =
"last_entry_date"
Class Method Summary collapse
- .build_yaml_block(checksums:, version: nil, applied_at: nil, changelog_replay: nil) ⇒ Object
- .build_yaml_state(checksums:, version: nil, applied_at: nil, changelog_replay: nil) ⇒ Object
- .build_yaml_state_lines(checksums:, version: nil, applied_at: nil, changelog_replay: nil) ⇒ Object
- .compute(template_root:) ⇒ Object
- .detail_lines(diff) ⇒ Object
- .diff(current:, stored:) ⇒ Object
- .diff_count(diff) ⇒ Object
- .load_state(config_path:) ⇒ Object
- .load_stored(config_path:) ⇒ Object
- .merge_yaml_state(content, state_block) ⇒ Object
- .remove_from_config(config_path:) ⇒ Object
- .summary(diff) ⇒ Object
- .write_to_config(config_path:, checksums:, version: nil, applied_at: nil, changelog_replay: nil) ⇒ Object
- .yaml_state_node_range(content) ⇒ Object
Class Method Details
.build_yaml_block(checksums:, version: nil, applied_at: nil, changelog_replay: nil) ⇒ Object
1911 1912 1913 1914 1915 1916 |
# File 'lib/kettle/jem.rb', line 1911 def build_yaml_block(checksums:, version: nil, applied_at: nil, changelog_replay: nil) lines = [YAML_KEY] lines[0] = "#{lines[0]}:" lines.concat(build_yaml_state_lines(checksums: checksums, version: version, applied_at: applied_at, changelog_replay: changelog_replay).map { |line| " #{line}" }) lines.join("\n") end |
.build_yaml_state(checksums:, version: nil, applied_at: nil, changelog_replay: nil) ⇒ Object
1918 1919 1920 1921 1922 1923 1924 1925 |
# File 'lib/kettle/jem.rb', line 1918 def build_yaml_state(checksums:, version: nil, applied_at: nil, changelog_replay: nil) build_yaml_state_lines( checksums: checksums, version: version, applied_at: applied_at, changelog_replay: changelog_replay ).join("\n") end |
.build_yaml_state_lines(checksums:, version: nil, applied_at: nil, changelog_replay: nil) ⇒ Object
1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 |
# File 'lib/kettle/jem.rb', line 1927 def build_yaml_state_lines(checksums:, version: nil, applied_at: nil, changelog_replay: nil) lines = [] lines << "#{VERSION_SUBKEY}: #{version.to_s.dump}" if version lines << "#{APPLIED_AT_SUBKEY}: #{applied_at.to_s.dump}" if applied_at if changelog_replay.is_a?(Hash) && !changelog_replay.empty? lines << "#{CHANGELOG_REPLAY_SUBKEY}:" last_entry_key = changelog_replay[LAST_ENTRY_KEY_SUBKEY] || changelog_replay[:last_entry_key] last_entry_date = changelog_replay[LAST_ENTRY_DATE_SUBKEY] || changelog_replay[:last_entry_date] lines << " #{LAST_ENTRY_KEY_SUBKEY}: #{last_entry_key.to_s.dump}" if last_entry_key lines << " #{LAST_ENTRY_DATE_SUBKEY}: #{last_entry_date.to_s.dump}" if last_entry_date end lines << "#{CHECKSUMS_SUBKEY}:" checksums.sort.each do |path, sha| lines << " #{path.dump}: #{sha.dump}" end lines end |
.compute(template_root:) ⇒ Object
1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 |
# File 'lib/kettle/jem.rb', line 1832 def compute(template_root:) root = template_root.to_s.chomp("/") checksums = {} Find.find(root) do |path| next unless File.file?(path) relative_path = path.delete_prefix("#{root}/") checksums[relative_path] = Digest::SHA256.file(path).hexdigest end checksums.sort.to_h end |
.detail_lines(diff) ⇒ Object
1903 1904 1905 1906 1907 1908 1909 |
# File 'lib/kettle/jem.rb', line 1903 def detail_lines(diff) [ *diff.fetch(:added, []).map { |path| " + #{path}" }, *diff.fetch(:changed, []).map { |path| " ~ #{path}" }, *diff.fetch(:removed, []).map { |path| " - #{path}" } ] end |
.diff(current:, stored:) ⇒ Object
1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 |
# File 'lib/kettle/jem.rb', line 1877 def diff(current:, stored:) current_keys = current.keys.to_set stored_keys = stored.keys.to_set { added: (current_keys - stored_keys).sort, changed: (current_keys & stored_keys).select { |path| current[path] != stored[path] }.sort, removed: (stored_keys - current_keys).sort } end |
.diff_count(diff) ⇒ Object
1888 1889 1890 |
# File 'lib/kettle/jem.rb', line 1888 def diff_count(diff) diff.fetch(:added, []).size + diff.fetch(:changed, []).size + diff.fetch(:removed, []).size end |
.load_state(config_path:) ⇒ Object
1854 1855 1856 1857 1858 1859 1860 1861 1862 |
# File 'lib/kettle/jem.rb', line 1854 def load_state(config_path:) return {} unless File.exist?(config_path.to_s) data = YAML.safe_load_file(config_path.to_s, permitted_classes: [], aliases: false) entry = data.is_a?(Hash) ? data[YAML_KEY] : nil entry.is_a?(Hash) ? entry : {} rescue {} end |
.load_stored(config_path:) ⇒ Object
1844 1845 1846 1847 1848 1849 1850 1851 1852 |
# File 'lib/kettle/jem.rb', line 1844 def load_stored(config_path:) return {} unless File.exist?(config_path.to_s) entry = load_state(config_path: config_path) stored = entry.is_a?(Hash) ? entry[CHECKSUMS_SUBKEY] : nil stored.is_a?(Hash) ? stored : {} rescue {} end |
.merge_yaml_state(content, state_block) ⇒ Object
1959 1960 1961 1962 1963 1964 1965 |
# File 'lib/kettle/jem.rb', line 1959 def merge_yaml_state(content, state_block) range = yaml_state_node_range(content) return "#{content.to_s.rstrip}\n\n#{state_block}\n" unless range lines = content.to_s.lines [*lines[0...range.begin], "#{state_block}\n", *lines[range.end..].to_a].join end |
.remove_from_config(config_path:) ⇒ Object
1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 |
# File 'lib/kettle/jem.rb', line 1864 def remove_from_config(config_path:) return false unless File.exist?(config_path.to_s) content = File.read(config_path.to_s) range = yaml_state_node_range(content) return false unless range lines = content.to_s.lines updated = [*lines[0...range.begin], *lines[range.end..].to_a].join File.write(config_path.to_s, updated.gsub(/\n{3,}/, "\n\n")) true end |
.summary(diff) ⇒ Object
1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 |
# File 'lib/kettle/jem.rb', line 1892 def summary(diff) count = diff_count(diff) return "no template files changed since last run" if count.zero? parts = [] parts << "#{diff.fetch(:added, []).size} added" if diff.fetch(:added, []).any? parts << "#{diff.fetch(:changed, []).size} changed" if diff.fetch(:changed, []).any? parts << "#{diff.fetch(:removed, []).size} removed" if diff.fetch(:removed, []).any? "#{count} template file(s) since last run: #{parts.join(", ")}" end |
.write_to_config(config_path:, checksums:, version: nil, applied_at: nil, changelog_replay: nil) ⇒ Object
1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 |
# File 'lib/kettle/jem.rb', line 1945 def write_to_config(config_path:, checksums:, version: nil, applied_at: nil, changelog_replay: nil) return unless File.exist?(config_path.to_s) content = File.read(config_path.to_s) state = build_yaml_state( checksums: checksums, version: version, applied_at: applied_at, changelog_replay: changelog_replay ) updated = merge_yaml_state(content, "#{YAML_KEY}:\n#{state.lines.map { |line| " #{line}" }.join}") File.write(config_path.to_s, updated) end |
.yaml_state_node_range(content) ⇒ Object
1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 |
# File 'lib/kettle/jem.rb', line 1967 def yaml_state_node_range(content) require "yaml/merge" analysis = Yaml::Merge::FileAnalysis.new(content.to_s) raise Error, "could not parse kettle-jem config as YAML" unless analysis.valid? body = analysis.documents.first&.body_node return unless body&.mapping? pairs = body.mapping_pairs pairs.each_with_index do |pair, index| next unless pair.key_name == YAML_KEY start_index = pair.start_line.to_i - 1 next_pair = pairs[index + 1] end_index = next_pair ? next_pair.start_line.to_i - 1 : [pair.end_line.to_i - 1, content.to_s.lines.length].min return start_index...end_index end nil end |